From 3ac0d74eb348f49c3917901ecbca8f05786b03d9 Mon Sep 17 00:00:00 2001 From: Create CLI Date: Thu, 11 Apr 2024 19:39:34 +0000 Subject: [PATCH 01/56] build: initial commit --- .gitignore | 8 + Config | 12 + README.md | 5 + build-info.xml | 45 ++ build.xml | 6 + latest/userguide/book.adoc | 56 ++ latest/userguide/cloudformation-template.adoc | 44 ++ latest/userguide/cloudtrail.adoc | 59 ++ latest/userguide/compliance-validation.adoc | 31 + latest/userguide/data-protection.adoc | 40 ++ .../disaster-recovery-resiliency.adoc | 19 + latest/userguide/doc-history.adoc | 51 ++ latest/userguide/getting-started.adoc | 89 +++ latest/userguide/monitoring.adoc | 82 +++ latest/userguide/network-isolation.adoc | 21 + latest/userguide/private-link-template.adoc | 91 +++ latest/userguide/quotas.adoc | 43 ++ latest/userguide/security-iam.adoc | 640 ++++++++++++++++++ latest/userguide/security.adoc | 50 ++ latest/userguide/setting-up.adoc | 65 ++ latest/userguide/what-is.adoc | 52 ++ 21 files changed, 1509 insertions(+) create mode 100644 .gitignore create mode 100755 Config create mode 100644 README.md create mode 100755 build-info.xml create mode 100755 build.xml create mode 100644 latest/userguide/book.adoc create mode 100644 latest/userguide/cloudformation-template.adoc create mode 100644 latest/userguide/cloudtrail.adoc create mode 100644 latest/userguide/compliance-validation.adoc create mode 100644 latest/userguide/data-protection.adoc create mode 100644 latest/userguide/disaster-recovery-resiliency.adoc create mode 100644 latest/userguide/doc-history.adoc create mode 100644 latest/userguide/getting-started.adoc create mode 100644 latest/userguide/monitoring.adoc create mode 100644 latest/userguide/network-isolation.adoc create mode 100644 latest/userguide/private-link-template.adoc create mode 100644 latest/userguide/quotas.adoc create mode 100644 latest/userguide/security-iam.adoc create mode 100644 latest/userguide/security.adoc create mode 100644 latest/userguide/setting-up.adoc create mode 100644 latest/userguide/what-is.adoc diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b0c911017 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ + +*.running.properties.txt +*\~ +*.mobi +/build +*.DS_Store +*.aws-oxygen +.attach_pid* diff --git a/Config b/Config new file mode 100755 index 000000000..040e5c15a --- /dev/null +++ b/Config @@ -0,0 +1,12 @@ +package.AmazonEKSBestPracticesDocs = { + interfaces = (3.0); + + build-system = happytrails; + build-tools = { + 3.0 = { + HappyTrails = 3.2; + JavaBuildAndTestMin = jdk8; + ZonBook = 4.0; + }; + }; +}; diff --git a/README.md b/README.md new file mode 100644 index 000000000..d81922634 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +Guide Package for Amazon EKS + +Update this README file with information that might be helpful. The README file is not published. + +Initial guilde pathslug when package created: /EKS/latest/userguide diff --git a/build-info.xml b/build-info.xml new file mode 100755 index 000000000..5a6e536ca --- /dev/null +++ b/build-info.xml @@ -0,0 +1,45 @@ + + + + + EKS + Amazon EKS + 0 + Amazon EKS + + + + enabled + + + + + userguide + eks-bpg + Best Practices Guide + EKS + latest + latest + latest/userguide + en_us + + + + + Best Practices Guide Updates + eks-bpg + + + + + + + + + + + + diff --git a/build.xml b/build.xml new file mode 100755 index 000000000..86ea9368a --- /dev/null +++ b/build.xml @@ -0,0 +1,6 @@ + + + This is the entry point for happy trails builds (package builder and eclipse). + + + diff --git a/latest/userguide/book.adoc b/latest/userguide/book.adoc new file mode 100644 index 000000000..b47587ba0 --- /dev/null +++ b/latest/userguide/book.adoc @@ -0,0 +1,56 @@ +//!!NODE_ROOT +[[top]] += Amazon EKS +:doctype: book +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:info_doctype: book +:info_title: Amazon EKS +:info_subtitle: Best Practices Guide +:info_abstract: Insert abstract text +:info_corpauthor: AWS +:info_publisher: AWS +:info_copyright: 2020 \ + Amazon Web Services, Inc. and/or its affiliates. All rights reserved. +:info_legalnotice: Amazon's trademarks and trade dress may not be used in \ + connection with any product or service that is not Amazon's, \ + in any manner that is likely to cause confusion among customers, \ + or in any manner that disparages or discredits Amazon. All other \ + trademarks not owned by Amazon are the property of their respective \ + owners, who may or may not be affiliated with, connected to, or \ + sponsored by Amazon. + +[abstract] +-- +Insert abstract text +-- +:sectnums: + +include::what-is.adoc[leveloffset=+1] + + +include::setting-up.adoc[leveloffset=+1] + + +include::getting-started.adoc[leveloffset=+1] + + +include::security.adoc[leveloffset=+1] + + +include::monitoring.adoc[leveloffset=+1] + + +include::cloudformation-template.adoc[leveloffset=+1] + + +include::private-link-template.adoc[leveloffset=+1] + + +include::quotas.adoc[leveloffset=+1] + + +// include::doc-history.adoc[leveloffset=+1] Commenting out until can fix syntax issue diff --git a/latest/userguide/cloudformation-template.adoc b/latest/userguide/cloudformation-template.adoc new file mode 100644 index 000000000..33d5cfa26 --- /dev/null +++ b/latest/userguide/cloudformation-template.adoc @@ -0,0 +1,44 @@ +//!!NODE_ROOT +[."topic"] +[[creating-resources-with-cloudformation,creating-resources-with-cloudformation.title]] += Creating Amazon EKS resources with AWS CloudFormation +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Creating Amazon EKS resources with \ + AWS CloudFormation +:info_titleabbrev: AWS CloudFormation resources +:info_abstract: Learn about how to create resources for Amazon EKS using an AWS CloudFormation template. + +[abstract] +-- +Learn about how to create resources for Amazon EKS using an AWS CloudFormation template. +-- + +Amazon EKS is integrated with AWS CloudFormation, a service that helps you model and set up your AWS resources so that you can spend less time creating and managing your resources and infrastructure. You create a template that describes all the AWS resources that you want (like YOUR-RESOURCE-PLURAL), and AWS CloudFormation takes care of provisioning and configuring those resources for you. + +When you use AWS CloudFormation, you can reuse your template to set up your Amazon EKS resources consistently and repeatedly. Just describe your resources once, and then provision the same resources over and over in multiple AWS accounts and Regions. + +[[working-with-templates,working-with-templates.title]] +== Amazon EKS and AWS CloudFormation templates + +To provision and configure resources for Amazon EKS and related services, you must understand https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html[AWS CloudFormation templates]. Templates are formatted text files in JSON or YAML. These templates describe the resources that you want to provision in your AWS CloudFormation stacks. If you're unfamiliar with JSON or YAML, you can use AWS CloudFormation Designer to help you get started with AWS CloudFormation templates. For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/working-with-templates-cfn-designer.html[What is AWS CloudFormation Designer?] in the __AWS CloudFormation User Guide__. + +Amazon EKS supports creating YOUR-RESOURCE-PLURAL in AWS CloudFormation. For more information, including examples of JSON and YAML templates for YOUR-RESOURCE-PLURAL, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html[YOUR-SERVICE-RESOURCE-TOPNODE-IN-CLOUDFORMATION, modify this link in the local-phrases.ent file] in the __AWS CloudFormation User Guide__. + +[[learn-more-cloudformation,learn-more-cloudformation.title]] +== Learn more about AWS CloudFormation + +To learn more about AWS CloudFormation, see the following resources: + + + +* http://aws.amazon.com/cloudformation/[AWS CloudFormation] +* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html[AWS CloudFormation User Guide] +* https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html[AWS CloudFormation Command Line Interface User Guide] diff --git a/latest/userguide/cloudtrail.adoc b/latest/userguide/cloudtrail.adoc new file mode 100644 index 000000000..289bde10a --- /dev/null +++ b/latest/userguide/cloudtrail.adoc @@ -0,0 +1,59 @@ +//!!NODE_ROOT
+:https---docs-aws-amazon-com-awscloudtrail-latest-userguide-getting-notifications-top-level-html: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/getting_notifications_top_level.html +:https---docs-aws-amazon-com-awscloudtrail-latest-userguide-cloudtrail-aws-service-specific-topics-html-cloudtrail-aws-service-specific-topics-integrations: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html#cloudtrail-aws-service-specific-topics-integrations + +[."topic"] +[[logging-using-cloudtrail,logging-using-cloudtrail.title]] += Logging Amazon EKS API calls using AWS CloudTrail +:info_doctype: section +:info_title: Logging Amazon EKS API calls using AWS CloudTrail +:info_titleabbrev: CloudTrail logs +:info_abstract: Learn about logging Amazon EKS with AWS CloudTrail. + +[abstract] +-- +Learn about logging Amazon EKS with AWS CloudTrail. +-- + +Amazon EKS is integrated with AWS CloudTrail, a service that provides a record of actions taken by a user, role, or an AWS service in Amazon EKS. CloudTrail captures all API calls for Amazon EKS as events. The calls captured include calls from the Amazon EKS console and code calls to the Amazon EKS API operations. If you create a trail, you can enable continuous delivery of CloudTrail events to an Amazon S3 bucket, including events for Amazon EKS. If you don't configure a trail, you can still view the most recent events in the CloudTrail console in **Event history**. Using the information collected by CloudTrail, you can determine the request that was made to Amazon EKS, the IP address from which the request was made, who made the request, when it was made, and additional details. + +To learn more about CloudTrail, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/[AWS CloudTrail User Guide]. + +[[service-name-info-in-cloudtrail,service-name-info-in-cloudtrail.title]] +== Amazon EKS information in CloudTrail + +CloudTrail is enabled on your AWS account when you create the account. When activity occurs in Amazon EKS, that activity is recorded in a CloudTrail event along with other AWS service events in **Event history**. You can view, search, and download recent events in your AWS account. For more information, see https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html[Viewing Events with CloudTrail Event History]. + +For an ongoing record of events in your AWS account, including events for Amazon EKS, create a trail. A _trail_ enables CloudTrail to deliver log files to an Amazon S3 bucket. By default, when you create a trail in the console, the trail applies to all AWS Regions. The trail logs events from all Regions in the AWS partition and delivers the log files to the Amazon S3 bucket that you specify. Additionally, you can configure other AWS services to further analyze and act upon the event data collected in CloudTrail logs. For more information, see the following: + + + +* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html[Overview for creating a trail] +* {https---docs-aws-amazon-com-awscloudtrail-latest-userguide-cloudtrail-aws-service-specific-topics-html-cloudtrail-aws-service-specific-topics-integrations}[CloudTrail supported services and integrations] +* {https---docs-aws-amazon-com-awscloudtrail-latest-userguide-getting-notifications-top-level-html}[Configuring Amazon SNS notifications for CloudTrail] +* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html[Receiving CloudTrail log files from multiple Regions] +* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html[Receiving CloudTrail log files from multiple accounts] + +All Amazon EKS actions are logged by CloudTrail and are documented in the https://docs.aws.amazon.com/slug/latest/APIReference/[Amazon EKS API Reference]. For example, calls to the ``ACTION_1``, `ACTION_2` and `ACTION_3` actions generate entries in the CloudTrail log files. + +Every event or log entry contains information about who generated the request. The identity information helps you determine the following: + + + +* Whether the request was made with root or AWS Identity and Access Management (IAM) user credentials. +* Whether the request was made with temporary security credentials for a role or federated user. +* Whether the request was made by another AWS service. + +For more information, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html[CloudTrail userIdentity element]. + +[[understanding-service-name-entries,understanding-service-name-entries.title]] +== Understanding Amazon EKS log file entries + +A trail is a configuration that enables delivery of events as log files to an Amazon S3 bucket that you specify. CloudTrail log files contain one or more log entries. An event represents a single request from any source and includes information about the requested action, the date and time of the action, request parameters, and so on. CloudTrail log files aren't an ordered stack trace of the public API calls, so they don't appear in any specific order. + +The following example shows a CloudTrail log entry that demonstrates the action. + +[source,json] +---- + +---- \ No newline at end of file diff --git a/latest/userguide/compliance-validation.adoc b/latest/userguide/compliance-validation.adoc new file mode 100644 index 000000000..35196715b --- /dev/null +++ b/latest/userguide/compliance-validation.adoc @@ -0,0 +1,31 @@ +//!!NODE_ROOT
+:https---d0-awsstatic-com-whitepapers-compliance-AWS-HIPAA-Compliance-Whitepaper-pdf: https://d0.awsstatic.com/whitepapers/compliance/AWS_HIPAA_Compliance_Whitepaper.pdf + +[."topic"] +[[compliance-validation,compliance-validation.title]] += Compliance validation for Amazon EKS +:info_doctype: section +:info_title: Compliance validation for Amazon EKS +:info_titleabbrev: Compliance validation +:info_abstract: Learn what AWS services are in scope of a specific compliance program. + +[abstract] +-- +Learn what AWS services are in scope of a specific compliance program. +-- + +Third-party auditors assess the security and compliance of Amazon EKS as part of multiple AWS compliance programs. These include SOC, PCI, FedRAMP, HIPAA, and others. + +For a list of AWS services in scope of specific compliance programs, see http://aws.amazon.com/compliance/services-in-scope/[AWS Services in Scope by Compliance Program]. For general information, see http://aws.amazon.com/compliance/programs/[AWS Compliance Programs]. + +You can download third-party audit reports using AWS Artifact. For more information, see https://docs.aws.amazon.com/artifact/latest/ug/downloading-documents.html[Downloading Reports in AWS Artifact]. + +Your compliance responsibility when using Amazon EKS is determined by the sensitivity of your data, your company's compliance objectives, and applicable laws and regulations. AWS provides the following resources to help with compliance: + + + +* http://aws.amazon.com/quickstart/?awsf.quickstart-homepage-filter=categories%23security-identity-compliance[Security and Compliance Quick Start Guides] – These deployment guides discuss architectural considerations and provide steps for deploying security- and compliance-focused baseline environments on AWS. +* {https---d0-awsstatic-com-whitepapers-compliance-AWS-HIPAA-Compliance-Whitepaper-pdf}[Architecting for HIPAA Security and Compliance Whitepaper] – This whitepaper describes how companies can use AWS to create HIPAA-compliant applications. +* http://aws.amazon.com/compliance/resources/[AWS Compliance Resources] – This collection of workbooks and guides might apply to your industry and location. +* https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html[Evaluating Resources with Rules] in the _AWS Config Developer Guide_ – AWS Config; assesses how well your resource configurations comply with internal practices, industry guidelines, and regulations. +* https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html[AWS Security Hub] – This AWS service provides a comprehensive view of your security state within AWS that helps you check your compliance with security industry standards and best practices. diff --git a/latest/userguide/data-protection.adoc b/latest/userguide/data-protection.adoc new file mode 100644 index 000000000..9c3fa5232 --- /dev/null +++ b/latest/userguide/data-protection.adoc @@ -0,0 +1,40 @@ +//!!NODE_ROOT
+ +[."topic"] +[[data-protection,data-protection.title]] += Data protection in Amazon EKS +:info_doctype: section +:info_title: Data protection in Amazon EKS +:info_titleabbrev: Data protection +:info_abstract: Learn how the [.shared]`AWS` shared responsibility model applies to data protection in \ + Amazon EKS. + +[abstract] +-- +Learn how the [.shared]`AWS` shared responsibility model applies to data protection in Amazon EKS. +-- + +The [.shared]`AWS` http://aws.amazon.com/compliance/shared-responsibility-model/[shared responsibility model] applies to data protection in Amazon EKS. As described in this model, [.shared]`AWS` is responsible for protecting the global infrastructure that runs all of the [.shared]`AWS-Cloud`. You are responsible for maintaining control over your content that is hosted on this infrastructure. This content includes the security configuration and management tasks for the [.shared]`AWS-services` that you use. For more information about data privacy, see the http://aws.amazon.com/compliance/data-privacy-faq[Data Privacy FAQ].For information about data protection in Europe, see the http://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr[[.shared]`AWS` Shared Responsibility Model and GDPR] blog post on the __AWS Security Blog__. + +For data protection purposes, we recommend that you protect [.shared]`AWS-account` credentials and set up individual users with [.shared]`IAMlong` ([.shared]`IAM`). That way each user is given only the permissions necessary to fulfill their job duties. We also recommend that you secure your data in the following ways: + + + +* Use multi-factor authentication (MFA) with each account. +* Use SSL/TLS to communicate with [.shared]`AWS` resources. We recommend TLS 1.2 or later. +* Set up API and user activity logging with [.shared]`CTlong`. +* Use [.shared]`AWS` encryption solutions, along with all default security controls within [.shared]`AWS-services`. +* Use advanced managed security services such as [.shared]`MCElong`, which assists in discovering and securing sensitive data that is stored in [.shared]`S3`. +* If you require FIPS 140-2 validated cryptographic modules when accessing [.shared]`AWS` through a command line interface or an API, use a FIPS endpoint. For more information about the available FIPS endpoints, see http://aws.amazon.com/compliance/fips/[Federal Information Processing Standard (FIPS) 140-2]. + +We strongly recommend that you never put sensitive identifying information, such as your customers' account numbers, into free-form fields such as a *Name* field. This includes when you work with Amazon EKS or other [.shared]`AWS-services` using the console, API, [.shared]`CLI`, or [.shared]`AWS` SDKs. Any data that you enter into Amazon EKS or other services might get picked up for inclusion in diagnostic logs. When you provide a URL to an external server, don't include credentials information in the URL to validate your request to that server. + +[[encryption-rest,encryption-rest.title]] +== Encryption at rest + +TBD + +[[encryption-transit,encryption-transit.title]] +== Encryption in transit + +TBD \ No newline at end of file diff --git a/latest/userguide/disaster-recovery-resiliency.adoc b/latest/userguide/disaster-recovery-resiliency.adoc new file mode 100644 index 000000000..4246ce8bc --- /dev/null +++ b/latest/userguide/disaster-recovery-resiliency.adoc @@ -0,0 +1,19 @@ +//!!NODE_ROOT
+ +[."topic"] +[[disaster-recovery-resiliency,disaster-recovery-resiliency.title]] += Resilience in Amazon EKS +:info_doctype: section +:info_title: Resilience in Amazon EKS +:info_titleabbrev: Resilience +:info_abstract: Learn how AWS architecture supports data redundancy, and learn about specific \ + Amazon EKS features for data resiliency. + +[abstract] +-- +Learn how AWS architecture supports data redundancy, and learn about specific Amazon EKS features for data resiliency. +-- + +The AWS global infrastructure is built around AWS Regions and Availability Zones. Regions provide multiple physically separated and isolated Availability Zones, which are connected through low-latency, high-throughput, and highly redundant networking. With Availability Zones, you can design and operate applications and databases that automatically fail over between zones without interruption. Availability Zones are more highly available, fault tolerant, and scalable than traditional single or multiple data center infrastructures. + +For more information about AWS Regions and Availability Zones, see http://aws.amazon.com/about-aws/global-infrastructure/[AWS Global Infrastructure]. \ No newline at end of file diff --git a/latest/userguide/doc-history.adoc b/latest/userguide/doc-history.adoc new file mode 100644 index 000000000..a67bf8f68 --- /dev/null +++ b/latest/userguide/doc-history.adoc @@ -0,0 +1,51 @@ +//!!NODE_ROOT +[."topic"] +[[doc-history,doc-history.title]] += Document history for the Amazon EKS User Guide +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Document history for the Amazon EKS User Guide +:info_titleabbrev: Document history +:info_abstract: Find the revision dates and related releases for Amazon EKS. + +[abstract] +-- +Find the revision dates and related releases for Amazon EKS. +-- + +[.updates] +== updates + +[.update,date="2020-09-20"] +=== Initial Creation of AsciiDoc Syntax Page + +[.update-ulink] +http://amazon.com[Ignored Text] + +The AsciiDoc Syntax Page was added + +[.details] +==== details +This is some additional details as an example + +[.update,date="2021-09-20"] +=== Added Updates +Added ability to add updates + + +[.details] +==== details +Also added details feature + +The following table describes the documentation releases for Amazon EKS. + +[.update-history] +|=== +|=== diff --git a/latest/userguide/getting-started.adoc b/latest/userguide/getting-started.adoc new file mode 100644 index 000000000..f6a2b36aa --- /dev/null +++ b/latest/userguide/getting-started.adoc @@ -0,0 +1,89 @@ +//!!NODE_ROOT +[."topic"] +[[getting-started,getting-started.title]] += Getting started with Amazon EKS +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Getting started with Amazon EKS +:info_titleabbrev: Getting started +:info_abstract: Get started with Amazon EKS. + +[abstract] +-- +Get started with Amazon EKS. +-- + +Introductory paragraph here. This paragraph should be brief, explain why to do the task, approximately how long it will take, costs (if any), and the outcome of the task. It should include the service name and service long name if appropriate. + +[.topiclist] +[[Topic List]] + +[[getting-started-prerequisites,getting-started-prerequisites.title]] +== Prerequisites + +Text that introduces the steps that must occur before the tutorial is started. Include a link to your Setting up section if you have one. + + + +* Text +* Text +* Text + + +[[getting-started-step1,getting-started-step1.title]] +== Step 1: Name of step + +Text + +. Text +. Text +. Text + + +[[getting-started-step2,getting-started-step2.title]] +== Step 2: Name of step + +Text + +. Text +. Text +. Text + + +[[getting-started-step3,getting-started-step3.title]] +== Step 3: Name of step + +Text + +. Text +. Text +. Text + + +[[getting-started-cleanup,getting-started-cleanup.title]] +== Step 4: Clean up + +Text + +. Text +. Text +. Text + + +[[getting-started-next-steps,getting-started-next-steps.title]] +== Next steps + +Text + + + +* Text +* Text +* Text diff --git a/latest/userguide/monitoring.adoc b/latest/userguide/monitoring.adoc new file mode 100644 index 000000000..45ba6e84c --- /dev/null +++ b/latest/userguide/monitoring.adoc @@ -0,0 +1,82 @@ +//!!NODE_ROOT +[."topic"] +[[monitoring-overview,monitoring-overview.title]] += Monitoring Amazon EKS +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Monitoring Amazon EKS +:info_titleabbrev: Monitoring +:info_abstract: Monitor Amazon EKS to maintain reliability, availability, and performance. + +[abstract] +-- +Monitor Amazon EKS to maintain reliability, availability, and performance. +-- + +Monitoring is an important part of maintaining the reliability, availability, and performance of Amazon EKS and your other AWS solutions. AWS provides the following monitoring tools to watch Amazon EKS, report when something is wrong, and take automatic actions when appropriate: + + + +* _Amazon CloudWatch_ monitors your AWS resources and and the applications you run on AWS in real time. You can collect and track metrics, create customized dashboards, and set alarms that notify you or take actions when a specified metric reaches a threshold that you specify. For example, you can have CloudWatch track CPU usage or other metrics of your Amazon EC2 instances and automatically launch new instances when needed. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/[Amazon CloudWatch User Guide]. +* _Amazon CloudWatch Logs_ enables you to monitor, store, and access your log files from Amazon EC2 instances, CloudTrail, and other sources. CloudWatch Logs can monitor information in the log files and notify you when certain thresholds are met. You can also archive your log data in highly durable storage. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/[Amazon CloudWatch Logs User Guide]. +* _Amazon EventBridge_ can be used to automate your AWS services and respond automatically to system events, such as application availability issues or resource changes. Events from AWS services are delivered to EventBridge in near real time. You can write simple rules to indicate which events are of interest to you and which automated actions to take when an event matches a rule. For more information, see https://docs.aws.amazon.com/eventbridge/latest/userguide/[Amazon EventBridge User Guide]. +* _AWS CloudTrail_ captures API calls and related events made by or on behalf of your AWS account and delivers the log files to an Amazon S3 bucket that you specify. You can identify which users and accounts called AWS, the source IP address from which the calls were made, and when the calls occurred. For more information, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/[AWS CloudTrail User Guide]. + + +[."topic"] +[[monitoring-cloudwatch,monitoring-cloudwatch.title]] +== Monitoring Amazon EKS with Amazon CloudWatch + +You can monitor Amazon EKS using CloudWatch, which collects raw data and processes it into readable, near real-time metrics. These statistics are kept for 15 months, so that you can access historical information and gain a better perspective on how your web application or service is performing. You can also set alarms that watch for certain thresholds, and send notifications or take actions when those thresholds are met. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/[Amazon CloudWatch User Guide]. + +For Amazon EKS, you might want to watch for [replaceable]``XXX``, and also watch [replaceable]``XXX`` and [replaceable]``Take Automatic Action`` when [replaceable]``This Happens``. + +The following tables list the metrics and dimensions for Amazon EKS. + +[."topic"] +[[monitoring-events,monitoring-events.title]] +== Monitoring Amazon EKS events in Amazon EventBridge + +You can monitor Amazon EKS events in EventBridge, which delivers a stream of real-time data from your own applications, software-as-a-service (SaaS) applications, and AWS services. EventBridge routes that data to targets such as AWS Lambda and Amazon Simple Notification Service. These events are the same as those that appear in Amazon CloudWatch Events, which delivers a near real-time stream of system events that describe changes in AWS resources. + +The following examples show events for Amazon EKS. + +[.topiclist] +[[Topic List]] + +[[eventname,eventName.title]] +=== eventName event + +In this example event, . + +[source] +---- +{ + "version": "0", + "id": "01234567-EXAMPLE", + "detail-type": "ServiceName ResourceType State Change", + "source": "aws.servicename", + "account": "123456789012", + "time": "2019-06-12T10:23:43Z", + "region": "us-east-2", + "resources": [ + "arn:aws:servicename:us-east-2:123456789012:resourcename" + ], + "detail": { + "event": "eventName", + "detailOne": "something", + "detailTwo": "12345678-1234-5678-abcd-12345678abcd", + "detailThree": "something", + "detailFour": "something" + } +} +---- + +include::cloudtrail.adoc[leveloffset=+1] diff --git a/latest/userguide/network-isolation.adoc b/latest/userguide/network-isolation.adoc new file mode 100644 index 000000000..a99048af7 --- /dev/null +++ b/latest/userguide/network-isolation.adoc @@ -0,0 +1,21 @@ +//!!NODE_ROOT
+:https---d0-awsstatic-com-whitepapers-Security-AWS-Security-Whitepaper-pdf: https://d0.awsstatic.com/whitepapers/Security/AWS_Security_Whitepaper.pdf + +[."topic"] +[[infrastructure-security,infrastructure-security.title]] += Infrastructure security in Amazon EKS +:info_doctype: section +:info_title: Infrastructure security in Amazon EKS +:info_titleabbrev: Infrastructure security +:info_abstract: Learn how Amazon EKS isolates service traffic. + +[abstract] +-- +Learn how Amazon EKS isolates service traffic. +-- + +As a managed service, Amazon EKS is protected by the AWS global network security procedures that are described in the {https---d0-awsstatic-com-whitepapers-Security-AWS-Security-Whitepaper-pdf}[Amazon Web Services: Overview of Security Processes] whitepaper. + +You use AWS published API calls to access Amazon EKS through the network. Clients must support Transport Layer Security (TLS) 1.0 or later. We recommend TLS 1.2 or later. Clients must also support cipher suites with perfect forward secrecy (PFS) such as Ephemeral Diffie-Hellman (DHE) or Elliptic Curve Ephemeral Diffie-Hellman (ECDHE). Most modern systems such as Java 7 and later support these modes. + +Additionally, requests must be signed using an access key ID and a secret access key that is associated with an IAM principal. Or you can use the https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html[AWS Security Token Service] (AWS STS) to generate temporary security credentials to sign requests. \ No newline at end of file diff --git a/latest/userguide/private-link-template.adoc b/latest/userguide/private-link-template.adoc new file mode 100644 index 000000000..c7c02cb61 --- /dev/null +++ b/latest/userguide/private-link-template.adoc @@ -0,0 +1,91 @@ +//!!NODE_ROOT +:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-access-service-though-endpoint: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#access-service-though-endpoint +:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-create-interface-endpoint: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint +:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-vpce-interface-limitations: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#vpce-interface-limitations +[."topic"] +[[vpc-interface-endpoints,vpc-interface-endpoints.title]] += Amazon EKS and interface VPC endpoints (AWS PrivateLink) +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Amazon EKS and interface VPC endpoints \ + (AWS PrivateLink) +:info_titleabbrev: VPC endpoints (AWS PrivateLink) +:info_abstract: You can use an interface VPC endpoint to create \ + a private connection between your VPC and Amazon EKS without requiring access over the \ + internet or through a NAT device, a VPN connection, or an AWS Direct Connect connection. + +[abstract] +-- +You can use an interface VPC endpoint to create a private connection between your VPC and Amazon EKS without requiring access over the internet or through a NAT device, a VPN connection, or an AWS Direct Connect connection. +-- + +You can establish a private connection between your VPC and Amazon EKS by creating an __interface VPC endpoint__. Interface endpoints are powered by http://aws.amazon.com/privatelink[AWS PrivateLink], a technology that enables you to privately access Amazon EKS APIs without an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC don't need public IP addresses to communicate with Amazon EKS APIs. Traffic between your VPC and Amazon EKS does not leave the Amazon network. + +Each interface endpoint is represented by one or more https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html[Elastic Network Interfaces] in your subnets. + +For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html[Interface VPC endpoints (AWS PrivateLink)] in the __Amazon VPC User Guide__. + +[[vpc-endpoint-considerations,vpc-endpoint-considerations.title]] +== Considerations for Amazon EKS VPC endpoints + +Before you set up an interface VPC endpoint for Amazon EKS, ensure that you review {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-vpce-interface-limitations}[Interface endpoint properties and limitations] in the __Amazon VPC User Guide__. + +Amazon EKS supports making calls to all of its API actions from your VPC. + +VPC endpoint policies are not supported for Amazon EKS. By default, full access to Amazon EKS is allowed through the endpoint. For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html[Controlling access to services with VPC endpoints] in the __Amazon VPC User Guide__. + +[[vpc-endpoint-create,vpc-endpoint-create.title]] +== Creating an interface VPC endpoint for Amazon EKS + +You can create a VPC endpoint for the Amazon EKS service using either the Amazon VPC console or the AWS Command Line Interface (AWS CLI). For more information, see {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-create-interface-endpoint}[Creating an interface endpoint] in the __Amazon VPC User Guide__. + +Create a VPC endpoint for Amazon EKS using the following service name: + + + +* com.amazonaws.[replaceable]``region``. + +If you enable private DNS for the endpoint, you can make API requests to Amazon EKS using its default DNS name for the Region, for example, ``.us-east-1.amazonaws.com``. + +For more information, see {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-access-service-though-endpoint}[Accessing a service through an interface endpoint] in the __Amazon VPC User Guide__. + +[[vpc-endpoint-policy,vpc-endpoint-policy.title]] +== Creating a VPC endpoint policy for Amazon EKS + +You can attach an endpoint policy to your VPC endpoint that controls access to Amazon EKS. The policy specifies the following information: + + + +* The principal that can perform actions. +* The actions that can be performed. +* The resources on which actions can be performed. + +For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html[Controlling access to services with VPC endpoints] in the __Amazon VPC User Guide__. + +.Example: VPC endpoint policy for Amazon EKS actions +The following is an example of an endpoint policy for Amazon EKS. When attached to an endpoint, this policy grants access to the listed Amazon EKS actions for all principals on all resources. + +[source] +---- +{ + "Statement":[ + { + "Principal":"*", + "Effect":"Allow", + "Action":[ + "servicename:action-1", + "servicename:action-2", + "servicename:action-2" + ], + "Resource":"*" + } + ] +} +---- \ No newline at end of file diff --git a/latest/userguide/quotas.adoc b/latest/userguide/quotas.adoc new file mode 100644 index 000000000..e34814d54 --- /dev/null +++ b/latest/userguide/quotas.adoc @@ -0,0 +1,43 @@ +//!!NODE_ROOT +:https---console-aws-amazon-com-support-home--case-create-issueType-service-limit-increase: https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase +[[load-balancer-limits,load-balancer-limits.title]] += Quotas for Amazon EKS +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Quotas for Amazon EKS +:info_titleabbrev: Quotas +:info_abstract: Learn about the quotas for Amazon EKS. + +[abstract] +-- +Learn about the quotas for Amazon EKS. +-- + +Your AWS account has default quotas, formerly referred to as limits, for each AWS service. Unless otherwise noted, each quota is Region-specific. You can request increases for some quotas, and other quotas cannot be increased. + +To view the quotas for Amazon EKS, open the https://console.aws.amazon.com/servicequotas/home[Service Quotas console]. In the navigation pane, choose *AWS services* and select **Amazon EKS**. + +To request a quota increase, see https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html[Requesting a Quota Increase] in the __Service Quotas User Guide__. If the quota is not yet available in Service Quotas, use the {https---console-aws-amazon-com-support-home--case-create-issueType-service-limit-increase}[limit increase form]. + +Your AWS account has the following quotas related to Amazon EKS. + +[[quotas-table]] +[cols="1,1", options="header"] +|=== +| Resource +| Default + + +|Quota +|Description + +|Quota +|Description +|=== \ No newline at end of file diff --git a/latest/userguide/security-iam.adoc b/latest/userguide/security-iam.adoc new file mode 100644 index 000000000..6d33d868d --- /dev/null +++ b/latest/userguide/security-iam.adoc @@ -0,0 +1,640 @@ +//!!NODE_ROOT
+:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-federated-users-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-third-party-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-aws-accounts-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_aws-accounts.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-getting-started-create-delegated-user-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-delegated-user.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-access-keys-html-Using-CreateAccessKey: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html-Conditions-IPAddress: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_IPAddress +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-change-permissions-html-users-change-permissions-add-console: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console +:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-grant-least-privilege: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-bp-use-aws-defined-policies: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html-access-policies-create-json-editor: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-role +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-linked-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role +:https---docs-aws-amazon-com-STS-latest-APIReference-API-GetFederationToken-html: https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html +:https---docs-aws-amazon-com-STS-latest-APIReference-API-AssumeRole-html: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html +:https---docs-aws-amazon-com-general-latest-gr-acct-identifiers-html-FindingCanonicalId: https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html#FindingCanonicalId +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-principal-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-policy-keys: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-policy-keys +:https---docs-aws-amazon-com-AWSEC2-latest-UserGuide-ExamplePolicies-EC2-html-iam-example-region: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-region +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-condition-keys-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-variables-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-resources-for-iam-policies: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-resources-for-iam-policies +:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-actions-as-permissions +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-aws-services-that-work-with-iam-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-evaluation-logic-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-policies-session: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session +:https---docs-aws-amazon-com-organizations-latest-userguide-orgs-manage-policies-about-scps-html: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_about-scps.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-boundaries-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-managed-vs-inline-html-choosing-managed-or-inline: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#choosing-managed-or-inline +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-access-policies-json: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#access_policies-json +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_which-to-choose_role +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-ec2-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-create-for-service-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_compare-resource-policies.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-introduction-access-management-html-intro-access-roles: https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_access-management.html#intro-access-roles +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-providers-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-console-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose: https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_which-to-choose +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-groups-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-access-keys-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-create-iam-users: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-analyzer-policy-validation: https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-validation.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-configure-api-require-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html + +[."topic"] +[[security-iam,security-iam.title]] += Identity and access management for Amazon EKS +:info_doctype: section +:info_title: Identity and access management for Amazon EKS +:info_titleabbrev: Identity and access management +:info_abstract: How to authenticate requests and manage access your Amazon EKS \ + resources. + +[abstract] +-- +How to authenticate requests and manage access your Amazon EKS resources. +-- + +[.shared]`IAMlong` ([.shared]`IAM`) is an [.shared]`AWS-service` that helps an administrator securely control access to [.shared]`AWS` resources. [.shared]`IAM` administrators control who can be _authenticated_ (signed in) and _authorized_ (have permissions) to use Amazon EKS resources. [.shared]`IAM` is an [.shared]`AWS-service` that you can use with no additional charge. + +[.topiclist] +[[Topic List]] + +[[security-iam-audience,security_iam_audience.title]] +== Audience + +How you use [.shared]`IAMlong` ([.shared]`IAM`) differs, depending on the work you do in Amazon EKS. + +*Service user* – If you use the Amazon EKS service to do your job, then your administrator provides you with the credentials and permissions that you need. As you use more Amazon EKS features to do your work, you might need additional permissions. Understanding how access is managed can help you request the right permissions from your administrator. If you cannot access a feature in Amazon EKS, see xref:security-iam-troubleshoot[Troubleshooting Amazon EKS identity and access,linkend=security_iam_troubleshoot]. + +*Service administrator* – If you're in charge of Amazon EKS resources at your company, you probably have full access to Amazon EKS. It's your job to determine which Amazon EKS features and resources your service users should access. You must then submit requests to your [.shared]`IAM` administrator to change the permissions of your service users. Review the information on this page to understand the basic concepts of [.shared]`IAM`. To learn more about how your company can use [.shared]`IAM` with Amazon EKS, see xref:security-iam-service-with-iam[How Amazon EKS works with [.shared]`IAM`,linkend=security_iam_service-with-iam]. + +*[.shared]`IAM` administrator* – If you're an [.shared]`IAM` administrator, you might want to learn details about how you can write policies to manage access to Amazon EKS. To view example Amazon EKS identity-based policies that you can use in [.shared]`IAM`, see xref:security-iam-id-based-policy-examples[Amazon EKS identity-based policy examples,linkend=security_iam_id-based-policy-examples]. + +[[security-iam-authentication,security_iam_authentication.title]] +== Authenticating with identities + +Authentication is how you sign in to [.shared]`AWS` using your identity credentials. You must be _authenticated_ (signed in to [.shared]`AWS`) as the AWS account root user, an [.shared]`IAM-user`, or by assuming an [.shared]`IAM` role. + +You can sign in to [.shared]`AWS` as a federated identity by using credentials provided through an identity source. [.shared]`SSOlong` ([.shared]`SSO`) users, your company's single sign-on authentication, and your Google or Facebook credentials are examples of federated identities. When you sign in as a federated identity, your administrator previously set up identity federation using [.shared]`IAM` roles. When you access [.shared]`AWS` by using federation, you are indirectly assuming a role. + +Depending on the type of user you are, you can sign in to the [.shared]`console` or the [.shared]`AWS` access portal. For more information about signing in to [.shared]`AWS`, see https://docs.aws.amazon.com/signin/latest/userguide/how-to-sign-in.html[How to sign in to your [.shared]`AWS-account`] in the _AWS Sign-In User Guide_. + +If you access [.shared]`AWS` programmatically, [.shared]`AWS` provides a software development kit (SDK) and a command line interface (CLI) to cryptographically sign your requests using your credentials. If you don't use [.shared]`AWS` tools, you must sign requests yourself. For more information about using the recommended method to sign requests yourself, see https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html[Signature Version 4 signing process] in the _AWS General Reference_. + +Regardless of the authentication method that you use, you might also be required to provide additional security information. For example, [.shared]`AWS` recommends that you use multi-factor authentication (MFA) to increase the security of your account. To learn more, see https://docs.aws.amazon.com/singlesignon/latest/userguide/enable-mfa.html[Multi-factor authentication] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_ and {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-html}[Using multi-factor authentication (MFA) in [.shared]`AWS`] in the _IAM User Guide_. + +[[security-iam-authentication-rootuser,security_iam_authentication-rootuser.title]] +=== AWS account root user + +When you first create an [.shared]`AWS-account`, you begin with a single sign-in identity that has complete access to all [.shared]`AWS-services` and resources in the account. This identity is called the AWS account root user and is accessed by signing in with the email address and password that you used to create the account. We strongly recommend that you don't use the root user for your everyday tasks. Safeguard your root user credentials and use them to perform tasks that only the root user can perform. For the complete list of tasks that require you to sign in as the root user, see https://docs.aws.amazon.com/accounts/latest/reference/root-user-tasks.html[Tasks that require root user credentials] in the _Account Management Reference Guide_. + +[[security-iam-authentication-federateduser,security_iam_authentication-federateduser.title]] +=== Federated identity + +As a best practice, require human users, including users that require administrator access, to use federation with an identity provider to access [.shared]`AWS-services` by using temporary credentials. + +A federated identity is a user from your enterprise user directory, a web identity provider, the [.shared]`ADSlong`, the Identity Center directory, or any user that accesses [.shared]`AWS-services` by using credentials provided through an identity source. When federated identities access [.shared]`AWS-accounts`, they assume roles, and the roles provide temporary credentials. + +For centralized access management, we recommend that you use [.shared]`SSOlong`. You can create users and groups in IAM Identity Center, or you can connect and synchronize to a set of users and groups in your own identity source for use across all your [.shared]`AWS-accounts` and applications. For information about IAM Identity Center, see https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[What is IAM Identity Center?] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_. + +[[security-iam-authentication-iamuser,security_iam_authentication-iamuser.title]] +=== [.shared]`IAM-users` and groups + +An _{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-html}[[.shared]`IAM-user`]_ is an identity within your [.shared]`AWS-account` that has specific permissions for a single person or application. Where possible, we recommend relying on temporary credentials instead of creating [.shared]`IAM-users` who have long-term credentials such as passwords and access keys. However, if you have specific use cases that require long-term credentials with [.shared]`IAM-users`, we recommend that you rotate access keys. For more information, see https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials[Rotate access keys regularly for use cases that require long-term credentials] in the __IAM User Guide__. + +An {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-groups-html}[[.shared]`IAM` group] is an identity that specifies a collection of [.shared]`IAM-users`. You can't sign in as a group. You can use groups to specify permissions for multiple users at a time. Groups make permissions easier to manage for large sets of users. For example, you could have a group named _IAMAdmins_ and give that group permissions to administer [.shared]`IAM` resources. + +Users are different from roles. A user is uniquely associated with one person or application, but a role is intended to be assumable by anyone who needs it. Users have permanent long-term credentials, but roles provide temporary credentials. To learn more, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose}[When to create an [.shared]`IAM-user` (instead of a role)] in the __IAM User Guide__. + +[[security-iam-authentication-iamrole,security_iam_authentication-iamrole.title]] +=== [.shared]`IAM` roles + +An _{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html}[[.shared]`IAM` role]_ is an identity within your [.shared]`AWS-account` that has specific permissions. It is similar to an [.shared]`IAM-user`, but is not associated with a specific person. You can temporarily assume an [.shared]`IAM` role in the [.shared]`console` by {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-console-html}[switching roles]. You can assume a role by calling an [.shared]`CLI` or [.shared]`AWS` API operation or by using a custom URL. For more information about methods for using roles, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-html}[Using [.shared]`IAM` roles] in the __IAM User Guide__. + +[.shared]`IAM` roles with temporary credentials are useful in the following situations: + +* *Federated user access* – To assign permissions to a federated identity, you create a role and define permissions for the role. When a federated identity authenticates, the identity is associated with the role and is granted the permissions that are defined by the role. For information about roles for federation, see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp.html[Creating a role for a third-party Identity Provider] in the _IAM User Guide_. If you use IAM Identity Center, you configure a permission set. To control what your identities can access after they authenticate, IAM Identity Center correlates the permission set to a role in [.shared]`IAM`. For information about permissions sets, see https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html[Permission sets] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_. + +* *Temporary [.shared]`IAM-user` permissions* – An [.shared]`IAM-user` can assume an [.shared]`IAM` role to temporarily take on different permissions for a specific task. + +* *Cross-account access* – You can use an [.shared]`IAM` role to allow someone (a trusted principal) in a different account to access resources in your account. Roles are the primary way to grant cross-account access. However, with some [.shared]`AWS-services`, you can attach a policy directly to a resource (instead of using a role as a proxy). To learn the difference between roles and resource-based policies for cross-account access, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies] in the __IAM User Guide__. + +* *Cross-service access* – Some [.shared]`AWS-services` use features in other [.shared]`AWS-services`. For example, when you make a call in a service, it's common for that service to run applications in [.shared]`EC2` or store objects in [.shared]`S3`. A service might do this using the calling principal's permissions, using a service role, or using a service-linked role. + + ** *Principal permissions* – When you use an [.shared]`IAM-user` or role to perform actions in [.shared]`AWS`, you are considered a principal. Policies grant permissions to a principal. When you use some services, you might perform an action that then triggers another action in a different service. In this case, you must have permissions to perform both actions. + + ** *Service role* – A service role is an [.shared]`IAM` role that a service assumes to perform actions on your behalf. An [.shared]`IAM` administrator can create, modify, and delete a service role from within [.shared]`IAM`. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-create-for-service-html}[Creating a role to delegate permissions to an [.shared]`AWS-service`] in the _IAM User Guide_. + + ** *Service-linked role* – A service-linked role is a type of service role that is linked to an [.shared]`AWS-service`. The service can assume the role to perform an action on your behalf. Service-linked roles appear in your [.shared]`AWS-account` and are owned by the service. An [.shared]`IAM` administrator can view, but not edit the permissions for service-linked roles. + +* *Applications running on [.shared]`EC2`* – You can use an [.shared]`IAM` role to manage temporary credentials for applications that are running on an [.shared]`EC2` instance and making [.shared]`CLI` or [.shared]`AWS` API requests. This is preferable to storing access keys within the [.shared]`EC2` instance. To assign an [.shared]`AWS` role to an [.shared]`EC2` instance and make it available to all of its applications, you create an instance profile that is attached to the instance. An instance profile contains the role and enables programs that are running on the [.shared]`EC2` instance to get temporary credentials. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-ec2-html}[Using an [.shared]`IAM` role to grant permissions to applications running on [.shared]`EC2` instances] in the __IAM User Guide__. + +To learn whether to use [.shared]`IAM` roles, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose-role}[When to create an [.shared]`IAM` role (instead of a user)] in the __IAM User Guide__. + +[[security-iam-access-manage,security_iam_access-manage.title]] +== Managing access using policies + +You control access in [.shared]`AWS` by creating policies and attaching them to [.shared]`AWS` identities or resources. A policy is an object in [.shared]`AWS` that, when associated with an identity or resource, defines their permissions. [.shared]`AWS` evaluates these policies when a principal (user, root user, or role session) makes a request. Permissions in the policies determine whether the request is allowed or denied. Most policies are stored in [.shared]`AWS` as JSON documents. For more information about the structure and contents of JSON policy documents, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-access-policies-json}[Overview of JSON policies] in the __IAM User Guide__. + +Administrators can use [.shared]`AWS` JSON policies to specify who has access to what. That is, which *principal* can perform *actions* on what *resources*, and under what *conditions*. + +Every [.shared]`IAM` entity (user or role) starts with no permissions. By default, users can do nothing, not even change their own password. To give a user permission to do something, an administrator must attach a permissions policy to a user. Or the administrator can add the user to a group that has the intended permissions. When an administrator gives permissions to a group, all users in that group are granted those permissions. + +[.shared]`IAM` policies define permissions for an action regardless of the method that you use to perform the operation. For example, suppose that you have a policy that allows the `iam:GetRole` action. A user with that policy can get role information from the [.shared]`console`, the [.shared]`CLI`, or the [.shared]`AWS` API. + +[[security-iam-access-manage-id-based-policies,security_iam_access-manage-id-based-policies.title]] +=== Identity-based policies + +Identity-based policies are JSON permissions policy documents that you can attach to an identity, such as an [.shared]`IAM-user`, role, or group. These policies control what actions users and roles can perform, on which resources, and under what conditions. To learn how to create an identity-based policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html}[Creating [.shared]`IAM` policies] in the __IAM User Guide__. + +Identity-based policies can be further categorized as _inline policies_ or __managed policies__. Inline policies are embedded directly into a single user, group, or role. Managed policies are standalone policies that you can attach to multiple users, groups, and roles in your [.shared]`AWS-account`. Managed policies include [.shared]`AWS` managed policies and customer managed policies. To learn how to choose between a managed policy or an inline policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-managed-vs-inline-html-choosing-managed-or-inline}[Choosing between managed policies and inline policies] in the __IAM User Guide__. + +[[security-iam-access-manage-resource-based-policies,security_iam_access-manage-resource-based-policies.title]] +=== Resource-based policies + +Resource-based policies are JSON policy documents that you attach to a resource such as an [.shared]`S3` bucket. Service administrators can use these policies to define what actions a specified principal (account member, user, or role) can perform on that resource and under what conditions. Resource-based policies are inline policies. There are no managed resource-based policies. + +[[security-iam-access-manage-acl,security_iam_access-manage-acl.title]] +=== Access control lists (ACLs) + +Access control lists (ACLs) are a type of policy that controls which principals (account members, users, or roles) have permissions to access a resource. ACLs are similar to resource-based policies, although they do not use the JSON policy document format. [.shared]`S3`, [.shared]`WAF`, and [.shared]`VPC` are examples of services that support ACLs. To learn more about ACLs, see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html[Access Control List (ACL) overview] in the __Amazon Simple Storage Service Developer Guide__. + +[[security-iam-access-manage-other-policies,security_iam_access-manage-other-policies.title]] +=== Other policy types + +[.shared]`AWS` supports additional, less-common policy types. These policy types can set the maximum permissions granted to you by the more common policy types. + + + +* *Permissions boundaries* – A permissions boundary is an advanced feature in which you set the maximum permissions that an identity-based policy can grant to an [.shared]`IAM` entity ([.shared]`IAM-user` or role). You can set a permissions boundary for an entity. The resulting permissions are the intersection of entity's identity-based policies and its permissions boundaries. Resource-based policies that specify the user or role in the `Principal` field are not limited by the permissions boundary. An explicit deny in any of these policies overrides the allow. For more information about permissions boundaries, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-boundaries-html}[Permissions boundaries for [.shared]`IAM` entities] in the __IAM User Guide__. +* *Service control policies (SCPs)* – SCPs are JSON policies that specify the maximum permissions for an organization or organizational unit (OU) in [.shared]`AOlong`. [.shared]`AOlong` is a service for grouping and centrally managing multiple [.shared]`AWS-accounts` that your business owns. If you enable all features in an organization, then you can apply service control policies (SCPs) to any or all of your accounts. The SCP limits permissions for entities in member accounts, including each AWS account root user. For more information about Organizations and SCPs, see {https---docs-aws-amazon-com-organizations-latest-userguide-orgs-manage-policies-about-scps-html}[How SCPs work] in the __AWS Organizations User Guide__. +* *Session policies* – Session policies are advanced policies that you pass as a parameter when you programmatically create a temporary session for a role or federated user. The resulting session's permissions are the intersection of the user or role's identity-based policies and the session policies. Permissions can also come from a resource-based policy. An explicit deny in any of these policies overrides the allow. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-policies-session}[Session policies] in the __IAM User Guide__. + + +[[security-iam-access-manage-multiple-policies,security_iam_access-manage-multiple-policies.title]] +=== Multiple policy types + +When multiple types of policies apply to a request, the resulting permissions are more complicated to understand. To learn how [.shared]`AWS` determines whether to allow a request when multiple policy types are involved, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-evaluation-logic-html}[Policy evaluation logic] in the __IAM User Guide__. + +[."topic"] +[[security-iam-service-with-iam,security_iam_service-with-iam.title]] +== How Amazon EKS works with [.shared]`IAM` + +Before you use [.shared]`IAM` to manage access to Amazon EKS, learn what [.shared]`IAM` features are available to use with Amazon EKS. To get a high-level view of how Amazon EKS and other [.shared]`AWS-services` work with [.shared]`IAM`, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-aws-services-that-work-with-iam-html}[[.shared]`AWS-services` that work with [.shared]`IAM`] in the __IAM User Guide__. + +[.topiclist] +[[Topic List]] + +[[security-iam-service-with-iam-id-based-policies,security_iam_service-with-iam-id-based-policies.title]] +=== Amazon EKS Identity-based policies + +With [.shared]`IAM` identity-based policies, you can specify allowed or denied actions and resources as well as the conditions under which actions are allowed or denied. You can't specify the principal in an identity-based policy because it applies to the user or role to which it is attached. To learn about all of the elements that you use in a JSON policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-html}[[.shared]`IAM` JSON policy elements reference] in the __IAM User Guide__. + +[[security-iam-service-with-iam-id-based-policies-actions,security_iam_service-with-iam-id-based-policies-actions.title]] +==== Actions + +The `Action` element of an [.shared]`IAM` identity-based policy describes the specific action or actions that will be allowed or denied by the policy. Policy actions usually have the same name as the associated [.shared]`AWS` API operation. The action is used in a policy to grant permissions to perform the associated operation. + +Policy actions in Amazon EKS use the following prefix before the action: ``YOUR-SERVICE-PREFIX:``. For example, to grant someone permission to run an [.shared]`EC2` instance with the [.shared]`EC2` `RunInstances` API operation, you include the `ec2:RunInstances` action in their policy. Policy statements must include either an `Action` or `NotAction` element. Amazon EKS defines its own set of actions that describe tasks that you can perform with this service. + +To specify multiple actions in a single statement, separate them with commas as follows: + +[source] +---- +"Action": [ + "ec2:action1", + "ec2:action2" +---- + +You can specify multiple actions using wildcards (*). For example, to specify all actions that begin with the word ``Describe``, include the following action: + +[source] +---- +"Action": "ec2:Describe*" +---- + + +To see a list of Amazon EKS actions, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions Defined by Amazon EKS] in the __IAM User Guide__. + +[[security-iam-service-with-iam-id-based-policies-resources,security_iam_service-with-iam-id-based-policies-resources.title]] +==== Resources + +The `Resource` element specifies the object or objects to which the action applies. Statements must include either a `Resource` or a `NotResource` element. You specify a resource using an ARN or using the wildcard (*) to indicate that the statement applies to all resources. + + +The [.shared]`EC2` instance resource has the following ARN: + +[source] +---- +arn:${Partition}:ec2:${Region}:${Account}:instance/${InstanceId} +---- + +For more information about the format of ARNs, see https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html[Amazon Resource Names (ARNs) and [.shared]`AWS-service` Namespaces]. + +For example, to specify the `i-1234567890abcdef0` instance in your statement, use the following ARN: + +[source] +---- +"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0" +---- + +To specify all instances that belong to a specific account, use the wildcard (*): + +[source] +---- +"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*" +---- + +Some Amazon EKS actions, such as those for creating resources, cannot be performed on a specific resource. In those cases, you must use the wildcard (*). + +[source] +---- +"Resource": "*" +---- + +Many [.shared]`EC2` API actions involve multiple resources. For example, `AttachVolume` attaches an Amazon EBS volume to an instance, so an [.shared]`IAM-user` must have permissions to use the volume and the instance. To specify multiple resources in a single statement, separate the ARNs with commas. + +[source] +---- +"Resource": [ + "resource1", + "resource2" +---- + +To see a list of Amazon EKS resource types and their ARNs, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-resources-for-iam-policies}[Resources Defined by Amazon EKS] in the __IAM User Guide__. To learn with which actions you can specify the ARN of each resource, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions Defined by Amazon EKS]. + +[[security-iam-service-with-iam-id-based-policies-conditionkeys,security_iam_service-with-iam-id-based-policies-conditionkeys.title]] +==== Condition keys + +The `Condition` element (or `Condition`__block__) lets you specify conditions in which a statement is in effect. The `Condition` element is optional. You can create conditional expressions that use {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html}[condition operators], such as equals or less than, to match the condition in the policy with values in the request. + +If you specify multiple `Condition` elements in a statement, or multiple keys in a single `Condition` element, [.shared]`AWS` evaluates them using a logical `AND` operation. If you specify multiple values for a single condition key, [.shared]`AWS` evaluates the condition using a logical `OR` operation. All of the conditions must be met before the statement's permissions are granted. + +You can also use placeholder variables when you specify conditions. For example, you can grant an [.shared]`IAM-user` permission to access a resource only if it is tagged with their [.shared]`IAM-user` name. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-variables-html}[[.shared]`IAM` policy elements: variables and tags] in the __IAM User Guide__. + +Amazon EKS defines its own set of condition keys and also supports using some global condition keys. To see all [.shared]`AWS` global condition keys, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-condition-keys-html}[[.shared]`AWS` global condition context keys] in the __IAM User Guide__. + + +All [.shared]`EC2` actions support the `aws:RequestedRegion` and `ec2:Region` condition keys. For more information, see {https---docs-aws-amazon-com-AWSEC2-latest-UserGuide-ExamplePolicies-EC2-html-iam-example-region}[Example: Restricting access to a specific region]. + +To see a list of Amazon EKS condition keys, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-policy-keys}[Condition Keys for Amazon EKS] in the __IAM User Guide__. To learn with which actions and resources you can use a condition key, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions defined by Amazon EKS]. + +[[security-iam-service-with-iam-id-based-policies-examples,security_iam_service-with-iam-id-based-policies-examples.title]] +==== Examples + + +To view examples of Amazon EKS identity-based policies, see xref:security-iam-id-based-policy-examples[Amazon EKS identity-based policy examples,linkend=security_iam_id-based-policy-examples]. + +[[security-iam-service-with-iam-resource-based-policies,security_iam_service-with-iam-resource-based-policies.title]] +=== Amazon EKS resource-based policies + +Resource-based policies are JSON policy documents that specify what actions a specified principal can perform on the Amazon EKS resource and under what conditions. [.shared]`S3` supports resource-based permissions policies for [.shared]`S3` [replaceable]``buckets``. Resource-based policies let you grant usage permission to other accounts on a per-resource basis. You can also use a resource-based policy to allow an [.shared]`AWS-service` to access your [.shared]`S3` [replaceable]``buckets``. + +To enable cross-account access, you can specify an entire account or [.shared]`IAM` entities in another account as the {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-principal-html}[principal in a resource-based policy]. Adding a cross-account principal to a resource-based policy is only half of establishing the trust relationship. When the principal and the resource are in different [.shared]`AWS-accounts`, you must also grant the principal entity permission to access the resource. Grant permission by attaching an identity-based policy to the entity. However, if a resource-based policy grants access to a principal in the same account, no additional identity-based policy is required. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies]in the __IAM User Guide__. + +The [.shared]`S3` service supports only one type of resource-based policy called a __[replaceable]``__bucket__`` policy__, which is attached to a [replaceable]``bucket``. This policy defines which principal entities (accounts, users, roles, and federated users) can perform actions on the [replaceable]``widget``. + +To learn how to attach a resource-based policy to a [replaceable]``bucket``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +[[security-iam-service-with-iam-resource-based-policies-examples,security_iam_service-with-iam-resource-based-policies-examples.title]] +==== Examples + + +To view examples of Amazon EKS resource-based policies, see xref:security-iam-resource-based-policy-examples[Amazon EKS resource-based policy examples,linkend=security_iam_resource-based-policy-examples], + +[[security-iam-service-with-iam-acls,security_iam_service-with-iam-acls.title]] +=== Access control lists (ACLs) + +Access control lists (ACLs) are lists of grantees that you can attach to resources. They grant accounts permissions to access the resource to which they are attached. You can attach ACLs to an [.shared]`S3` [replaceable]``bucket`` resource. For more information about attaching ACLs to [replaceable]``buckets``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +With [.shared]`S3` access control lists (ACLs), you can manage access to [replaceable]``bucket`` resources. Each [replaceable]``bucket`` has an ACL attached to it as a subresource. It defines which [.shared]`AWS-accounts`, [.shared]`IAM-users` or groups of users, or [.shared]`IAM` roles are granted access and the type of access. When a request is received for a resource, [.shared]`AWS` checks the corresponding ACL to verify that the requester has the necessary access permissions. + +When you create a [replaceable]``bucket`` resource, [.shared]`S3` creates a default ACL that grants the resource owner full control over the resource. In the following example [replaceable]``bucket`` ACL, John Doe is listed as the owner of the [replaceable]``bucket`` and is granted full control over that [replaceable]``bucket``. An ACL can have up to 100 grantees. + +[source] +---- + + + + c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6 + john-doe + + + + + c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6 + john-doe + + FULL_CONTROL + + + +---- + +The ID field in the ACL is the [.shared]`AWS-account` canonical user ID. To learn how to view this ID in an account that you own, see {https---docs-aws-amazon-com-general-latest-gr-acct-identifiers-html-FindingCanonicalId}[Finding an [.shared]`AWS-account` canonical user ID]. + +[[security-iam-service-with-iam-tags,security_iam_service-with-iam-tags.title]] +=== Authorization based on Amazon EKS tags + +You can attach tags to Amazon EKS resources or pass tags in a request to Amazon EKS. To control access based on tags, you provide tag information in the {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[condition element] of a policy using the ``YOUR-SERVICE-PREFIX:ResourceTag/[replaceable]``key-name````, ``aws:RequestTag/[replaceable]``key-name````, or `aws:TagKeys` condition keys. For more information about tagging Amazon EKS resources, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +To view an example identity-based policy for limiting access to a resource based on the tags on that resource, see xref:security-iam-id-based-policy-examples-view-widget-tags[Viewing Amazon EKS widgets based on tags,linkend=security_iam_id-based-policy-examples-view-widget-tags]. + +[[security-iam-service-with-iam-roles,security_iam_service-with-iam-roles.title]] +=== Amazon EKS [.shared]`IAM` roles + +An {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html}[[.shared]`IAM` role] is an entity within your [.shared]`AWS-account` that has specific permissions. + +[[security-iam-service-with-iam-roles-tempcreds,security_iam_service-with-iam-roles-tempcreds.title]] +==== Using temporary credentials with Amazon EKS + +You can use temporary credentials to sign in with federation, assume an [.shared]`IAM` role, or to assume a cross-account role. You obtain temporary security credentials by calling [.shared]`STS` API operations such as {https---docs-aws-amazon-com-STS-latest-APIReference-API-AssumeRole-html}[AssumeRole] or {https---docs-aws-amazon-com-STS-latest-APIReference-API-GetFederationToken-html}[GetFederationToken]. + +Amazon EKS supports using temporary credentials. + +[[security-iam-service-with-iam-roles-service-linked,security_iam_service-with-iam-roles-service-linked.title]] +==== Service-linked roles + +{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-linked-role}[Service-linked roles] allow [.shared]`AWS-services` to access resources in other services to complete an action on your behalf. Service-linked roles appear in your [.shared]`IAM` account and are owned by the service. An [.shared]`IAM` administrator can view but not edit the permissions for service-linked roles. + +Amazon EKS supports service-linked roles. For details about creating or managing Amazon EKS service-linked roles, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +[[security-iam-service-with-iam-roles-service,security_iam_service-with-iam-roles-service.title]] +==== Service roles + +This feature allows a service to assume a {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-role}[service role] on your behalf. This role allows the service to access resources in other services to complete an action on your behalf. Service roles appear in your [.shared]`IAM` account and are owned by the account. This means that an [.shared]`IAM` administrator can change the permissions for this role. However, doing so might break the functionality of the service. + +Amazon EKS supports service roles. + +[[security-iam-service-with-iam-roles-choose,security_iam_service-with-iam-roles-choose.title]] +==== Choosing an [.shared]`IAM` role in Amazon EKS + +When you create a [replaceable]``widget`` resource in Amazon EKS, you must choose a role to allow Amazon EKS to access [.shared]`EC2` on your behalf. If you have previously created a service role or service-linked role, then Amazon EKS provides you with a list of roles to choose from. It's important to choose a role that allows access to start and stop [.shared]`EC2` instances. For more information, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +[."topic"] +[[security-iam-id-based-policy-examples,security_iam_id-based-policy-examples.title]] +== Amazon EKS identity-based policy examples + +By default, [.shared]`IAM-users` and roles don't have permission to create or modify Amazon EKS resources. They also can't perform tasks using the [.shared]`console`, [.shared]`CLI`, or [.shared]`AWS` API. An [.shared]`IAM` administrator must create [.shared]`IAM` policies that grant users and roles permission to perform specific API operations on the specified resources they need. The administrator must then attach those policies to the [.shared]`IAM-users` or groups that require those permissions. + +To learn how to create an [.shared]`IAM` identity-based policy using these example JSON policy documents, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html-access-policies-create-json-editor}[Creating policies on the JSON tab] in the __IAM User Guide__. + +[.topiclist] +[[Topic List]] + +[[security-iam-service-with-iam-policy-best-practices,security_iam_service-with-iam-policy-best-practices.title]] +=== Policy best practices + +Identity-based policies determine whether someone can create, access, or delete Amazon EKS resources in your account. These actions can incur costs for your [.shared]`AWS-account`. When you create or edit identity-based policies, follow these guidelines and recommendations: + + + +* *Get started with [.shared]`AWS` managed policies and move toward least-privilege permissions* – To get started granting permissions to your users and workloads, use the [.shared]`AWS` managed policies that grant permissions for many common use cases. They are available in your [.shared]`AWS-account`. We recommend that you reduce permissions further by defining [.shared]`AWS` customer managed policies that are specific to your use cases. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-bp-use-aws-defined-policies}[[.shared]`AWS` managed policies] or https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html[[.shared]`AWS` managed policies for job functions] in the __IAM User Guide__. + +* *Apply least-privilege permissions* – When you set permissions with [.shared]`IAM` policies, grant only the permissions required to perform a task. You do this by defining the actions that can be taken on specific resources under specific conditions, also known as _least-privilege permissions_. For more information about using [.shared]`IAM` to apply permissions, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-grant-least-privilege}[Policies and permissions in [.shared]`IAM`] in the __IAM User Guide__. + +* *Use conditions in [.shared]`IAM` policies to further restrict access* – You can add a condition to your policies to limit access to actions and resources. For example, you can write a policy condition to specify that all requests must be sent using SSL. You can also use conditions to grant access to service actions if they are used through a specific [.shared]`AWS-service`, such as [.shared]`CFN`. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[[.shared]`IAM` JSON policy elements: condition] in the __IAM User Guide__. + +* *Use [.shared]`iam-citadel` to validate your [.shared]`IAM` policies to ensure secure and functional permissions* – [.shared]`iam-citadel` validates new and existing policies so that the policies adhere to the [.shared]`IAM` policy language (JSON) and [.shared]`IAM` best practices. [.shared]`iam-citadel` provides more than 100 policy checks and actionable recommendations to help you author secure and functional policies. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-analyzer-policy-validation}[[.shared]`iam-citadel` policy validation] in the __IAM User Guide__. + +* *Require multi-factor authentication (MFA)* – If you have a scenario that requires [.shared]`IAM-users` or root users in your account, turn on MFA for additional security. To require MFA when API operations are called, add MFA conditions to your policies. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-configure-api-require-html}[Configuring MFA-protected API access] in the __IAM User Guide__. + + + +[[security-iam-id-based-policy-examples-console,security_iam_id-based-policy-examples-console.title]] +=== Using the Amazon EKS console + +To access the Amazon EKS console, you must have a minimum set of permissions. These permissions must allow you to list and view details about the Amazon EKS resources in your [.shared]`AWS-account`. If you create an identity-based policy that is more restrictive than the minimum required permissions, the console won't function as intended for entities (users or roles) with that policy. + +To ensure that those entities can still use the Amazon EKS console, also attach the following [.shared]`AWS` managed policy to the entities. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-change-permissions-html-users-change-permissions-add-console}[Adding permissions to a user] in the __IAM User Guide__: + +[source] +---- +AWSAwesomeConsoleAccess +---- + +You don't need to allow minimum console permissions for users that are making calls only to the [.shared]`CLI` or the [.shared]`AWS` API. Instead, allow access to only the actions that match the API operation that you're trying to perform. + +[[security-iam-id-based-policy-examples-view-own-permissions,security_iam_id-based-policy-examples-view-own-permissions.title]] +=== Allow users to view their own permissions + +This example shows how you might create a policy that allows [.shared]`IAM-users` to view the inline and managed policies that are attached to their user identity. This policy includes permissions to complete this action on the console or programmatically using the [.shared]`CLI` or [.shared]`AWS` API. + +[source] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ViewOwnUserInfo", + "Effect": "Allow", + "Action": [ + "iam:GetUserPolicy", + "iam:ListGroupsForUser", + "iam:ListAttachedUserPolicies", + "iam:ListUserPolicies", + "iam:GetUser" + ], + "Resource": ["arn:aws:iam::*:user/${aws:username}"] + }, + { + "Sid": "NavigateInConsole", + "Effect": "Allow", + "Action": [ + "iam:GetGroupPolicy", + "iam:GetPolicyVersion", + "iam:GetPolicy", + "iam:ListAttachedGroupPolicies", + "iam:ListGroupPolicies", + "iam:ListPolicyVersions", + "iam:ListPolicies", + "iam:ListUsers" + ], + "Resource": "*" + } + ] +} +---- + + +[[security-iam-id-based-policy-examples-access-one-bucket,security_iam_id-based-policy-examples-access-one-bucket.title]] +=== Accessing one [.shared]`S3` bucket + +In this example, you want to grant an [.shared]`IAM-user` in your [.shared]`AWS-account` access to one of your [.shared]`S3` buckets, ``examplebucket``. You also want to allow the user to add, update, and delete objects. + +In addition to granting the ``s3:PutObject``, ``s3:GetObject``, and `s3:DeleteObject` permissions to the user, the policy also grants the ``s3:ListAllMyBuckets``, ``s3:GetBucketLocation``, and `s3:ListBucket` permissions. These are the additional permissions required by the console. Also, the `s3:PutObjectAcl` and the `s3:GetObjectAcl` actions are required to be able to copy, cut, and paste objects in the console. For an example walkthrough that grants permissions to users and tests them using the console, see https://docs.aws.amazon.com/AmazonS3/latest/dev/walkthrough1.html[An Example Walkthrough: Using user policies to control access to your bucket]. + +[source] +---- +{ + "Version":"2012-10-17", + "Statement":[ + { + "Sid":"ListBucketsInConsole", + "Effect":"Allow", + "Action":[ + "s3:ListAllMyBuckets" + ], + "Resource":"arn:aws:s3:::*" + }, + { + "Sid":"ViewSpecificBucketInfo", + "Effect":"Allow", + "Action":[ + "s3:ListBucket", + "s3:GetBucketLocation" + ], + "Resource":"arn:aws:s3:::examplebucket" + }, + { + "Sid":"ManageBucketContents", + "Effect":"Allow", + "Action":[ + "s3:PutObject", + "s3:PutObjectAcl", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:DeleteObject" + ], + "Resource":"arn:aws:s3:::examplebucket/*" + } + ] +} +---- + + +[[security-iam-id-based-policy-examples-view-widget-tags,security_iam_id-based-policy-examples-view-widget-tags.title]] +=== Viewing Amazon EKS [replaceable]``widgets`` based on tags + +You can use conditions in your identity-based policy to control access to Amazon EKS resources based on tags. This example shows how you might create a policy that allows viewing a [replaceable]``widget``. However, permission is granted only if the [replaceable]``widget`` tag `Owner` has the value of that user's user name. This policy also grants the permissions necessary to complete this action on the console. + +[source] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ListWidgetsInConsole", + "Effect": "Allow", + "Action": "YOUR-SERVICE-PREFIX:ListWidgets", + "Resource": "*" + }, + { + "Sid": "ViewWidgetIfOwner", + "Effect": "Allow", + "Action": "YOUR-SERVICE-PREFIX:GetWidget", + "Resource": "arn:aws:YOUR-SERVICE-PREFIX:*:*:widget/*", + "Condition": { + "StringEquals": {"YOUR-SERVICE-PREFIX:ResourceTag/Owner": "${aws:username}"} + } + } + ] +} +---- + +You can attach this policy to the [.shared]`IAM-users` in your account. If a user named `richard-roe` attempts to view an Amazon EKS [replaceable]``widget``, the [replaceable]``widget`` must be tagged `Owner=richard-roe` or ``owner=richard-roe``. Otherwise he is denied access. The condition tag key `Owner` matches both `Owner` and `owner` because condition key names are not case-sensitive. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[[.shared]`IAM` JSON policy elements: condition] in the __IAM User Guide__. + +[."topic"] +[[security-iam-resource-based-policy-examples,security_iam_resource-based-policy-examples.title]] +== Amazon EKS resource-based policy examples + +To learn how to create a [replaceable]``widget``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. + +[.topiclist] +[[Topic List]] + +[[security-iam-resource-based-policy-examples-restrict-bucket-by-ip,security_iam_id-based-policy-examples-restrict-bucket-by-ip.title]] +=== Restricting [.shared]`S3` bucket access to specific IP addresses + +The following example grants permissions to any user to perform any [.shared]`S3` operations on objects in the specified bucket. However, the request must originate from the range of IP addresses specified in the condition. + +The condition in this statement identifies the 54.240.143.* range of allowed Internet Protocol version 4 (IPv4) IP addresses, with one exception: 54.240.143.188. + +The `Condition` block uses the `IpAddress` and `NotIpAddress` conditions and the `aws:SourceIp` condition key, which is an [.shared]`AWS` wide condition key. For more information about these condition keys, see https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html[Specifying Conditions in a Policy]. The``aws:sourceIp`` IPv4 values use the standard CIDR notation. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html-Conditions-IPAddress}[IP address condition operators] in the __IAM User Guide__. + +[source] +---- +{ + "Version": "2012-10-17", + "Id": "S3PolicyId1", + "Statement": [ + { + "Sid": "IPAllow", + "Effect": "Allow", + "Principal": "*", + "Action": "s3:*", + "Resource": "arn:aws:s3:::examplebucket/*", + "Condition": { + "IpAddress": {"aws:SourceIp": "54.240.143.0/24"}, + "NotIpAddress": {"aws:SourceIp": "54.240.143.188/32"} + } + } + ] +} +---- + + +[."topic"] +[[security-iam-troubleshoot,security_iam_troubleshoot.title]] +== Troubleshooting Amazon EKS identity and access + +Use the following information to help you diagnose and fix common issues that you might encounter when working with Amazon EKS and [.shared]`IAM`. + +[.topiclist] +[[Topic List]] + +[[security-iam-troubleshoot-no-permissions,security_iam_troubleshoot-no-permissions.title]] +=== I am not authorized to perform an action in Amazon EKS + +If the [.shared]`console` tells you that you're not authorized to perform an action, then you must contact your administrator for assistance. Your administrator is the person that provided you with your user name and password. + +The following example error occurs when the `mateojackson` [.shared]`IAM-user` tries to use the console to view details about a [replaceable]``widget`` but does not have `YOUR-SERVICE-PREFIX:[replaceable]``GetWidget``` permissions. + +[source] +---- +User: arn:aws:iam::123456789012:user/mateojackson is not authorized to perform: YOUR-SERVICE-PREFIX:GetWidget on resource: my-example-widget +---- + +In this case, Mateo asks his administrator to update his policies to allow him to access the `[replaceable]``my-example-widget``` resource using the `YOUR-SERVICE-PREFIX:[replaceable]``GetWidget``` action. + +[[security-iam-troubleshoot-passrole,security_iam_troubleshoot-passrole.title]] +=== I am not authorized to perform iam:PassRole + +If you receive an error that you're not authorized to perform the `iam:PassRole` action, then you must contact your administrator for assistance. Your administrator is the person that provided you with your user name and password. Ask that person to update your policies to allow you to pass a role to Amazon EKS. + +Some [.shared]`AWS-services` allow you to pass an existing role to that service, instead of creating a new service role or service-linked role. To do this, you must have permissions to pass the role to the service. + +The following example error occurs when an [.shared]`IAM-user` named `marymajor` tries to use the console to perform an action in Amazon EKS. However, the action requires the service to have permissions granted by a service role. Mary does not have permissions to pass the role to the service. + +[source] +---- +User: arn:aws:iam::123456789012:user/marymajor is not authorized to perform: iam:PassRole +---- + +In this case, Mary asks her administrator to update her policies to allow her to perform the `iam:PassRole` action. + +[[security-iam-troubleshoot-cross-account-access,security_iam_troubleshoot-cross-account-access.title]] +=== I want to allow people outside of my [.shared]`AWS-account` to access my Amazon EKS resources + +You can create a role that users in other accounts or people outside of your organization can use to access your resources. You can specify who is trusted to assume the role. For services that support resource-based policies or access control lists (ACLs), you can use those policies to grant people access to your resources. + +To learn more, consult the following: + + + +* To learn whether Amazon EKS supports these features, see xref:security-iam-service-with-iam[How Amazon EKS works with [.shared]`IAM`,linkend=security_iam_service-with-iam]. +* To learn how to provide access to your resources across [.shared]`AWS-accounts` that you own, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-aws-accounts-html}[Providing access to an [.shared]`IAM-user` in another [.shared]`AWS-account` that you own] in the __IAM User Guide__. +* To learn how to provide access to your resources to third-party [.shared]`AWS-accounts`, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-third-party-html}[Providing access to [.shared]`AWS-accounts` owned by third parties] in the __IAM User Guide__. +* To learn how to provide access through identity federation, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-federated-users-html}[Providing Access to Externally Authenticated Users (Identity Federation)] in the __IAM User Guide__. +* To learn the difference between using roles and resource-based policies for cross-account access, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies] in the __IAM User Guide__. diff --git a/latest/userguide/security.adoc b/latest/userguide/security.adoc new file mode 100644 index 000000000..6f5a20379 --- /dev/null +++ b/latest/userguide/security.adoc @@ -0,0 +1,50 @@ +//!!NODE_ROOT +[."topic"] +[[security,security.title]] += Security in Amazon EKS +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Security in Amazon EKS +:info_titleabbrev: Security +:info_abstract: Configure Amazon EKS to meet your security and compliance objectives, and learn how to \ + use other AWS services that help you to secure your Amazon EKS resources. + +[abstract] +-- +Configure Amazon EKS to meet your security and compliance objectives, and learn how to use other AWS services that help you to secure your Amazon EKS resources. +-- + +Cloud security at AWS is the highest priority. As an AWS customer, you benefit from a data center and network architecture that is built to meet the requirements of the most security-sensitive organizations. + +Security is a shared responsibility between AWS and you. The http://aws.amazon.com/compliance/shared-responsibility-model/[shared responsibility model] describes this as security of the cloud and security in the cloud: + + + +* *Security of the cloud* – AWS is responsible for protecting the infrastructure that runs AWS services in the AWS Cloud. AWS also provides you with services that you can use securely. Third-party auditors regularly test and verify the effectiveness of our security as part of the http://aws.amazon.com/compliance/programs/[AWS Compliance Programs]. To learn about the compliance programs that apply to Amazon EKS, see http://aws.amazon.com/compliance/services-in-scope/[AWS Services in Scope by Compliance Program]. +* *Security in the cloud* – Your responsibility is determined by the AWS service that you use. You are also responsible for other factors including the sensitivity of your data, your company`'s requirements, and applicable laws and regulations + +This documentation helps you understand how to apply the shared responsibility model when using Amazon EKS. It shows you how to configure Amazon EKS to meet your security and compliance objectives. You also learn how to use other AWS services that help you to monitor and secure your Amazon EKS resources. + +[.topiclist-abbrev] +Contents + +include::data-protection.adoc[leveloffset=+1] + + +include::security-iam.adoc[leveloffset=+1] Commenting out until can fix syntax issue + + +include::compliance-validation.adoc[leveloffset=+1] + + +include::disaster-recovery-resiliency.adoc[leveloffset=+1] + + +include::network-isolation.adoc[leveloffset=+1] diff --git a/latest/userguide/setting-up.adoc b/latest/userguide/setting-up.adoc new file mode 100644 index 000000000..73f286aab --- /dev/null +++ b/latest/userguide/setting-up.adoc @@ -0,0 +1,65 @@ +//!!NODE_ROOT +:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-examples-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-tags-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html +:https---docs-aws-amazon-com-IAM-latest-UserGuide-tutorial-billing-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_billing.html +:https---docs-aws-amazon-com-general-latest-gr-aws-tasks-that-require-root-html: https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html +[."topic"] +[[setting-up,setting-up.title]] += Setting up Amazon EKS +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Setting up Amazon EKS +:info_abstract: Insert chapter abstract text here. + +[abstract] +-- +Insert chapter abstract text here. +-- + +Insert your introductory paragraph here. + +[.topiclist] +[[Topic List]] + +[[setting-up-aws-sign-up,setting-up-aws-sign-up.title]] +== Sign up for AWS + +If you do not have an AWS account, complete the following steps to create one. + +. Open https://portal.aws.amazon.com/billing/signup. +. Follow the online instructions. ++ + +Part of the sign-up procedure involves receiving a phone call and entering a verification code on the phone keypad. + + +[[setting-up-create-iam-user,setting-up-create-iam-user.title]] +== Create an IAM user +. Sign in to the https://console.aws.amazon.com/iam/[IAM console] as the account owner by choosing *Root user* and entering your AWS account email address. On the next page, enter your password. ++ +NOTE: We strongly recommend that you adhere to the best practice of using the `Administrator` IAM user below and securely lock away the root user credentials. Sign in as the root user only to perform a few {https---docs-aws-amazon-com-general-latest-gr-aws-tasks-that-require-root-html}[account and service management tasks]. +. In the navigation pane, choose *Users* and then choose **Add user**. +. For **User name**, enter ``Administrator``. +. Select the check box next to **AWS Management Console access**. Then select **Custom password**, and then enter your new password in the text box. +. (Optional) By default, AWS requires the new user to create a new password when first signing in. You can clear the check box next to *User must create a new password at next sign-in* to allow the new user to reset their password after they sign in. +. Choose **Next: Permissions**. +. Under **Set permissions**, choose **Add user to group**. +. Choose **Create group**. +. In the *Create group* dialog box, for *Group name* enter ``Administrators``. +. Choose **Filter policies**, and then select *AWS managed -job function* to filter the table contents. +. In the policy list, select the check box for **AdministratorAccess**. Then choose **Create group**. ++ +NOTE: You must activate IAM user and role access to Billing before you can use the `AdministratorAccess` permissions to access the AWS Billing and Cost Management console. To do this, follow the instructions in {https---docs-aws-amazon-com-IAM-latest-UserGuide-tutorial-billing-html}[step 1 of the tutorial about delegating access to the billing console]. +. Back in the list of groups, select the check box for your new group. Choose *Refresh* if necessary to see the group in the list. +. Choose **Next: Tags**. +. (Optional) Add metadata to the user by attaching tags as key-value pairs. For more information about using tags in IAM, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-tags-html}[Tagging IAM Entities] in the __IAM User Guide__. +. Choose *Next: Review* to see the list of group memberships to be added to the new user. When you are ready to proceed, choose **Create user**. + +You can use this same process to create more groups and users and to give your users access to your AWS account resources. To learn about using policies that restrict user permissions to specific AWS resources, see https://docs.aws.amazon.com/IAM/latest/UserGuide/access.html[Access Management] and {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-examples-html}[Example Policies]. \ No newline at end of file diff --git a/latest/userguide/what-is.adoc b/latest/userguide/what-is.adoc new file mode 100644 index 000000000..192788ede --- /dev/null +++ b/latest/userguide/what-is.adoc @@ -0,0 +1,52 @@ +//!!NODE_ROOT +[."topic"] +[[what-is-service,what-is-service.title]] += What is Amazon EKS? +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: What is Amazon EKS? +:info_abstract: Learn about Amazon EKS, a service that... + +[abstract] +-- +Learn about Amazon EKS, a service that... +-- + +Amazon EKS is... Describe what your service is and how customers can use it. + +[.topiclist] +[[Topic List]] + +[[first-time-user,first-time-user.title]] +== Are you a first-time Amazon EKS user? + +If you are a first-time user of Amazon EKS, we recommend that you begin by reading the following sections: + + + +* Text +* Text +* Text + + +[[servicename-feature-overview,servicename-feature-overview.title]] +== Features of Amazon EKS + +Include a brief but descriptive list of service features. If you need to go into more depth on a feature, consider adding a How It Works conceptual topic. + +[[related-services,related-services.title]] +== Related services + +Offer a list of related services complete with links to the best place to start for each service. Briefly explain how the service is related. If you don't have any, remove this section. + +[[acessing-servicename,acessing-servicename.title]] +== Accessing Amazon EKS + +Briefly explain the different ways to gain access to the service, whether by console, CLI, or API. \ No newline at end of file From 77b0e51705797584177725dd2f3df8742722ff34 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Thu, 11 Apr 2024 23:07:25 +0000 Subject: [PATCH 02/56] remove init files --- latest/userguide/book.adoc | 23 - latest/userguide/cloudformation-template.adoc | 44 -- latest/userguide/cloudtrail.adoc | 59 -- latest/userguide/compliance-validation.adoc | 31 - latest/userguide/data-protection.adoc | 40 -- .../disaster-recovery-resiliency.adoc | 19 - latest/userguide/doc-history.adoc | 51 -- latest/userguide/getting-started.adoc | 89 --- latest/userguide/monitoring.adoc | 82 --- latest/userguide/network-isolation.adoc | 21 - latest/userguide/private-link-template.adoc | 91 --- latest/userguide/quotas.adoc | 43 -- latest/userguide/security-iam.adoc | 640 ------------------ latest/userguide/security.adoc | 50 -- latest/userguide/setting-up.adoc | 65 -- 15 files changed, 1348 deletions(-) delete mode 100644 latest/userguide/cloudformation-template.adoc delete mode 100644 latest/userguide/cloudtrail.adoc delete mode 100644 latest/userguide/compliance-validation.adoc delete mode 100644 latest/userguide/data-protection.adoc delete mode 100644 latest/userguide/disaster-recovery-resiliency.adoc delete mode 100644 latest/userguide/doc-history.adoc delete mode 100644 latest/userguide/getting-started.adoc delete mode 100644 latest/userguide/monitoring.adoc delete mode 100644 latest/userguide/network-isolation.adoc delete mode 100644 latest/userguide/private-link-template.adoc delete mode 100644 latest/userguide/quotas.adoc delete mode 100644 latest/userguide/security-iam.adoc delete mode 100644 latest/userguide/security.adoc delete mode 100644 latest/userguide/setting-up.adoc diff --git a/latest/userguide/book.adoc b/latest/userguide/book.adoc index b47587ba0..c0ea29c26 100644 --- a/latest/userguide/book.adoc +++ b/latest/userguide/book.adoc @@ -31,26 +31,3 @@ Insert abstract text include::what-is.adoc[leveloffset=+1] - -include::setting-up.adoc[leveloffset=+1] - - -include::getting-started.adoc[leveloffset=+1] - - -include::security.adoc[leveloffset=+1] - - -include::monitoring.adoc[leveloffset=+1] - - -include::cloudformation-template.adoc[leveloffset=+1] - - -include::private-link-template.adoc[leveloffset=+1] - - -include::quotas.adoc[leveloffset=+1] - - -// include::doc-history.adoc[leveloffset=+1] Commenting out until can fix syntax issue diff --git a/latest/userguide/cloudformation-template.adoc b/latest/userguide/cloudformation-template.adoc deleted file mode 100644 index 33d5cfa26..000000000 --- a/latest/userguide/cloudformation-template.adoc +++ /dev/null @@ -1,44 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[creating-resources-with-cloudformation,creating-resources-with-cloudformation.title]] -= Creating Amazon EKS resources with AWS CloudFormation -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Creating Amazon EKS resources with \ - AWS CloudFormation -:info_titleabbrev: AWS CloudFormation resources -:info_abstract: Learn about how to create resources for Amazon EKS using an AWS CloudFormation template. - -[abstract] --- -Learn about how to create resources for Amazon EKS using an AWS CloudFormation template. --- - -Amazon EKS is integrated with AWS CloudFormation, a service that helps you model and set up your AWS resources so that you can spend less time creating and managing your resources and infrastructure. You create a template that describes all the AWS resources that you want (like YOUR-RESOURCE-PLURAL), and AWS CloudFormation takes care of provisioning and configuring those resources for you. - -When you use AWS CloudFormation, you can reuse your template to set up your Amazon EKS resources consistently and repeatedly. Just describe your resources once, and then provision the same resources over and over in multiple AWS accounts and Regions. - -[[working-with-templates,working-with-templates.title]] -== Amazon EKS and AWS CloudFormation templates - -To provision and configure resources for Amazon EKS and related services, you must understand https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html[AWS CloudFormation templates]. Templates are formatted text files in JSON or YAML. These templates describe the resources that you want to provision in your AWS CloudFormation stacks. If you're unfamiliar with JSON or YAML, you can use AWS CloudFormation Designer to help you get started with AWS CloudFormation templates. For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/working-with-templates-cfn-designer.html[What is AWS CloudFormation Designer?] in the __AWS CloudFormation User Guide__. - -Amazon EKS supports creating YOUR-RESOURCE-PLURAL in AWS CloudFormation. For more information, including examples of JSON and YAML templates for YOUR-RESOURCE-PLURAL, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html[YOUR-SERVICE-RESOURCE-TOPNODE-IN-CLOUDFORMATION, modify this link in the local-phrases.ent file] in the __AWS CloudFormation User Guide__. - -[[learn-more-cloudformation,learn-more-cloudformation.title]] -== Learn more about AWS CloudFormation - -To learn more about AWS CloudFormation, see the following resources: - - - -* http://aws.amazon.com/cloudformation/[AWS CloudFormation] -* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html[AWS CloudFormation User Guide] -* https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html[AWS CloudFormation Command Line Interface User Guide] diff --git a/latest/userguide/cloudtrail.adoc b/latest/userguide/cloudtrail.adoc deleted file mode 100644 index 289bde10a..000000000 --- a/latest/userguide/cloudtrail.adoc +++ /dev/null @@ -1,59 +0,0 @@ -//!!NODE_ROOT
-:https---docs-aws-amazon-com-awscloudtrail-latest-userguide-getting-notifications-top-level-html: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/getting_notifications_top_level.html -:https---docs-aws-amazon-com-awscloudtrail-latest-userguide-cloudtrail-aws-service-specific-topics-html-cloudtrail-aws-service-specific-topics-integrations: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-aws-service-specific-topics.html#cloudtrail-aws-service-specific-topics-integrations - -[."topic"] -[[logging-using-cloudtrail,logging-using-cloudtrail.title]] -= Logging Amazon EKS API calls using AWS CloudTrail -:info_doctype: section -:info_title: Logging Amazon EKS API calls using AWS CloudTrail -:info_titleabbrev: CloudTrail logs -:info_abstract: Learn about logging Amazon EKS with AWS CloudTrail. - -[abstract] --- -Learn about logging Amazon EKS with AWS CloudTrail. --- - -Amazon EKS is integrated with AWS CloudTrail, a service that provides a record of actions taken by a user, role, or an AWS service in Amazon EKS. CloudTrail captures all API calls for Amazon EKS as events. The calls captured include calls from the Amazon EKS console and code calls to the Amazon EKS API operations. If you create a trail, you can enable continuous delivery of CloudTrail events to an Amazon S3 bucket, including events for Amazon EKS. If you don't configure a trail, you can still view the most recent events in the CloudTrail console in **Event history**. Using the information collected by CloudTrail, you can determine the request that was made to Amazon EKS, the IP address from which the request was made, who made the request, when it was made, and additional details. - -To learn more about CloudTrail, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/[AWS CloudTrail User Guide]. - -[[service-name-info-in-cloudtrail,service-name-info-in-cloudtrail.title]] -== Amazon EKS information in CloudTrail - -CloudTrail is enabled on your AWS account when you create the account. When activity occurs in Amazon EKS, that activity is recorded in a CloudTrail event along with other AWS service events in **Event history**. You can view, search, and download recent events in your AWS account. For more information, see https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html[Viewing Events with CloudTrail Event History]. - -For an ongoing record of events in your AWS account, including events for Amazon EKS, create a trail. A _trail_ enables CloudTrail to deliver log files to an Amazon S3 bucket. By default, when you create a trail in the console, the trail applies to all AWS Regions. The trail logs events from all Regions in the AWS partition and delivers the log files to the Amazon S3 bucket that you specify. Additionally, you can configure other AWS services to further analyze and act upon the event data collected in CloudTrail logs. For more information, see the following: - - - -* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail.html[Overview for creating a trail] -* {https---docs-aws-amazon-com-awscloudtrail-latest-userguide-cloudtrail-aws-service-specific-topics-html-cloudtrail-aws-service-specific-topics-integrations}[CloudTrail supported services and integrations] -* {https---docs-aws-amazon-com-awscloudtrail-latest-userguide-getting-notifications-top-level-html}[Configuring Amazon SNS notifications for CloudTrail] -* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/receive-cloudtrail-log-files-from-multiple-regions.html[Receiving CloudTrail log files from multiple Regions] -* https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-receive-logs-from-multiple-accounts.html[Receiving CloudTrail log files from multiple accounts] - -All Amazon EKS actions are logged by CloudTrail and are documented in the https://docs.aws.amazon.com/slug/latest/APIReference/[Amazon EKS API Reference]. For example, calls to the ``ACTION_1``, `ACTION_2` and `ACTION_3` actions generate entries in the CloudTrail log files. - -Every event or log entry contains information about who generated the request. The identity information helps you determine the following: - - - -* Whether the request was made with root or AWS Identity and Access Management (IAM) user credentials. -* Whether the request was made with temporary security credentials for a role or federated user. -* Whether the request was made by another AWS service. - -For more information, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html[CloudTrail userIdentity element]. - -[[understanding-service-name-entries,understanding-service-name-entries.title]] -== Understanding Amazon EKS log file entries - -A trail is a configuration that enables delivery of events as log files to an Amazon S3 bucket that you specify. CloudTrail log files contain one or more log entries. An event represents a single request from any source and includes information about the requested action, the date and time of the action, request parameters, and so on. CloudTrail log files aren't an ordered stack trace of the public API calls, so they don't appear in any specific order. - -The following example shows a CloudTrail log entry that demonstrates the action. - -[source,json] ----- - ----- \ No newline at end of file diff --git a/latest/userguide/compliance-validation.adoc b/latest/userguide/compliance-validation.adoc deleted file mode 100644 index 35196715b..000000000 --- a/latest/userguide/compliance-validation.adoc +++ /dev/null @@ -1,31 +0,0 @@ -//!!NODE_ROOT
-:https---d0-awsstatic-com-whitepapers-compliance-AWS-HIPAA-Compliance-Whitepaper-pdf: https://d0.awsstatic.com/whitepapers/compliance/AWS_HIPAA_Compliance_Whitepaper.pdf - -[."topic"] -[[compliance-validation,compliance-validation.title]] -= Compliance validation for Amazon EKS -:info_doctype: section -:info_title: Compliance validation for Amazon EKS -:info_titleabbrev: Compliance validation -:info_abstract: Learn what AWS services are in scope of a specific compliance program. - -[abstract] --- -Learn what AWS services are in scope of a specific compliance program. --- - -Third-party auditors assess the security and compliance of Amazon EKS as part of multiple AWS compliance programs. These include SOC, PCI, FedRAMP, HIPAA, and others. - -For a list of AWS services in scope of specific compliance programs, see http://aws.amazon.com/compliance/services-in-scope/[AWS Services in Scope by Compliance Program]. For general information, see http://aws.amazon.com/compliance/programs/[AWS Compliance Programs]. - -You can download third-party audit reports using AWS Artifact. For more information, see https://docs.aws.amazon.com/artifact/latest/ug/downloading-documents.html[Downloading Reports in AWS Artifact]. - -Your compliance responsibility when using Amazon EKS is determined by the sensitivity of your data, your company's compliance objectives, and applicable laws and regulations. AWS provides the following resources to help with compliance: - - - -* http://aws.amazon.com/quickstart/?awsf.quickstart-homepage-filter=categories%23security-identity-compliance[Security and Compliance Quick Start Guides] – These deployment guides discuss architectural considerations and provide steps for deploying security- and compliance-focused baseline environments on AWS. -* {https---d0-awsstatic-com-whitepapers-compliance-AWS-HIPAA-Compliance-Whitepaper-pdf}[Architecting for HIPAA Security and Compliance Whitepaper] – This whitepaper describes how companies can use AWS to create HIPAA-compliant applications. -* http://aws.amazon.com/compliance/resources/[AWS Compliance Resources] – This collection of workbooks and guides might apply to your industry and location. -* https://docs.aws.amazon.com/config/latest/developerguide/evaluate-config.html[Evaluating Resources with Rules] in the _AWS Config Developer Guide_ – AWS Config; assesses how well your resource configurations comply with internal practices, industry guidelines, and regulations. -* https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html[AWS Security Hub] – This AWS service provides a comprehensive view of your security state within AWS that helps you check your compliance with security industry standards and best practices. diff --git a/latest/userguide/data-protection.adoc b/latest/userguide/data-protection.adoc deleted file mode 100644 index 9c3fa5232..000000000 --- a/latest/userguide/data-protection.adoc +++ /dev/null @@ -1,40 +0,0 @@ -//!!NODE_ROOT
- -[."topic"] -[[data-protection,data-protection.title]] -= Data protection in Amazon EKS -:info_doctype: section -:info_title: Data protection in Amazon EKS -:info_titleabbrev: Data protection -:info_abstract: Learn how the [.shared]`AWS` shared responsibility model applies to data protection in \ - Amazon EKS. - -[abstract] --- -Learn how the [.shared]`AWS` shared responsibility model applies to data protection in Amazon EKS. --- - -The [.shared]`AWS` http://aws.amazon.com/compliance/shared-responsibility-model/[shared responsibility model] applies to data protection in Amazon EKS. As described in this model, [.shared]`AWS` is responsible for protecting the global infrastructure that runs all of the [.shared]`AWS-Cloud`. You are responsible for maintaining control over your content that is hosted on this infrastructure. This content includes the security configuration and management tasks for the [.shared]`AWS-services` that you use. For more information about data privacy, see the http://aws.amazon.com/compliance/data-privacy-faq[Data Privacy FAQ].For information about data protection in Europe, see the http://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr[[.shared]`AWS` Shared Responsibility Model and GDPR] blog post on the __AWS Security Blog__. - -For data protection purposes, we recommend that you protect [.shared]`AWS-account` credentials and set up individual users with [.shared]`IAMlong` ([.shared]`IAM`). That way each user is given only the permissions necessary to fulfill their job duties. We also recommend that you secure your data in the following ways: - - - -* Use multi-factor authentication (MFA) with each account. -* Use SSL/TLS to communicate with [.shared]`AWS` resources. We recommend TLS 1.2 or later. -* Set up API and user activity logging with [.shared]`CTlong`. -* Use [.shared]`AWS` encryption solutions, along with all default security controls within [.shared]`AWS-services`. -* Use advanced managed security services such as [.shared]`MCElong`, which assists in discovering and securing sensitive data that is stored in [.shared]`S3`. -* If you require FIPS 140-2 validated cryptographic modules when accessing [.shared]`AWS` through a command line interface or an API, use a FIPS endpoint. For more information about the available FIPS endpoints, see http://aws.amazon.com/compliance/fips/[Federal Information Processing Standard (FIPS) 140-2]. - -We strongly recommend that you never put sensitive identifying information, such as your customers' account numbers, into free-form fields such as a *Name* field. This includes when you work with Amazon EKS or other [.shared]`AWS-services` using the console, API, [.shared]`CLI`, or [.shared]`AWS` SDKs. Any data that you enter into Amazon EKS or other services might get picked up for inclusion in diagnostic logs. When you provide a URL to an external server, don't include credentials information in the URL to validate your request to that server. - -[[encryption-rest,encryption-rest.title]] -== Encryption at rest - -TBD - -[[encryption-transit,encryption-transit.title]] -== Encryption in transit - -TBD \ No newline at end of file diff --git a/latest/userguide/disaster-recovery-resiliency.adoc b/latest/userguide/disaster-recovery-resiliency.adoc deleted file mode 100644 index 4246ce8bc..000000000 --- a/latest/userguide/disaster-recovery-resiliency.adoc +++ /dev/null @@ -1,19 +0,0 @@ -//!!NODE_ROOT
- -[."topic"] -[[disaster-recovery-resiliency,disaster-recovery-resiliency.title]] -= Resilience in Amazon EKS -:info_doctype: section -:info_title: Resilience in Amazon EKS -:info_titleabbrev: Resilience -:info_abstract: Learn how AWS architecture supports data redundancy, and learn about specific \ - Amazon EKS features for data resiliency. - -[abstract] --- -Learn how AWS architecture supports data redundancy, and learn about specific Amazon EKS features for data resiliency. --- - -The AWS global infrastructure is built around AWS Regions and Availability Zones. Regions provide multiple physically separated and isolated Availability Zones, which are connected through low-latency, high-throughput, and highly redundant networking. With Availability Zones, you can design and operate applications and databases that automatically fail over between zones without interruption. Availability Zones are more highly available, fault tolerant, and scalable than traditional single or multiple data center infrastructures. - -For more information about AWS Regions and Availability Zones, see http://aws.amazon.com/about-aws/global-infrastructure/[AWS Global Infrastructure]. \ No newline at end of file diff --git a/latest/userguide/doc-history.adoc b/latest/userguide/doc-history.adoc deleted file mode 100644 index a67bf8f68..000000000 --- a/latest/userguide/doc-history.adoc +++ /dev/null @@ -1,51 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[doc-history,doc-history.title]] -= Document history for the Amazon EKS User Guide -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Document history for the Amazon EKS User Guide -:info_titleabbrev: Document history -:info_abstract: Find the revision dates and related releases for Amazon EKS. - -[abstract] --- -Find the revision dates and related releases for Amazon EKS. --- - -[.updates] -== updates - -[.update,date="2020-09-20"] -=== Initial Creation of AsciiDoc Syntax Page - -[.update-ulink] -http://amazon.com[Ignored Text] - -The AsciiDoc Syntax Page was added - -[.details] -==== details -This is some additional details as an example - -[.update,date="2021-09-20"] -=== Added Updates -Added ability to add updates - - -[.details] -==== details -Also added details feature - -The following table describes the documentation releases for Amazon EKS. - -[.update-history] -|=== -|=== diff --git a/latest/userguide/getting-started.adoc b/latest/userguide/getting-started.adoc deleted file mode 100644 index f6a2b36aa..000000000 --- a/latest/userguide/getting-started.adoc +++ /dev/null @@ -1,89 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[getting-started,getting-started.title]] -= Getting started with Amazon EKS -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Getting started with Amazon EKS -:info_titleabbrev: Getting started -:info_abstract: Get started with Amazon EKS. - -[abstract] --- -Get started with Amazon EKS. --- - -Introductory paragraph here. This paragraph should be brief, explain why to do the task, approximately how long it will take, costs (if any), and the outcome of the task. It should include the service name and service long name if appropriate. - -[.topiclist] -[[Topic List]] - -[[getting-started-prerequisites,getting-started-prerequisites.title]] -== Prerequisites - -Text that introduces the steps that must occur before the tutorial is started. Include a link to your Setting up section if you have one. - - - -* Text -* Text -* Text - - -[[getting-started-step1,getting-started-step1.title]] -== Step 1: Name of step - -Text - -. Text -. Text -. Text - - -[[getting-started-step2,getting-started-step2.title]] -== Step 2: Name of step - -Text - -. Text -. Text -. Text - - -[[getting-started-step3,getting-started-step3.title]] -== Step 3: Name of step - -Text - -. Text -. Text -. Text - - -[[getting-started-cleanup,getting-started-cleanup.title]] -== Step 4: Clean up - -Text - -. Text -. Text -. Text - - -[[getting-started-next-steps,getting-started-next-steps.title]] -== Next steps - -Text - - - -* Text -* Text -* Text diff --git a/latest/userguide/monitoring.adoc b/latest/userguide/monitoring.adoc deleted file mode 100644 index 45ba6e84c..000000000 --- a/latest/userguide/monitoring.adoc +++ /dev/null @@ -1,82 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[monitoring-overview,monitoring-overview.title]] -= Monitoring Amazon EKS -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Monitoring Amazon EKS -:info_titleabbrev: Monitoring -:info_abstract: Monitor Amazon EKS to maintain reliability, availability, and performance. - -[abstract] --- -Monitor Amazon EKS to maintain reliability, availability, and performance. --- - -Monitoring is an important part of maintaining the reliability, availability, and performance of Amazon EKS and your other AWS solutions. AWS provides the following monitoring tools to watch Amazon EKS, report when something is wrong, and take automatic actions when appropriate: - - - -* _Amazon CloudWatch_ monitors your AWS resources and and the applications you run on AWS in real time. You can collect and track metrics, create customized dashboards, and set alarms that notify you or take actions when a specified metric reaches a threshold that you specify. For example, you can have CloudWatch track CPU usage or other metrics of your Amazon EC2 instances and automatically launch new instances when needed. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/[Amazon CloudWatch User Guide]. -* _Amazon CloudWatch Logs_ enables you to monitor, store, and access your log files from Amazon EC2 instances, CloudTrail, and other sources. CloudWatch Logs can monitor information in the log files and notify you when certain thresholds are met. You can also archive your log data in highly durable storage. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/[Amazon CloudWatch Logs User Guide]. -* _Amazon EventBridge_ can be used to automate your AWS services and respond automatically to system events, such as application availability issues or resource changes. Events from AWS services are delivered to EventBridge in near real time. You can write simple rules to indicate which events are of interest to you and which automated actions to take when an event matches a rule. For more information, see https://docs.aws.amazon.com/eventbridge/latest/userguide/[Amazon EventBridge User Guide]. -* _AWS CloudTrail_ captures API calls and related events made by or on behalf of your AWS account and delivers the log files to an Amazon S3 bucket that you specify. You can identify which users and accounts called AWS, the source IP address from which the calls were made, and when the calls occurred. For more information, see the https://docs.aws.amazon.com/awscloudtrail/latest/userguide/[AWS CloudTrail User Guide]. - - -[."topic"] -[[monitoring-cloudwatch,monitoring-cloudwatch.title]] -== Monitoring Amazon EKS with Amazon CloudWatch - -You can monitor Amazon EKS using CloudWatch, which collects raw data and processes it into readable, near real-time metrics. These statistics are kept for 15 months, so that you can access historical information and gain a better perspective on how your web application or service is performing. You can also set alarms that watch for certain thresholds, and send notifications or take actions when those thresholds are met. For more information, see the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/[Amazon CloudWatch User Guide]. - -For Amazon EKS, you might want to watch for [replaceable]``XXX``, and also watch [replaceable]``XXX`` and [replaceable]``Take Automatic Action`` when [replaceable]``This Happens``. - -The following tables list the metrics and dimensions for Amazon EKS. - -[."topic"] -[[monitoring-events,monitoring-events.title]] -== Monitoring Amazon EKS events in Amazon EventBridge - -You can monitor Amazon EKS events in EventBridge, which delivers a stream of real-time data from your own applications, software-as-a-service (SaaS) applications, and AWS services. EventBridge routes that data to targets such as AWS Lambda and Amazon Simple Notification Service. These events are the same as those that appear in Amazon CloudWatch Events, which delivers a near real-time stream of system events that describe changes in AWS resources. - -The following examples show events for Amazon EKS. - -[.topiclist] -[[Topic List]] - -[[eventname,eventName.title]] -=== eventName event - -In this example event, . - -[source] ----- -{ - "version": "0", - "id": "01234567-EXAMPLE", - "detail-type": "ServiceName ResourceType State Change", - "source": "aws.servicename", - "account": "123456789012", - "time": "2019-06-12T10:23:43Z", - "region": "us-east-2", - "resources": [ - "arn:aws:servicename:us-east-2:123456789012:resourcename" - ], - "detail": { - "event": "eventName", - "detailOne": "something", - "detailTwo": "12345678-1234-5678-abcd-12345678abcd", - "detailThree": "something", - "detailFour": "something" - } -} ----- - -include::cloudtrail.adoc[leveloffset=+1] diff --git a/latest/userguide/network-isolation.adoc b/latest/userguide/network-isolation.adoc deleted file mode 100644 index a99048af7..000000000 --- a/latest/userguide/network-isolation.adoc +++ /dev/null @@ -1,21 +0,0 @@ -//!!NODE_ROOT
-:https---d0-awsstatic-com-whitepapers-Security-AWS-Security-Whitepaper-pdf: https://d0.awsstatic.com/whitepapers/Security/AWS_Security_Whitepaper.pdf - -[."topic"] -[[infrastructure-security,infrastructure-security.title]] -= Infrastructure security in Amazon EKS -:info_doctype: section -:info_title: Infrastructure security in Amazon EKS -:info_titleabbrev: Infrastructure security -:info_abstract: Learn how Amazon EKS isolates service traffic. - -[abstract] --- -Learn how Amazon EKS isolates service traffic. --- - -As a managed service, Amazon EKS is protected by the AWS global network security procedures that are described in the {https---d0-awsstatic-com-whitepapers-Security-AWS-Security-Whitepaper-pdf}[Amazon Web Services: Overview of Security Processes] whitepaper. - -You use AWS published API calls to access Amazon EKS through the network. Clients must support Transport Layer Security (TLS) 1.0 or later. We recommend TLS 1.2 or later. Clients must also support cipher suites with perfect forward secrecy (PFS) such as Ephemeral Diffie-Hellman (DHE) or Elliptic Curve Ephemeral Diffie-Hellman (ECDHE). Most modern systems such as Java 7 and later support these modes. - -Additionally, requests must be signed using an access key ID and a secret access key that is associated with an IAM principal. Or you can use the https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html[AWS Security Token Service] (AWS STS) to generate temporary security credentials to sign requests. \ No newline at end of file diff --git a/latest/userguide/private-link-template.adoc b/latest/userguide/private-link-template.adoc deleted file mode 100644 index c7c02cb61..000000000 --- a/latest/userguide/private-link-template.adoc +++ /dev/null @@ -1,91 +0,0 @@ -//!!NODE_ROOT -:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-access-service-though-endpoint: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#access-service-though-endpoint -:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-create-interface-endpoint: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint -:https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-vpce-interface-limitations: https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#vpce-interface-limitations -[."topic"] -[[vpc-interface-endpoints,vpc-interface-endpoints.title]] -= Amazon EKS and interface VPC endpoints (AWS PrivateLink) -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Amazon EKS and interface VPC endpoints \ - (AWS PrivateLink) -:info_titleabbrev: VPC endpoints (AWS PrivateLink) -:info_abstract: You can use an interface VPC endpoint to create \ - a private connection between your VPC and Amazon EKS without requiring access over the \ - internet or through a NAT device, a VPN connection, or an AWS Direct Connect connection. - -[abstract] --- -You can use an interface VPC endpoint to create a private connection between your VPC and Amazon EKS without requiring access over the internet or through a NAT device, a VPN connection, or an AWS Direct Connect connection. --- - -You can establish a private connection between your VPC and Amazon EKS by creating an __interface VPC endpoint__. Interface endpoints are powered by http://aws.amazon.com/privatelink[AWS PrivateLink], a technology that enables you to privately access Amazon EKS APIs without an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC don't need public IP addresses to communicate with Amazon EKS APIs. Traffic between your VPC and Amazon EKS does not leave the Amazon network. - -Each interface endpoint is represented by one or more https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html[Elastic Network Interfaces] in your subnets. - -For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html[Interface VPC endpoints (AWS PrivateLink)] in the __Amazon VPC User Guide__. - -[[vpc-endpoint-considerations,vpc-endpoint-considerations.title]] -== Considerations for Amazon EKS VPC endpoints - -Before you set up an interface VPC endpoint for Amazon EKS, ensure that you review {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-vpce-interface-limitations}[Interface endpoint properties and limitations] in the __Amazon VPC User Guide__. - -Amazon EKS supports making calls to all of its API actions from your VPC. - -VPC endpoint policies are not supported for Amazon EKS. By default, full access to Amazon EKS is allowed through the endpoint. For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html[Controlling access to services with VPC endpoints] in the __Amazon VPC User Guide__. - -[[vpc-endpoint-create,vpc-endpoint-create.title]] -== Creating an interface VPC endpoint for Amazon EKS - -You can create a VPC endpoint for the Amazon EKS service using either the Amazon VPC console or the AWS Command Line Interface (AWS CLI). For more information, see {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-create-interface-endpoint}[Creating an interface endpoint] in the __Amazon VPC User Guide__. - -Create a VPC endpoint for Amazon EKS using the following service name: - - - -* com.amazonaws.[replaceable]``region``. - -If you enable private DNS for the endpoint, you can make API requests to Amazon EKS using its default DNS name for the Region, for example, ``.us-east-1.amazonaws.com``. - -For more information, see {https---docs-aws-amazon-com-vpc-latest-userguide-vpce-interface-html-access-service-though-endpoint}[Accessing a service through an interface endpoint] in the __Amazon VPC User Guide__. - -[[vpc-endpoint-policy,vpc-endpoint-policy.title]] -== Creating a VPC endpoint policy for Amazon EKS - -You can attach an endpoint policy to your VPC endpoint that controls access to Amazon EKS. The policy specifies the following information: - - - -* The principal that can perform actions. -* The actions that can be performed. -* The resources on which actions can be performed. - -For more information, see https://docs.aws.amazon.com/vpc/latest/userguide/vpc-endpoints-access.html[Controlling access to services with VPC endpoints] in the __Amazon VPC User Guide__. - -.Example: VPC endpoint policy for Amazon EKS actions -The following is an example of an endpoint policy for Amazon EKS. When attached to an endpoint, this policy grants access to the listed Amazon EKS actions for all principals on all resources. - -[source] ----- -{ - "Statement":[ - { - "Principal":"*", - "Effect":"Allow", - "Action":[ - "servicename:action-1", - "servicename:action-2", - "servicename:action-2" - ], - "Resource":"*" - } - ] -} ----- \ No newline at end of file diff --git a/latest/userguide/quotas.adoc b/latest/userguide/quotas.adoc deleted file mode 100644 index e34814d54..000000000 --- a/latest/userguide/quotas.adoc +++ /dev/null @@ -1,43 +0,0 @@ -//!!NODE_ROOT -:https---console-aws-amazon-com-support-home--case-create-issueType-service-limit-increase: https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase -[[load-balancer-limits,load-balancer-limits.title]] -= Quotas for Amazon EKS -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Quotas for Amazon EKS -:info_titleabbrev: Quotas -:info_abstract: Learn about the quotas for Amazon EKS. - -[abstract] --- -Learn about the quotas for Amazon EKS. --- - -Your AWS account has default quotas, formerly referred to as limits, for each AWS service. Unless otherwise noted, each quota is Region-specific. You can request increases for some quotas, and other quotas cannot be increased. - -To view the quotas for Amazon EKS, open the https://console.aws.amazon.com/servicequotas/home[Service Quotas console]. In the navigation pane, choose *AWS services* and select **Amazon EKS**. - -To request a quota increase, see https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html[Requesting a Quota Increase] in the __Service Quotas User Guide__. If the quota is not yet available in Service Quotas, use the {https---console-aws-amazon-com-support-home--case-create-issueType-service-limit-increase}[limit increase form]. - -Your AWS account has the following quotas related to Amazon EKS. - -[[quotas-table]] -[cols="1,1", options="header"] -|=== -| Resource -| Default - - -|Quota -|Description - -|Quota -|Description -|=== \ No newline at end of file diff --git a/latest/userguide/security-iam.adoc b/latest/userguide/security-iam.adoc deleted file mode 100644 index 6d33d868d..000000000 --- a/latest/userguide/security-iam.adoc +++ /dev/null @@ -1,640 +0,0 @@ -//!!NODE_ROOT
-:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-federated-users-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-third-party-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-aws-accounts-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_aws-accounts.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-getting-started-create-delegated-user-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-delegated-user.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-access-keys-html-Using-CreateAccessKey: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html-Conditions-IPAddress: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_IPAddress -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-change-permissions-html-users-change-permissions-add-console: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console -:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-grant-least-privilege: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-bp-use-aws-defined-policies: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html-access-policies-create-json-editor: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-role -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-linked-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role -:https---docs-aws-amazon-com-STS-latest-APIReference-API-GetFederationToken-html: https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html -:https---docs-aws-amazon-com-STS-latest-APIReference-API-AssumeRole-html: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html -:https---docs-aws-amazon-com-general-latest-gr-acct-identifiers-html-FindingCanonicalId: https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html#FindingCanonicalId -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-principal-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-policy-keys: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-policy-keys -:https---docs-aws-amazon-com-AWSEC2-latest-UserGuide-ExamplePolicies-EC2-html-iam-example-region: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-region -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-condition-keys-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-variables-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-resources-for-iam-policies: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-resources-for-iam-policies -:https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awskeymanagementservice.html#awskeymanagementservice-actions-as-permissions -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-aws-services-that-work-with-iam-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-evaluation-logic-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-policies-session: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -:https---docs-aws-amazon-com-organizations-latest-userguide-orgs-manage-policies-about-scps-html: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_about-scps.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-boundaries-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-managed-vs-inline-html-choosing-managed-or-inline: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#choosing-managed-or-inline -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-access-policies-json: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#access_policies-json -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose-role: https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_which-to-choose_role -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-ec2-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-create-for-service-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_compare-resource-policies.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-introduction-access-management-html-intro-access-roles: https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_access-management.html#intro-access-roles -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-providers-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-console-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose: https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_which-to-choose -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-groups-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-access-keys-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-create-iam-users: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-analyzer-policy-validation: https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-validation.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-configure-api-require-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html - -[."topic"] -[[security-iam,security-iam.title]] -= Identity and access management for Amazon EKS -:info_doctype: section -:info_title: Identity and access management for Amazon EKS -:info_titleabbrev: Identity and access management -:info_abstract: How to authenticate requests and manage access your Amazon EKS \ - resources. - -[abstract] --- -How to authenticate requests and manage access your Amazon EKS resources. --- - -[.shared]`IAMlong` ([.shared]`IAM`) is an [.shared]`AWS-service` that helps an administrator securely control access to [.shared]`AWS` resources. [.shared]`IAM` administrators control who can be _authenticated_ (signed in) and _authorized_ (have permissions) to use Amazon EKS resources. [.shared]`IAM` is an [.shared]`AWS-service` that you can use with no additional charge. - -[.topiclist] -[[Topic List]] - -[[security-iam-audience,security_iam_audience.title]] -== Audience - -How you use [.shared]`IAMlong` ([.shared]`IAM`) differs, depending on the work you do in Amazon EKS. - -*Service user* – If you use the Amazon EKS service to do your job, then your administrator provides you with the credentials and permissions that you need. As you use more Amazon EKS features to do your work, you might need additional permissions. Understanding how access is managed can help you request the right permissions from your administrator. If you cannot access a feature in Amazon EKS, see xref:security-iam-troubleshoot[Troubleshooting Amazon EKS identity and access,linkend=security_iam_troubleshoot]. - -*Service administrator* – If you're in charge of Amazon EKS resources at your company, you probably have full access to Amazon EKS. It's your job to determine which Amazon EKS features and resources your service users should access. You must then submit requests to your [.shared]`IAM` administrator to change the permissions of your service users. Review the information on this page to understand the basic concepts of [.shared]`IAM`. To learn more about how your company can use [.shared]`IAM` with Amazon EKS, see xref:security-iam-service-with-iam[How Amazon EKS works with [.shared]`IAM`,linkend=security_iam_service-with-iam]. - -*[.shared]`IAM` administrator* – If you're an [.shared]`IAM` administrator, you might want to learn details about how you can write policies to manage access to Amazon EKS. To view example Amazon EKS identity-based policies that you can use in [.shared]`IAM`, see xref:security-iam-id-based-policy-examples[Amazon EKS identity-based policy examples,linkend=security_iam_id-based-policy-examples]. - -[[security-iam-authentication,security_iam_authentication.title]] -== Authenticating with identities - -Authentication is how you sign in to [.shared]`AWS` using your identity credentials. You must be _authenticated_ (signed in to [.shared]`AWS`) as the AWS account root user, an [.shared]`IAM-user`, or by assuming an [.shared]`IAM` role. - -You can sign in to [.shared]`AWS` as a federated identity by using credentials provided through an identity source. [.shared]`SSOlong` ([.shared]`SSO`) users, your company's single sign-on authentication, and your Google or Facebook credentials are examples of federated identities. When you sign in as a federated identity, your administrator previously set up identity federation using [.shared]`IAM` roles. When you access [.shared]`AWS` by using federation, you are indirectly assuming a role. - -Depending on the type of user you are, you can sign in to the [.shared]`console` or the [.shared]`AWS` access portal. For more information about signing in to [.shared]`AWS`, see https://docs.aws.amazon.com/signin/latest/userguide/how-to-sign-in.html[How to sign in to your [.shared]`AWS-account`] in the _AWS Sign-In User Guide_. - -If you access [.shared]`AWS` programmatically, [.shared]`AWS` provides a software development kit (SDK) and a command line interface (CLI) to cryptographically sign your requests using your credentials. If you don't use [.shared]`AWS` tools, you must sign requests yourself. For more information about using the recommended method to sign requests yourself, see https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html[Signature Version 4 signing process] in the _AWS General Reference_. - -Regardless of the authentication method that you use, you might also be required to provide additional security information. For example, [.shared]`AWS` recommends that you use multi-factor authentication (MFA) to increase the security of your account. To learn more, see https://docs.aws.amazon.com/singlesignon/latest/userguide/enable-mfa.html[Multi-factor authentication] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_ and {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-html}[Using multi-factor authentication (MFA) in [.shared]`AWS`] in the _IAM User Guide_. - -[[security-iam-authentication-rootuser,security_iam_authentication-rootuser.title]] -=== AWS account root user - -When you first create an [.shared]`AWS-account`, you begin with a single sign-in identity that has complete access to all [.shared]`AWS-services` and resources in the account. This identity is called the AWS account root user and is accessed by signing in with the email address and password that you used to create the account. We strongly recommend that you don't use the root user for your everyday tasks. Safeguard your root user credentials and use them to perform tasks that only the root user can perform. For the complete list of tasks that require you to sign in as the root user, see https://docs.aws.amazon.com/accounts/latest/reference/root-user-tasks.html[Tasks that require root user credentials] in the _Account Management Reference Guide_. - -[[security-iam-authentication-federateduser,security_iam_authentication-federateduser.title]] -=== Federated identity - -As a best practice, require human users, including users that require administrator access, to use federation with an identity provider to access [.shared]`AWS-services` by using temporary credentials. - -A federated identity is a user from your enterprise user directory, a web identity provider, the [.shared]`ADSlong`, the Identity Center directory, or any user that accesses [.shared]`AWS-services` by using credentials provided through an identity source. When federated identities access [.shared]`AWS-accounts`, they assume roles, and the roles provide temporary credentials. - -For centralized access management, we recommend that you use [.shared]`SSOlong`. You can create users and groups in IAM Identity Center, or you can connect and synchronize to a set of users and groups in your own identity source for use across all your [.shared]`AWS-accounts` and applications. For information about IAM Identity Center, see https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[What is IAM Identity Center?] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_. - -[[security-iam-authentication-iamuser,security_iam_authentication-iamuser.title]] -=== [.shared]`IAM-users` and groups - -An _{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-html}[[.shared]`IAM-user`]_ is an identity within your [.shared]`AWS-account` that has specific permissions for a single person or application. Where possible, we recommend relying on temporary credentials instead of creating [.shared]`IAM-users` who have long-term credentials such as passwords and access keys. However, if you have specific use cases that require long-term credentials with [.shared]`IAM-users`, we recommend that you rotate access keys. For more information, see https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials[Rotate access keys regularly for use cases that require long-term credentials] in the __IAM User Guide__. - -An {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-groups-html}[[.shared]`IAM` group] is an identity that specifies a collection of [.shared]`IAM-users`. You can't sign in as a group. You can use groups to specify permissions for multiple users at a time. Groups make permissions easier to manage for large sets of users. For example, you could have a group named _IAMAdmins_ and give that group permissions to administer [.shared]`IAM` resources. - -Users are different from roles. A user is uniquely associated with one person or application, but a role is intended to be assumable by anyone who needs it. Users have permanent long-term credentials, but roles provide temporary credentials. To learn more, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose}[When to create an [.shared]`IAM-user` (instead of a role)] in the __IAM User Guide__. - -[[security-iam-authentication-iamrole,security_iam_authentication-iamrole.title]] -=== [.shared]`IAM` roles - -An _{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html}[[.shared]`IAM` role]_ is an identity within your [.shared]`AWS-account` that has specific permissions. It is similar to an [.shared]`IAM-user`, but is not associated with a specific person. You can temporarily assume an [.shared]`IAM` role in the [.shared]`console` by {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-console-html}[switching roles]. You can assume a role by calling an [.shared]`CLI` or [.shared]`AWS` API operation or by using a custom URL. For more information about methods for using roles, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-html}[Using [.shared]`IAM` roles] in the __IAM User Guide__. - -[.shared]`IAM` roles with temporary credentials are useful in the following situations: - -* *Federated user access* – To assign permissions to a federated identity, you create a role and define permissions for the role. When a federated identity authenticates, the identity is associated with the role and is granted the permissions that are defined by the role. For information about roles for federation, see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp.html[Creating a role for a third-party Identity Provider] in the _IAM User Guide_. If you use IAM Identity Center, you configure a permission set. To control what your identities can access after they authenticate, IAM Identity Center correlates the permission set to a role in [.shared]`IAM`. For information about permissions sets, see https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html[Permission sets] in the _AWS IAM Identity Center (successor to AWS Single Sign-On) User Guide_. - -* *Temporary [.shared]`IAM-user` permissions* – An [.shared]`IAM-user` can assume an [.shared]`IAM` role to temporarily take on different permissions for a specific task. - -* *Cross-account access* – You can use an [.shared]`IAM` role to allow someone (a trusted principal) in a different account to access resources in your account. Roles are the primary way to grant cross-account access. However, with some [.shared]`AWS-services`, you can attach a policy directly to a resource (instead of using a role as a proxy). To learn the difference between roles and resource-based policies for cross-account access, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies] in the __IAM User Guide__. - -* *Cross-service access* – Some [.shared]`AWS-services` use features in other [.shared]`AWS-services`. For example, when you make a call in a service, it's common for that service to run applications in [.shared]`EC2` or store objects in [.shared]`S3`. A service might do this using the calling principal's permissions, using a service role, or using a service-linked role. - - ** *Principal permissions* – When you use an [.shared]`IAM-user` or role to perform actions in [.shared]`AWS`, you are considered a principal. Policies grant permissions to a principal. When you use some services, you might perform an action that then triggers another action in a different service. In this case, you must have permissions to perform both actions. - - ** *Service role* – A service role is an [.shared]`IAM` role that a service assumes to perform actions on your behalf. An [.shared]`IAM` administrator can create, modify, and delete a service role from within [.shared]`IAM`. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-create-for-service-html}[Creating a role to delegate permissions to an [.shared]`AWS-service`] in the _IAM User Guide_. - - ** *Service-linked role* – A service-linked role is a type of service role that is linked to an [.shared]`AWS-service`. The service can assume the role to perform an action on your behalf. Service-linked roles appear in your [.shared]`AWS-account` and are owned by the service. An [.shared]`IAM` administrator can view, but not edit the permissions for service-linked roles. - -* *Applications running on [.shared]`EC2`* – You can use an [.shared]`IAM` role to manage temporary credentials for applications that are running on an [.shared]`EC2` instance and making [.shared]`CLI` or [.shared]`AWS` API requests. This is preferable to storing access keys within the [.shared]`EC2` instance. To assign an [.shared]`AWS` role to an [.shared]`EC2` instance and make it available to all of its applications, you create an instance profile that is attached to the instance. An instance profile contains the role and enables programs that are running on the [.shared]`EC2` instance to get temporary credentials. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-use-switch-role-ec2-html}[Using an [.shared]`IAM` role to grant permissions to applications running on [.shared]`EC2` instances] in the __IAM User Guide__. - -To learn whether to use [.shared]`IAM` roles, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-html-id-which-to-choose-role}[When to create an [.shared]`IAM` role (instead of a user)] in the __IAM User Guide__. - -[[security-iam-access-manage,security_iam_access-manage.title]] -== Managing access using policies - -You control access in [.shared]`AWS` by creating policies and attaching them to [.shared]`AWS` identities or resources. A policy is an object in [.shared]`AWS` that, when associated with an identity or resource, defines their permissions. [.shared]`AWS` evaluates these policies when a principal (user, root user, or role session) makes a request. Permissions in the policies determine whether the request is allowed or denied. Most policies are stored in [.shared]`AWS` as JSON documents. For more information about the structure and contents of JSON policy documents, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-access-policies-json}[Overview of JSON policies] in the __IAM User Guide__. - -Administrators can use [.shared]`AWS` JSON policies to specify who has access to what. That is, which *principal* can perform *actions* on what *resources*, and under what *conditions*. - -Every [.shared]`IAM` entity (user or role) starts with no permissions. By default, users can do nothing, not even change their own password. To give a user permission to do something, an administrator must attach a permissions policy to a user. Or the administrator can add the user to a group that has the intended permissions. When an administrator gives permissions to a group, all users in that group are granted those permissions. - -[.shared]`IAM` policies define permissions for an action regardless of the method that you use to perform the operation. For example, suppose that you have a policy that allows the `iam:GetRole` action. A user with that policy can get role information from the [.shared]`console`, the [.shared]`CLI`, or the [.shared]`AWS` API. - -[[security-iam-access-manage-id-based-policies,security_iam_access-manage-id-based-policies.title]] -=== Identity-based policies - -Identity-based policies are JSON permissions policy documents that you can attach to an identity, such as an [.shared]`IAM-user`, role, or group. These policies control what actions users and roles can perform, on which resources, and under what conditions. To learn how to create an identity-based policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html}[Creating [.shared]`IAM` policies] in the __IAM User Guide__. - -Identity-based policies can be further categorized as _inline policies_ or __managed policies__. Inline policies are embedded directly into a single user, group, or role. Managed policies are standalone policies that you can attach to multiple users, groups, and roles in your [.shared]`AWS-account`. Managed policies include [.shared]`AWS` managed policies and customer managed policies. To learn how to choose between a managed policy or an inline policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-managed-vs-inline-html-choosing-managed-or-inline}[Choosing between managed policies and inline policies] in the __IAM User Guide__. - -[[security-iam-access-manage-resource-based-policies,security_iam_access-manage-resource-based-policies.title]] -=== Resource-based policies - -Resource-based policies are JSON policy documents that you attach to a resource such as an [.shared]`S3` bucket. Service administrators can use these policies to define what actions a specified principal (account member, user, or role) can perform on that resource and under what conditions. Resource-based policies are inline policies. There are no managed resource-based policies. - -[[security-iam-access-manage-acl,security_iam_access-manage-acl.title]] -=== Access control lists (ACLs) - -Access control lists (ACLs) are a type of policy that controls which principals (account members, users, or roles) have permissions to access a resource. ACLs are similar to resource-based policies, although they do not use the JSON policy document format. [.shared]`S3`, [.shared]`WAF`, and [.shared]`VPC` are examples of services that support ACLs. To learn more about ACLs, see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html[Access Control List (ACL) overview] in the __Amazon Simple Storage Service Developer Guide__. - -[[security-iam-access-manage-other-policies,security_iam_access-manage-other-policies.title]] -=== Other policy types - -[.shared]`AWS` supports additional, less-common policy types. These policy types can set the maximum permissions granted to you by the more common policy types. - - - -* *Permissions boundaries* – A permissions boundary is an advanced feature in which you set the maximum permissions that an identity-based policy can grant to an [.shared]`IAM` entity ([.shared]`IAM-user` or role). You can set a permissions boundary for an entity. The resulting permissions are the intersection of entity's identity-based policies and its permissions boundaries. Resource-based policies that specify the user or role in the `Principal` field are not limited by the permissions boundary. An explicit deny in any of these policies overrides the allow. For more information about permissions boundaries, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-boundaries-html}[Permissions boundaries for [.shared]`IAM` entities] in the __IAM User Guide__. -* *Service control policies (SCPs)* – SCPs are JSON policies that specify the maximum permissions for an organization or organizational unit (OU) in [.shared]`AOlong`. [.shared]`AOlong` is a service for grouping and centrally managing multiple [.shared]`AWS-accounts` that your business owns. If you enable all features in an organization, then you can apply service control policies (SCPs) to any or all of your accounts. The SCP limits permissions for entities in member accounts, including each AWS account root user. For more information about Organizations and SCPs, see {https---docs-aws-amazon-com-organizations-latest-userguide-orgs-manage-policies-about-scps-html}[How SCPs work] in the __AWS Organizations User Guide__. -* *Session policies* – Session policies are advanced policies that you pass as a parameter when you programmatically create a temporary session for a role or federated user. The resulting session's permissions are the intersection of the user or role's identity-based policies and the session policies. Permissions can also come from a resource-based policy. An explicit deny in any of these policies overrides the allow. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-html-policies-session}[Session policies] in the __IAM User Guide__. - - -[[security-iam-access-manage-multiple-policies,security_iam_access-manage-multiple-policies.title]] -=== Multiple policy types - -When multiple types of policies apply to a request, the resulting permissions are more complicated to understand. To learn how [.shared]`AWS` determines whether to allow a request when multiple policy types are involved, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-evaluation-logic-html}[Policy evaluation logic] in the __IAM User Guide__. - -[."topic"] -[[security-iam-service-with-iam,security_iam_service-with-iam.title]] -== How Amazon EKS works with [.shared]`IAM` - -Before you use [.shared]`IAM` to manage access to Amazon EKS, learn what [.shared]`IAM` features are available to use with Amazon EKS. To get a high-level view of how Amazon EKS and other [.shared]`AWS-services` work with [.shared]`IAM`, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-aws-services-that-work-with-iam-html}[[.shared]`AWS-services` that work with [.shared]`IAM`] in the __IAM User Guide__. - -[.topiclist] -[[Topic List]] - -[[security-iam-service-with-iam-id-based-policies,security_iam_service-with-iam-id-based-policies.title]] -=== Amazon EKS Identity-based policies - -With [.shared]`IAM` identity-based policies, you can specify allowed or denied actions and resources as well as the conditions under which actions are allowed or denied. You can't specify the principal in an identity-based policy because it applies to the user or role to which it is attached. To learn about all of the elements that you use in a JSON policy, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-html}[[.shared]`IAM` JSON policy elements reference] in the __IAM User Guide__. - -[[security-iam-service-with-iam-id-based-policies-actions,security_iam_service-with-iam-id-based-policies-actions.title]] -==== Actions - -The `Action` element of an [.shared]`IAM` identity-based policy describes the specific action or actions that will be allowed or denied by the policy. Policy actions usually have the same name as the associated [.shared]`AWS` API operation. The action is used in a policy to grant permissions to perform the associated operation. - -Policy actions in Amazon EKS use the following prefix before the action: ``YOUR-SERVICE-PREFIX:``. For example, to grant someone permission to run an [.shared]`EC2` instance with the [.shared]`EC2` `RunInstances` API operation, you include the `ec2:RunInstances` action in their policy. Policy statements must include either an `Action` or `NotAction` element. Amazon EKS defines its own set of actions that describe tasks that you can perform with this service. - -To specify multiple actions in a single statement, separate them with commas as follows: - -[source] ----- -"Action": [ - "ec2:action1", - "ec2:action2" ----- - -You can specify multiple actions using wildcards (*). For example, to specify all actions that begin with the word ``Describe``, include the following action: - -[source] ----- -"Action": "ec2:Describe*" ----- - - -To see a list of Amazon EKS actions, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions Defined by Amazon EKS] in the __IAM User Guide__. - -[[security-iam-service-with-iam-id-based-policies-resources,security_iam_service-with-iam-id-based-policies-resources.title]] -==== Resources - -The `Resource` element specifies the object or objects to which the action applies. Statements must include either a `Resource` or a `NotResource` element. You specify a resource using an ARN or using the wildcard (*) to indicate that the statement applies to all resources. - - -The [.shared]`EC2` instance resource has the following ARN: - -[source] ----- -arn:${Partition}:ec2:${Region}:${Account}:instance/${InstanceId} ----- - -For more information about the format of ARNs, see https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html[Amazon Resource Names (ARNs) and [.shared]`AWS-service` Namespaces]. - -For example, to specify the `i-1234567890abcdef0` instance in your statement, use the following ARN: - -[source] ----- -"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0" ----- - -To specify all instances that belong to a specific account, use the wildcard (*): - -[source] ----- -"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*" ----- - -Some Amazon EKS actions, such as those for creating resources, cannot be performed on a specific resource. In those cases, you must use the wildcard (*). - -[source] ----- -"Resource": "*" ----- - -Many [.shared]`EC2` API actions involve multiple resources. For example, `AttachVolume` attaches an Amazon EBS volume to an instance, so an [.shared]`IAM-user` must have permissions to use the volume and the instance. To specify multiple resources in a single statement, separate the ARNs with commas. - -[source] ----- -"Resource": [ - "resource1", - "resource2" ----- - -To see a list of Amazon EKS resource types and their ARNs, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-resources-for-iam-policies}[Resources Defined by Amazon EKS] in the __IAM User Guide__. To learn with which actions you can specify the ARN of each resource, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions Defined by Amazon EKS]. - -[[security-iam-service-with-iam-id-based-policies-conditionkeys,security_iam_service-with-iam-id-based-policies-conditionkeys.title]] -==== Condition keys - -The `Condition` element (or `Condition`__block__) lets you specify conditions in which a statement is in effect. The `Condition` element is optional. You can create conditional expressions that use {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html}[condition operators], such as equals or less than, to match the condition in the policy with values in the request. - -If you specify multiple `Condition` elements in a statement, or multiple keys in a single `Condition` element, [.shared]`AWS` evaluates them using a logical `AND` operation. If you specify multiple values for a single condition key, [.shared]`AWS` evaluates the condition using a logical `OR` operation. All of the conditions must be met before the statement's permissions are granted. - -You can also use placeholder variables when you specify conditions. For example, you can grant an [.shared]`IAM-user` permission to access a resource only if it is tagged with their [.shared]`IAM-user` name. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-variables-html}[[.shared]`IAM` policy elements: variables and tags] in the __IAM User Guide__. - -Amazon EKS defines its own set of condition keys and also supports using some global condition keys. To see all [.shared]`AWS` global condition keys, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-condition-keys-html}[[.shared]`AWS` global condition context keys] in the __IAM User Guide__. - - -All [.shared]`EC2` actions support the `aws:RequestedRegion` and `ec2:Region` condition keys. For more information, see {https---docs-aws-amazon-com-AWSEC2-latest-UserGuide-ExamplePolicies-EC2-html-iam-example-region}[Example: Restricting access to a specific region]. - -To see a list of Amazon EKS condition keys, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-policy-keys}[Condition Keys for Amazon EKS] in the __IAM User Guide__. To learn with which actions and resources you can use a condition key, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-list-awskeymanagementservice-html-awskeymanagementservice-actions-as-permissions}[Actions defined by Amazon EKS]. - -[[security-iam-service-with-iam-id-based-policies-examples,security_iam_service-with-iam-id-based-policies-examples.title]] -==== Examples - - -To view examples of Amazon EKS identity-based policies, see xref:security-iam-id-based-policy-examples[Amazon EKS identity-based policy examples,linkend=security_iam_id-based-policy-examples]. - -[[security-iam-service-with-iam-resource-based-policies,security_iam_service-with-iam-resource-based-policies.title]] -=== Amazon EKS resource-based policies - -Resource-based policies are JSON policy documents that specify what actions a specified principal can perform on the Amazon EKS resource and under what conditions. [.shared]`S3` supports resource-based permissions policies for [.shared]`S3` [replaceable]``buckets``. Resource-based policies let you grant usage permission to other accounts on a per-resource basis. You can also use a resource-based policy to allow an [.shared]`AWS-service` to access your [.shared]`S3` [replaceable]``buckets``. - -To enable cross-account access, you can specify an entire account or [.shared]`IAM` entities in another account as the {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-principal-html}[principal in a resource-based policy]. Adding a cross-account principal to a resource-based policy is only half of establishing the trust relationship. When the principal and the resource are in different [.shared]`AWS-accounts`, you must also grant the principal entity permission to access the resource. Grant permission by attaching an identity-based policy to the entity. However, if a resource-based policy grants access to a principal in the same account, no additional identity-based policy is required. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies]in the __IAM User Guide__. - -The [.shared]`S3` service supports only one type of resource-based policy called a __[replaceable]``__bucket__`` policy__, which is attached to a [replaceable]``bucket``. This policy defines which principal entities (accounts, users, roles, and federated users) can perform actions on the [replaceable]``widget``. - -To learn how to attach a resource-based policy to a [replaceable]``bucket``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -[[security-iam-service-with-iam-resource-based-policies-examples,security_iam_service-with-iam-resource-based-policies-examples.title]] -==== Examples - - -To view examples of Amazon EKS resource-based policies, see xref:security-iam-resource-based-policy-examples[Amazon EKS resource-based policy examples,linkend=security_iam_resource-based-policy-examples], - -[[security-iam-service-with-iam-acls,security_iam_service-with-iam-acls.title]] -=== Access control lists (ACLs) - -Access control lists (ACLs) are lists of grantees that you can attach to resources. They grant accounts permissions to access the resource to which they are attached. You can attach ACLs to an [.shared]`S3` [replaceable]``bucket`` resource. For more information about attaching ACLs to [replaceable]``buckets``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -With [.shared]`S3` access control lists (ACLs), you can manage access to [replaceable]``bucket`` resources. Each [replaceable]``bucket`` has an ACL attached to it as a subresource. It defines which [.shared]`AWS-accounts`, [.shared]`IAM-users` or groups of users, or [.shared]`IAM` roles are granted access and the type of access. When a request is received for a resource, [.shared]`AWS` checks the corresponding ACL to verify that the requester has the necessary access permissions. - -When you create a [replaceable]``bucket`` resource, [.shared]`S3` creates a default ACL that grants the resource owner full control over the resource. In the following example [replaceable]``bucket`` ACL, John Doe is listed as the owner of the [replaceable]``bucket`` and is granted full control over that [replaceable]``bucket``. An ACL can have up to 100 grantees. - -[source] ----- - - - - c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6 - john-doe - - - - - c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6 - john-doe - - FULL_CONTROL - - - ----- - -The ID field in the ACL is the [.shared]`AWS-account` canonical user ID. To learn how to view this ID in an account that you own, see {https---docs-aws-amazon-com-general-latest-gr-acct-identifiers-html-FindingCanonicalId}[Finding an [.shared]`AWS-account` canonical user ID]. - -[[security-iam-service-with-iam-tags,security_iam_service-with-iam-tags.title]] -=== Authorization based on Amazon EKS tags - -You can attach tags to Amazon EKS resources or pass tags in a request to Amazon EKS. To control access based on tags, you provide tag information in the {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[condition element] of a policy using the ``YOUR-SERVICE-PREFIX:ResourceTag/[replaceable]``key-name````, ``aws:RequestTag/[replaceable]``key-name````, or `aws:TagKeys` condition keys. For more information about tagging Amazon EKS resources, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -To view an example identity-based policy for limiting access to a resource based on the tags on that resource, see xref:security-iam-id-based-policy-examples-view-widget-tags[Viewing Amazon EKS widgets based on tags,linkend=security_iam_id-based-policy-examples-view-widget-tags]. - -[[security-iam-service-with-iam-roles,security_iam_service-with-iam-roles.title]] -=== Amazon EKS [.shared]`IAM` roles - -An {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-html}[[.shared]`IAM` role] is an entity within your [.shared]`AWS-account` that has specific permissions. - -[[security-iam-service-with-iam-roles-tempcreds,security_iam_service-with-iam-roles-tempcreds.title]] -==== Using temporary credentials with Amazon EKS - -You can use temporary credentials to sign in with federation, assume an [.shared]`IAM` role, or to assume a cross-account role. You obtain temporary security credentials by calling [.shared]`STS` API operations such as {https---docs-aws-amazon-com-STS-latest-APIReference-API-AssumeRole-html}[AssumeRole] or {https---docs-aws-amazon-com-STS-latest-APIReference-API-GetFederationToken-html}[GetFederationToken]. - -Amazon EKS supports using temporary credentials. - -[[security-iam-service-with-iam-roles-service-linked,security_iam_service-with-iam-roles-service-linked.title]] -==== Service-linked roles - -{https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-linked-role}[Service-linked roles] allow [.shared]`AWS-services` to access resources in other services to complete an action on your behalf. Service-linked roles appear in your [.shared]`IAM` account and are owned by the service. An [.shared]`IAM` administrator can view but not edit the permissions for service-linked roles. - -Amazon EKS supports service-linked roles. For details about creating or managing Amazon EKS service-linked roles, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -[[security-iam-service-with-iam-roles-service,security_iam_service-with-iam-roles-service.title]] -==== Service roles - -This feature allows a service to assume a {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-terms-and-concepts-html-iam-term-service-role}[service role] on your behalf. This role allows the service to access resources in other services to complete an action on your behalf. Service roles appear in your [.shared]`IAM` account and are owned by the account. This means that an [.shared]`IAM` administrator can change the permissions for this role. However, doing so might break the functionality of the service. - -Amazon EKS supports service roles. - -[[security-iam-service-with-iam-roles-choose,security_iam_service-with-iam-roles-choose.title]] -==== Choosing an [.shared]`IAM` role in Amazon EKS - -When you create a [replaceable]``widget`` resource in Amazon EKS, you must choose a role to allow Amazon EKS to access [.shared]`EC2` on your behalf. If you have previously created a service role or service-linked role, then Amazon EKS provides you with a list of roles to choose from. It's important to choose a role that allows access to start and stop [.shared]`EC2` instances. For more information, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -[."topic"] -[[security-iam-id-based-policy-examples,security_iam_id-based-policy-examples.title]] -== Amazon EKS identity-based policy examples - -By default, [.shared]`IAM-users` and roles don't have permission to create or modify Amazon EKS resources. They also can't perform tasks using the [.shared]`console`, [.shared]`CLI`, or [.shared]`AWS` API. An [.shared]`IAM` administrator must create [.shared]`IAM` policies that grant users and roles permission to perform specific API operations on the specified resources they need. The administrator must then attach those policies to the [.shared]`IAM-users` or groups that require those permissions. - -To learn how to create an [.shared]`IAM` identity-based policy using these example JSON policy documents, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-create-html-access-policies-create-json-editor}[Creating policies on the JSON tab] in the __IAM User Guide__. - -[.topiclist] -[[Topic List]] - -[[security-iam-service-with-iam-policy-best-practices,security_iam_service-with-iam-policy-best-practices.title]] -=== Policy best practices - -Identity-based policies determine whether someone can create, access, or delete Amazon EKS resources in your account. These actions can incur costs for your [.shared]`AWS-account`. When you create or edit identity-based policies, follow these guidelines and recommendations: - - - -* *Get started with [.shared]`AWS` managed policies and move toward least-privilege permissions* – To get started granting permissions to your users and workloads, use the [.shared]`AWS` managed policies that grant permissions for many common use cases. They are available in your [.shared]`AWS-account`. We recommend that you reduce permissions further by defining [.shared]`AWS` customer managed policies that are specific to your use cases. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-bp-use-aws-defined-policies}[[.shared]`AWS` managed policies] or https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html[[.shared]`AWS` managed policies for job functions] in the __IAM User Guide__. - -* *Apply least-privilege permissions* – When you set permissions with [.shared]`IAM` policies, grant only the permissions required to perform a task. You do this by defining the actions that can be taken on specific resources under specific conditions, also known as _least-privilege permissions_. For more information about using [.shared]`IAM` to apply permissions, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-best-practices-html-grant-least-privilege}[Policies and permissions in [.shared]`IAM`] in the __IAM User Guide__. - -* *Use conditions in [.shared]`IAM` policies to further restrict access* – You can add a condition to your policies to limit access to actions and resources. For example, you can write a policy condition to specify that all requests must be sent using SSL. You can also use conditions to grant access to service actions if they are used through a specific [.shared]`AWS-service`, such as [.shared]`CFN`. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[[.shared]`IAM` JSON policy elements: condition] in the __IAM User Guide__. - -* *Use [.shared]`iam-citadel` to validate your [.shared]`IAM` policies to ensure secure and functional permissions* – [.shared]`iam-citadel` validates new and existing policies so that the policies adhere to the [.shared]`IAM` policy language (JSON) and [.shared]`IAM` best practices. [.shared]`iam-citadel` provides more than 100 policy checks and actionable recommendations to help you author secure and functional policies. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-analyzer-policy-validation}[[.shared]`iam-citadel` policy validation] in the __IAM User Guide__. - -* *Require multi-factor authentication (MFA)* – If you have a scenario that requires [.shared]`IAM-users` or root users in your account, turn on MFA for additional security. To require MFA when API operations are called, add MFA conditions to your policies. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-credentials-mfa-configure-api-require-html}[Configuring MFA-protected API access] in the __IAM User Guide__. - - - -[[security-iam-id-based-policy-examples-console,security_iam_id-based-policy-examples-console.title]] -=== Using the Amazon EKS console - -To access the Amazon EKS console, you must have a minimum set of permissions. These permissions must allow you to list and view details about the Amazon EKS resources in your [.shared]`AWS-account`. If you create an identity-based policy that is more restrictive than the minimum required permissions, the console won't function as intended for entities (users or roles) with that policy. - -To ensure that those entities can still use the Amazon EKS console, also attach the following [.shared]`AWS` managed policy to the entities. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-users-change-permissions-html-users-change-permissions-add-console}[Adding permissions to a user] in the __IAM User Guide__: - -[source] ----- -AWSAwesomeConsoleAccess ----- - -You don't need to allow minimum console permissions for users that are making calls only to the [.shared]`CLI` or the [.shared]`AWS` API. Instead, allow access to only the actions that match the API operation that you're trying to perform. - -[[security-iam-id-based-policy-examples-view-own-permissions,security_iam_id-based-policy-examples-view-own-permissions.title]] -=== Allow users to view their own permissions - -This example shows how you might create a policy that allows [.shared]`IAM-users` to view the inline and managed policies that are attached to their user identity. This policy includes permissions to complete this action on the console or programmatically using the [.shared]`CLI` or [.shared]`AWS` API. - -[source] ----- -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ViewOwnUserInfo", - "Effect": "Allow", - "Action": [ - "iam:GetUserPolicy", - "iam:ListGroupsForUser", - "iam:ListAttachedUserPolicies", - "iam:ListUserPolicies", - "iam:GetUser" - ], - "Resource": ["arn:aws:iam::*:user/${aws:username}"] - }, - { - "Sid": "NavigateInConsole", - "Effect": "Allow", - "Action": [ - "iam:GetGroupPolicy", - "iam:GetPolicyVersion", - "iam:GetPolicy", - "iam:ListAttachedGroupPolicies", - "iam:ListGroupPolicies", - "iam:ListPolicyVersions", - "iam:ListPolicies", - "iam:ListUsers" - ], - "Resource": "*" - } - ] -} ----- - - -[[security-iam-id-based-policy-examples-access-one-bucket,security_iam_id-based-policy-examples-access-one-bucket.title]] -=== Accessing one [.shared]`S3` bucket - -In this example, you want to grant an [.shared]`IAM-user` in your [.shared]`AWS-account` access to one of your [.shared]`S3` buckets, ``examplebucket``. You also want to allow the user to add, update, and delete objects. - -In addition to granting the ``s3:PutObject``, ``s3:GetObject``, and `s3:DeleteObject` permissions to the user, the policy also grants the ``s3:ListAllMyBuckets``, ``s3:GetBucketLocation``, and `s3:ListBucket` permissions. These are the additional permissions required by the console. Also, the `s3:PutObjectAcl` and the `s3:GetObjectAcl` actions are required to be able to copy, cut, and paste objects in the console. For an example walkthrough that grants permissions to users and tests them using the console, see https://docs.aws.amazon.com/AmazonS3/latest/dev/walkthrough1.html[An Example Walkthrough: Using user policies to control access to your bucket]. - -[source] ----- -{ - "Version":"2012-10-17", - "Statement":[ - { - "Sid":"ListBucketsInConsole", - "Effect":"Allow", - "Action":[ - "s3:ListAllMyBuckets" - ], - "Resource":"arn:aws:s3:::*" - }, - { - "Sid":"ViewSpecificBucketInfo", - "Effect":"Allow", - "Action":[ - "s3:ListBucket", - "s3:GetBucketLocation" - ], - "Resource":"arn:aws:s3:::examplebucket" - }, - { - "Sid":"ManageBucketContents", - "Effect":"Allow", - "Action":[ - "s3:PutObject", - "s3:PutObjectAcl", - "s3:GetObject", - "s3:GetObjectAcl", - "s3:DeleteObject" - ], - "Resource":"arn:aws:s3:::examplebucket/*" - } - ] -} ----- - - -[[security-iam-id-based-policy-examples-view-widget-tags,security_iam_id-based-policy-examples-view-widget-tags.title]] -=== Viewing Amazon EKS [replaceable]``widgets`` based on tags - -You can use conditions in your identity-based policy to control access to Amazon EKS resources based on tags. This example shows how you might create a policy that allows viewing a [replaceable]``widget``. However, permission is granted only if the [replaceable]``widget`` tag `Owner` has the value of that user's user name. This policy also grants the permissions necessary to complete this action on the console. - -[source] ----- -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ListWidgetsInConsole", - "Effect": "Allow", - "Action": "YOUR-SERVICE-PREFIX:ListWidgets", - "Resource": "*" - }, - { - "Sid": "ViewWidgetIfOwner", - "Effect": "Allow", - "Action": "YOUR-SERVICE-PREFIX:GetWidget", - "Resource": "arn:aws:YOUR-SERVICE-PREFIX:*:*:widget/*", - "Condition": { - "StringEquals": {"YOUR-SERVICE-PREFIX:ResourceTag/Owner": "${aws:username}"} - } - } - ] -} ----- - -You can attach this policy to the [.shared]`IAM-users` in your account. If a user named `richard-roe` attempts to view an Amazon EKS [replaceable]``widget``, the [replaceable]``widget`` must be tagged `Owner=richard-roe` or ``owner=richard-roe``. Otherwise he is denied access. The condition tag key `Owner` matches both `Owner` and `owner` because condition key names are not case-sensitive. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-html}[[.shared]`IAM` JSON policy elements: condition] in the __IAM User Guide__. - -[."topic"] -[[security-iam-resource-based-policy-examples,security_iam_resource-based-policy-examples.title]] -== Amazon EKS resource-based policy examples - -To learn how to create a [replaceable]``widget``, see [replaceable]``**ADD XREF TO YOUR DOCS HERE**``. - -[.topiclist] -[[Topic List]] - -[[security-iam-resource-based-policy-examples-restrict-bucket-by-ip,security_iam_id-based-policy-examples-restrict-bucket-by-ip.title]] -=== Restricting [.shared]`S3` bucket access to specific IP addresses - -The following example grants permissions to any user to perform any [.shared]`S3` operations on objects in the specified bucket. However, the request must originate from the range of IP addresses specified in the condition. - -The condition in this statement identifies the 54.240.143.* range of allowed Internet Protocol version 4 (IPv4) IP addresses, with one exception: 54.240.143.188. - -The `Condition` block uses the `IpAddress` and `NotIpAddress` conditions and the `aws:SourceIp` condition key, which is an [.shared]`AWS` wide condition key. For more information about these condition keys, see https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html[Specifying Conditions in a Policy]. The``aws:sourceIp`` IPv4 values use the standard CIDR notation. For more information, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-reference-policies-elements-condition-operators-html-Conditions-IPAddress}[IP address condition operators] in the __IAM User Guide__. - -[source] ----- -{ - "Version": "2012-10-17", - "Id": "S3PolicyId1", - "Statement": [ - { - "Sid": "IPAllow", - "Effect": "Allow", - "Principal": "*", - "Action": "s3:*", - "Resource": "arn:aws:s3:::examplebucket/*", - "Condition": { - "IpAddress": {"aws:SourceIp": "54.240.143.0/24"}, - "NotIpAddress": {"aws:SourceIp": "54.240.143.188/32"} - } - } - ] -} ----- - - -[."topic"] -[[security-iam-troubleshoot,security_iam_troubleshoot.title]] -== Troubleshooting Amazon EKS identity and access - -Use the following information to help you diagnose and fix common issues that you might encounter when working with Amazon EKS and [.shared]`IAM`. - -[.topiclist] -[[Topic List]] - -[[security-iam-troubleshoot-no-permissions,security_iam_troubleshoot-no-permissions.title]] -=== I am not authorized to perform an action in Amazon EKS - -If the [.shared]`console` tells you that you're not authorized to perform an action, then you must contact your administrator for assistance. Your administrator is the person that provided you with your user name and password. - -The following example error occurs when the `mateojackson` [.shared]`IAM-user` tries to use the console to view details about a [replaceable]``widget`` but does not have `YOUR-SERVICE-PREFIX:[replaceable]``GetWidget``` permissions. - -[source] ----- -User: arn:aws:iam::123456789012:user/mateojackson is not authorized to perform: YOUR-SERVICE-PREFIX:GetWidget on resource: my-example-widget ----- - -In this case, Mateo asks his administrator to update his policies to allow him to access the `[replaceable]``my-example-widget``` resource using the `YOUR-SERVICE-PREFIX:[replaceable]``GetWidget``` action. - -[[security-iam-troubleshoot-passrole,security_iam_troubleshoot-passrole.title]] -=== I am not authorized to perform iam:PassRole - -If you receive an error that you're not authorized to perform the `iam:PassRole` action, then you must contact your administrator for assistance. Your administrator is the person that provided you with your user name and password. Ask that person to update your policies to allow you to pass a role to Amazon EKS. - -Some [.shared]`AWS-services` allow you to pass an existing role to that service, instead of creating a new service role or service-linked role. To do this, you must have permissions to pass the role to the service. - -The following example error occurs when an [.shared]`IAM-user` named `marymajor` tries to use the console to perform an action in Amazon EKS. However, the action requires the service to have permissions granted by a service role. Mary does not have permissions to pass the role to the service. - -[source] ----- -User: arn:aws:iam::123456789012:user/marymajor is not authorized to perform: iam:PassRole ----- - -In this case, Mary asks her administrator to update her policies to allow her to perform the `iam:PassRole` action. - -[[security-iam-troubleshoot-cross-account-access,security_iam_troubleshoot-cross-account-access.title]] -=== I want to allow people outside of my [.shared]`AWS-account` to access my Amazon EKS resources - -You can create a role that users in other accounts or people outside of your organization can use to access your resources. You can specify who is trusted to assume the role. For services that support resource-based policies or access control lists (ACLs), you can use those policies to grant people access to your resources. - -To learn more, consult the following: - - - -* To learn whether Amazon EKS supports these features, see xref:security-iam-service-with-iam[How Amazon EKS works with [.shared]`IAM`,linkend=security_iam_service-with-iam]. -* To learn how to provide access to your resources across [.shared]`AWS-accounts` that you own, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-aws-accounts-html}[Providing access to an [.shared]`IAM-user` in another [.shared]`AWS-account` that you own] in the __IAM User Guide__. -* To learn how to provide access to your resources to third-party [.shared]`AWS-accounts`, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-third-party-html}[Providing access to [.shared]`AWS-accounts` owned by third parties] in the __IAM User Guide__. -* To learn how to provide access through identity federation, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-common-scenarios-federated-users-html}[Providing Access to Externally Authenticated Users (Identity Federation)] in the __IAM User Guide__. -* To learn the difference between using roles and resource-based policies for cross-account access, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-roles-compare-resource-policies-html}[How [.shared]`IAM` roles differ from resource-based policies] in the __IAM User Guide__. diff --git a/latest/userguide/security.adoc b/latest/userguide/security.adoc deleted file mode 100644 index 6f5a20379..000000000 --- a/latest/userguide/security.adoc +++ /dev/null @@ -1,50 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[security,security.title]] -= Security in Amazon EKS -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Security in Amazon EKS -:info_titleabbrev: Security -:info_abstract: Configure Amazon EKS to meet your security and compliance objectives, and learn how to \ - use other AWS services that help you to secure your Amazon EKS resources. - -[abstract] --- -Configure Amazon EKS to meet your security and compliance objectives, and learn how to use other AWS services that help you to secure your Amazon EKS resources. --- - -Cloud security at AWS is the highest priority. As an AWS customer, you benefit from a data center and network architecture that is built to meet the requirements of the most security-sensitive organizations. - -Security is a shared responsibility between AWS and you. The http://aws.amazon.com/compliance/shared-responsibility-model/[shared responsibility model] describes this as security of the cloud and security in the cloud: - - - -* *Security of the cloud* – AWS is responsible for protecting the infrastructure that runs AWS services in the AWS Cloud. AWS also provides you with services that you can use securely. Third-party auditors regularly test and verify the effectiveness of our security as part of the http://aws.amazon.com/compliance/programs/[AWS Compliance Programs]. To learn about the compliance programs that apply to Amazon EKS, see http://aws.amazon.com/compliance/services-in-scope/[AWS Services in Scope by Compliance Program]. -* *Security in the cloud* – Your responsibility is determined by the AWS service that you use. You are also responsible for other factors including the sensitivity of your data, your company`'s requirements, and applicable laws and regulations - -This documentation helps you understand how to apply the shared responsibility model when using Amazon EKS. It shows you how to configure Amazon EKS to meet your security and compliance objectives. You also learn how to use other AWS services that help you to monitor and secure your Amazon EKS resources. - -[.topiclist-abbrev] -Contents - -include::data-protection.adoc[leveloffset=+1] - - -include::security-iam.adoc[leveloffset=+1] Commenting out until can fix syntax issue - - -include::compliance-validation.adoc[leveloffset=+1] - - -include::disaster-recovery-resiliency.adoc[leveloffset=+1] - - -include::network-isolation.adoc[leveloffset=+1] diff --git a/latest/userguide/setting-up.adoc b/latest/userguide/setting-up.adoc deleted file mode 100644 index 73f286aab..000000000 --- a/latest/userguide/setting-up.adoc +++ /dev/null @@ -1,65 +0,0 @@ -//!!NODE_ROOT -:https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-examples-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-id-tags-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags.html -:https---docs-aws-amazon-com-IAM-latest-UserGuide-tutorial-billing-html: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_billing.html -:https---docs-aws-amazon-com-general-latest-gr-aws-tasks-that-require-root-html: https://docs.aws.amazon.com/general/latest/gr/aws_tasks-that-require-root.html -[."topic"] -[[setting-up,setting-up.title]] -= Setting up Amazon EKS -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: Setting up Amazon EKS -:info_abstract: Insert chapter abstract text here. - -[abstract] --- -Insert chapter abstract text here. --- - -Insert your introductory paragraph here. - -[.topiclist] -[[Topic List]] - -[[setting-up-aws-sign-up,setting-up-aws-sign-up.title]] -== Sign up for AWS - -If you do not have an AWS account, complete the following steps to create one. - -. Open https://portal.aws.amazon.com/billing/signup. -. Follow the online instructions. -+ - -Part of the sign-up procedure involves receiving a phone call and entering a verification code on the phone keypad. - - -[[setting-up-create-iam-user,setting-up-create-iam-user.title]] -== Create an IAM user -. Sign in to the https://console.aws.amazon.com/iam/[IAM console] as the account owner by choosing *Root user* and entering your AWS account email address. On the next page, enter your password. -+ -NOTE: We strongly recommend that you adhere to the best practice of using the `Administrator` IAM user below and securely lock away the root user credentials. Sign in as the root user only to perform a few {https---docs-aws-amazon-com-general-latest-gr-aws-tasks-that-require-root-html}[account and service management tasks]. -. In the navigation pane, choose *Users* and then choose **Add user**. -. For **User name**, enter ``Administrator``. -. Select the check box next to **AWS Management Console access**. Then select **Custom password**, and then enter your new password in the text box. -. (Optional) By default, AWS requires the new user to create a new password when first signing in. You can clear the check box next to *User must create a new password at next sign-in* to allow the new user to reset their password after they sign in. -. Choose **Next: Permissions**. -. Under **Set permissions**, choose **Add user to group**. -. Choose **Create group**. -. In the *Create group* dialog box, for *Group name* enter ``Administrators``. -. Choose **Filter policies**, and then select *AWS managed -job function* to filter the table contents. -. In the policy list, select the check box for **AdministratorAccess**. Then choose **Create group**. -+ -NOTE: You must activate IAM user and role access to Billing before you can use the `AdministratorAccess` permissions to access the AWS Billing and Cost Management console. To do this, follow the instructions in {https---docs-aws-amazon-com-IAM-latest-UserGuide-tutorial-billing-html}[step 1 of the tutorial about delegating access to the billing console]. -. Back in the list of groups, select the check box for your new group. Choose *Refresh* if necessary to see the group in the list. -. Choose **Next: Tags**. -. (Optional) Add metadata to the user by attaching tags as key-value pairs. For more information about using tags in IAM, see {https---docs-aws-amazon-com-IAM-latest-UserGuide-id-tags-html}[Tagging IAM Entities] in the __IAM User Guide__. -. Choose *Next: Review* to see the list of group memberships to be added to the new user. When you are ready to proceed, choose **Create user**. - -You can use this same process to create more groups and users and to give your users access to your AWS account resources. To learn about using policies that restrict user permissions to specific AWS resources, see https://docs.aws.amazon.com/IAM/latest/UserGuide/access.html[Access Management] and {https---docs-aws-amazon-com-IAM-latest-UserGuide-access-policies-examples-html}[Example Policies]. \ No newline at end of file From 1658e4457f86c9b37a1fcd193e588640b106df99 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 3 May 2024 16:59:06 +0000 Subject: [PATCH 03/56] path config and gitignore --- .gitignore | 1 + Config | 1 + build-info.xml | 10 +++---- latest/userguide/book.adoc | 7 ++--- latest/userguide/index.adoc | 22 +++++++++++++++ latest/userguide/what-is.adoc | 52 ----------------------------------- 6 files changed, 32 insertions(+), 61 deletions(-) create mode 100644 latest/userguide/index.adoc delete mode 100644 latest/userguide/what-is.adoc diff --git a/.gitignore b/.gitignore index b0c911017..834029c1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +/.vscode *.running.properties.txt *\~ *.mobi diff --git a/Config b/Config index 040e5c15a..c77cff972 100755 --- a/Config +++ b/Config @@ -7,6 +7,7 @@ package.AmazonEKSBestPracticesDocs = { HappyTrails = 3.2; JavaBuildAndTestMin = jdk8; ZonBook = 4.0; + AWSEC2ContainerChecklist = 1.0; }; }; }; diff --git a/build-info.xml b/build-info.xml index 5a6e536ca..1c9c5beec 100755 --- a/build-info.xml +++ b/build-info.xml @@ -1,8 +1,8 @@ - - EKS + + eks Amazon EKS 0 Amazon EKS @@ -14,10 +14,10 @@ - userguide + best-practices eks-bpg Best Practices Guide - EKS + eks-bpg latest latest latest/userguide @@ -29,7 +29,7 @@ - Best Practices Guide Updates + EKS Best Practices Guide Updates eks-bpg diff --git a/latest/userguide/book.adoc b/latest/userguide/book.adoc index c0ea29c26..1ca5cfb6d 100644 --- a/latest/userguide/book.adoc +++ b/latest/userguide/book.adoc @@ -10,11 +10,10 @@ :info_doctype: book :info_title: Amazon EKS :info_subtitle: Best Practices Guide -:info_abstract: Insert abstract text +:info_abstract: Learn best practices for operating EKS clusters. :info_corpauthor: AWS :info_publisher: AWS -:info_copyright: 2020 \ - Amazon Web Services, Inc. and/or its affiliates. All rights reserved. +:info_copyright: 2024. Review license at https://github.com/aws/aws-eks-best-practices/blob/master/LICENSE :info_legalnotice: Amazon's trademarks and trade dress may not be used in \ connection with any product or service that is not Amazon's, \ in any manner that is likely to cause confusion among customers, \ @@ -29,5 +28,5 @@ Insert abstract text -- :sectnums: -include::what-is.adoc[leveloffset=+1] +include::index.adoc[leveloffset=+1] diff --git a/latest/userguide/index.adoc b/latest/userguide/index.adoc new file mode 100644 index 000000000..b92e5e574 --- /dev/null +++ b/latest/userguide/index.adoc @@ -0,0 +1,22 @@ +//!!NODE_ROOT +[."topic"] +[[introduction,introduction.title]] += Introduction +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Introduction +:info_abstract: Learn best practices for operating EKS clusters. + +[abstract] +-- +Learn best practices for operating EKS clusters. +-- + +Welcome to the EKS Best Practices Guides. The primary goal of this project is to offer a set of best practices for day 2 operations for Amazon EKS. We elected to publish this guidance to GitHub so we could iterate quickly, provide timely and effective recommendations for variety of concerns, and easily incorporate suggestions from the broader community. diff --git a/latest/userguide/what-is.adoc b/latest/userguide/what-is.adoc deleted file mode 100644 index 192788ede..000000000 --- a/latest/userguide/what-is.adoc +++ /dev/null @@ -1,52 +0,0 @@ -//!!NODE_ROOT -[."topic"] -[[what-is-service,what-is-service.title]] -= What is Amazon EKS? -:doctype: book -:sectnums: -:toc: left -:icons: font -:experimental: -:idprefix: -:idseparator: - -:sourcedir: . -:info_doctype: chapter -:info_title: What is Amazon EKS? -:info_abstract: Learn about Amazon EKS, a service that... - -[abstract] --- -Learn about Amazon EKS, a service that... --- - -Amazon EKS is... Describe what your service is and how customers can use it. - -[.topiclist] -[[Topic List]] - -[[first-time-user,first-time-user.title]] -== Are you a first-time Amazon EKS user? - -If you are a first-time user of Amazon EKS, we recommend that you begin by reading the following sections: - - - -* Text -* Text -* Text - - -[[servicename-feature-overview,servicename-feature-overview.title]] -== Features of Amazon EKS - -Include a brief but descriptive list of service features. If you need to go into more depth on a feature, consider adding a How It Works conceptual topic. - -[[related-services,related-services.title]] -== Related services - -Offer a list of related services complete with links to the best place to start for each service. Briefly explain how the service is related. If you don't have any, remove this section. - -[[acessing-servicename,acessing-servicename.title]] -== Accessing Amazon EKS - -Briefly explain the different ways to gain access to the service, whether by console, CLI, or API. \ No newline at end of file From 3b565136030dc1479cf6e7b5bebb361a23133d4f Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 3 May 2024 17:42:22 +0000 Subject: [PATCH 04/56] init draft of upgrades --- build-info.xml | 2 +- latest/{userguide => bpg}/book.adoc | 2 + latest/bpg/index.adoc | 65 ++ latest/bpg/upgrades/index.adoc | 989 ++++++++++++++++++++++++++++ latest/userguide/index.adoc | 22 - 5 files changed, 1057 insertions(+), 23 deletions(-) rename latest/{userguide => bpg}/book.adoc (95%) create mode 100644 latest/bpg/index.adoc create mode 100644 latest/bpg/upgrades/index.adoc delete mode 100644 latest/userguide/index.adoc diff --git a/build-info.xml b/build-info.xml index 1c9c5beec..c1bbb1a79 100755 --- a/build-info.xml +++ b/build-info.xml @@ -20,7 +20,7 @@ eks-bpg latest latest - latest/userguide + latest/bpg en_us Tn#wuhH~ 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 YKX?8!p8t#HGVABAf5!8F)p+*&AGeXnNB{r; literal 0 HcmV?d00001 diff --git a/latest/bpg/images/reliability_eks-data-plane-connectivity.jpeg b/latest/bpg/images/reliability_eks-data-plane-connectivity.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..253d6294e10f302bc595e1e579110714fad01dfa GIT binary patch literal 87614 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 te;C6bXJgp&e*oJcP`dyC literal 0 HcmV?d00001 diff --git a/latest/bpg/images/reliability_pod-topology-spread-constraints.jpg b/latest/bpg/images/reliability_pod-topology-spread-constraints.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2b67ea6b8034fcc349c4fc67370db09156ae8018 GIT binary patch literal 65249 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 +video::youtube[RBE3yk2UlYA] Amazon EKS implements cluster networking through the https://github.com/aws/amazon-vpc-cni-k8s[Amazon VPC Container Network Interface] plugin, also known as VPC CNI. The CNI plugin allows Kubernetes Pods to have the same IP address as they do on the VPC network. More specifically, all containers inside the Pod share a network namespace, and they can communicate with each-other using local ports. diff --git a/latest/bpg/reliability/application.adoc b/latest/bpg/reliability/application.adoc new file mode 100644 index 000000000..05e2607f7 --- /dev/null +++ b/latest/bpg/reliability/application.adoc @@ -0,0 +1,803 @@ +[."topic"] +[[application,application.title]] += Running highly-available applications +:info_doctype: section +:info_title: Running highly-available applications +:info_abstract: Running highly-available applications +:info_titleabbrev: Running highly-available applications +:imagesdir: images/ + + + +Your customers expect your application to be always available, including +when you’re making changes and especially during spikes in traffic. A +scalable and resilient architecture keeps your applications and services +running without disruptions, which keeps your users happy. A scalable +infrastructure grows and shrinks based on the needs of the business. +Eliminating single points of failure is a critical step towards +improving an application’s availability and making it resilient. + +With Kubernetes, you can operate your applications and run them in a +highly-available and resilient fashion. Its declarative management +ensures that once you’ve set up the application, Kubernetes will +continuously try to +https://kubernetes.io/docs/concepts/architecture/controller/#desired-vs-current[match +the current state with the desired state]. + +== Recommendations + +=== Avoid running singleton Pods + +If your entire application runs in a single Pod, then your application +will be unavailable if that Pod gets terminated. Instead of deploying +applications using individual pods, create +https://kubernetes.io/docs/concepts/workloads/controllers/deployment/[Deployments]. +If a Pod that is created by a Deployment fails or gets terminated, the +Deployment +https://kubernetes.io/docs/concepts/architecture/controller/[controller] +will start a new pod to ensure the specified number of replica Pods are +always running. + +=== Run multiple replicas + +Running multiple replicas Pods of an app using a Deployment helps it run +in a highly-available manner. If one replica fails, the remaining +replicas will still function, albeit at reduced capacity until +Kubernetes creates another Pod to make up for the loss. Furthermore, you +can use the +https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/[Horizontal +Pod Autoscaler] to scale replicas automatically based on workload +demand. + +=== Schedule replicas across nodes + +Running multiple replicas won’t be very useful if all the replicas are +running on the same node, and the node becomes unavailable. Consider +using pod anti-affinity or pod topology spread constraints to spread +replicas of a Deployment across multiple worker nodes. + +You can further improve a typical application’s reliability by running +it across multiple AZs. + +==== Using Pod anti-affinity rules + +The manifest below tells Kubernetes scheduler to _prefer_ to place pods +on separate nodes and AZs. It doesn’t require distinct nodes or AZ +because if it did, then Kubernetes will not be able to schedule any pods +once there is a pod running in each AZ. If your application requires +just three replicas, you can use +`+requiredDuringSchedulingIgnoredDuringExecution+` for +`+topologyKey: topology.kubernetes.io/zone+`, and Kubernetes scheduler +will not schedule two pods in the same AZ. + +.... +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spread-host-az + labels: + app: web-server +spec: + replicas: 4 + selector: + matchLabels: + app: web-server + template: + metadata: + labels: + app: web-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - web-server + topologyKey: topology.kubernetes.io/zone + weight: 100 + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - web-server + topologyKey: kubernetes.io/hostname + weight: 99 + containers: + - name: web-app + image: nginx:1.16-alpine +.... + +==== Using Pod topology spread constraints + +Similar to pod anti-affinity rules, pod topology spread constraints +allow you to make your application available across different failure +(or topology) domains like hosts or AZs. This approach works very well +when you’re trying to ensure fault tolerance as well as availability by +having multiple replicas in each of the different topology domains. Pod +anti-affinity rules, on the other hand, can easily produce a result +where you have a single replica in a topology domain because the pods +with an anti-affinity toward each other have a repelling effect. In such +cases, a single replica on a dedicated node isn’t ideal for fault +tolerance nor is it a good use of resources. With topology spread +constraints, you have more control over the spread or distribution that +the scheduler should try to apply across the topology domains. Here are +some important properties to use in this approach: 1. The `+maxSkew+` is +used to control or determine the maximum point to which things can be +uneven across the topology domains. For example, if an application has +10 replicas and is deployed across 3 AZs, you can’t get an even spread, +but you can influence how uneven the distribution will be. In this case, +the `+maxSkew+` can be anything between 1 and 10. A value of 1 means you +can potentially end up with a spread like `+4,3,3+`, `+3,4,3+` or +`+3,3,4+` across the 3 AZs. In contrast, a value of 10 means you can +potentially end up with a spread like `+10,0,0+`, `+0,10,0+` or +`+0,0,10+` across 3 AZs. 2. The `+topologyKey+` is a key for one of the +node labels and defines the type of topology domain that should be used +for the pod distribution. For example, a zonal spread would have the +following key-value pair: + +.... +topologyKey: "topology.kubernetes.io/zone" +.... + +[arabic, start=3] +. The `+whenUnsatisfiable+` property is used to determine how you want +the scheduler to respond if the desired constraints can’t be satisfied. +. The `+labelSelector+` is used to find matching pods so that the +scheduler can be aware of them when deciding where to place pods in +accordance with the constraints that you specify. + +In addition to these above, there are other fields that you can read +about further in the +https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/[Kubernetes +documentation]. + +.Pod topology spread constraints across 3 AZs +image::./images/pod-topology-spread-constraints.jpg[Pod topology spread +constraints across 3 AZs] + +.... +apiVersion: apps/v1 +kind: Deployment +metadata: + name: spread-host-az + labels: + app: web-server +spec: + replicas: 10 + selector: + matchLabels: + app: web-server + template: + metadata: + labels: + app: web-server + spec: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: "topology.kubernetes.io/zone" + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app: express-test + containers: + - name: web-app + image: nginx:1.16-alpine +.... + +=== Run Kubernetes Metrics Server + +Install the Kubernetes +https://github.com/kubernetes-sigs/metrics-server[metrics server] to +help scale your applications. Kubernetes autoscaler add-ons like +https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/[HPA] +and +https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler[VPA] +need to track metrics of applications to scale them. The metrics-server +collects resource metrics that can be used to make scaling decisions. +The metrics are collected from kubelets and served in +https://github.com/kubernetes/metrics[Metrics API format]. + +The metrics server doesn’t retain any data, and it’s not a monitoring +solution. Its purpose is to expose CPU and memory usage metrics to other +systems. If you want to track your application’s state over time, you +need a monitoring tool like Prometheus or Amazon CloudWatch. + +Follow the +https://docs.aws.amazon.com/eks/latest/userguide/metrics-server.html[EKS +documentation] to install metrics-server in your EKS cluster. + +== Horizontal Pod Autoscaler (HPA) + +HPA can automatically scale your application in response to demand and +help you avoid impacting your customers during peak traffic. It is +implemented as a control loop in Kubernetes that periodically queries +metrics from APIs that provide resource metrics. + +HPA can retrieve metrics from the following APIs: 1. `+metrics.k8s.io+` +also known as Resource Metrics API — Provides CPU and memory usage for +pods 2. `+custom.metrics.k8s.io+` — Provides metrics from other metric +collectors like Prometheus; these metrics are *internal* to your +Kubernetes cluster. 3. `+external.metrics.k8s.io+` — Provides metrics +that are *external* to your Kubernetes cluster (E.g., SQS Queue Depth, +ELB latency). + +You must use one of these three APIs to provide the metric to scale your +application. + +=== Scaling applications based on custom or external metrics + +You can use custom or external metrics to scale your application on +metrics other than CPU or memory utilization. +https://github.com/kubernetes-sigs/custom-metrics-apiserver[Custom +Metrics] API servers provide the `+custom-metrics.k8s.io+` API that HPA +can use to autoscale applications. + +You can use the +https://github.com/directxman12/k8s-prometheus-adapter[Prometheus +Adapter for Kubernetes Metrics APIs] to collect metrics from Prometheus +and use with the HPA. In this case, Prometheus adapter will expose +Prometheus metrics in +https://github.com/kubernetes/metrics/blob/master/pkg/apis/metrics/types.go[Metrics +API format]. + +Once you deploy the Prometheus Adapter, you can query custom metrics +using kubectl. `+kubectl get —raw /apis/custom.metrics.k8s.io/v1beta1/+` + +External metrics, as the name suggests, provide the Horizontal Pod +Autoscaler the ability to scale deployments using metrics that are +external to the Kubernetes cluster. For example, in batch processing +workloads, it is common to scale the number of replicas based on the +number of jobs in flight in an SQS queue. + +To autoscale a Deployment using a CloudWatch metric, for example, +https://github.com/awslabs/k8s-cloudwatch-adapter/blob/master/samples/sqs/README.md[scaling +a batch-processor application based on SQS queue depth], you can use +https://github.com/awslabs/k8s-cloudwatch-adapter[`+k8s-cloudwatch-adapter+`]. +`+k8s-cloudwatch-adapter+` is a community project and not maintained by +AWS. + +== Vertical Pod Autoscaler (VPA) + +VPA automatically adjusts the CPU and memory reservation for your Pods +to help you "`right-size`" your applications. For applications that need +to be scaled vertically - which is done by increasing resource +allocation - you can use +https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler[VPA] +to automatically scale Pod replicas or provide scaling recommendations. + +Your application may become temporarily unavailable if VPA needs to +scale it because VPA’s current implementation does not perform in-place +adjustments to Pods; instead, it will recreate the Pod that needs to be +scaled. + +https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html[EKS +Documentation] includes a walkthrough for setting up VPA. + +https://github.com/FairwindsOps/goldilocks/[Fairwinds Goldilocks] +project provides a dashboard to visualize VPA recommendations for CPU +and memory requests and limits. Its VPA update mode allows you to +auto-scale Pods based on VPA recommendations. + +== Updating applications + +Modern applications require rapid innovation with a high degree of +stability and availability. Kubernetes gives you the tools to update +your applications continuously without disrupting your customers. + +Let’s look at some of the best practices that make it possible to +quickly deploy changes without sacrificing availability. + +=== Have a mechanism to perform rollbacks + +Having an undo button can evade disasters. It is a best practice to test +deployments in a separate lower environment (test or development +environment) before updating the production cluster. Using a CI/CD +pipeline can help you automate and test deployments. With a continuous +deployment pipeline, you can quickly revert to the older version if the +upgrade happens to be defective. + +You can use Deployments to update a running application. This is +typically done by updating the container image. You can use `+kubectl+` +to update a Deployment like this: + +[source,bash] +---- +kubectl --record deployment.apps/nginx-deployment set image nginx-deployment nginx=nginx:1.16.1 +---- + +The `+--record+` argument record the changes to the Deployment and helps +you if you need to perform a rollback. +`+kubectl rollout history deployment+` shows you the recorded changes to +Deployments in your cluster. You can rollback a change using +`+kubectl rollout undo deployment +`. + +By default, when you update a Deployment that requires a recreation of +pods, Deployment will perform a +https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/[rolling +update]. In other words, Kubernetes will only update a portion of the +running pods in a Deployment and not all the Pods at once. You can +control how Kubernetes performs rolling updates through +`+RollingUpdateStrategy+` property. + +When performing a _rolling update_ of a Deployment, you can use the +https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#max-unavailable[`+Max Unavailable+`] +property to specify the maximum number of Pods that can be unavailable +during the update. The `+Max Surge+` property of Deployment allows you +to set the maximum number of Pods that can be created over the desired +number of Pods. + +Consider adjusting `+max unavailable+` to ensure that a rollout doesn’t +disrupt your customers. For example, Kubernetes sets 25% +`+max unavailable+` by default, which means if you have 100 Pods, you +may have only 75 Pods actively working during a rollout. If your +application needs a minimum of 80 Pods, this rollout can be disruptive. +Instead, you can set `+max unavailable+` to 20% to ensure that there are +at least 80 functional Pods throughout the rollout. + +=== Use blue/green deployments + +Changes are inherently risky, but changes that cannot be undone can be +potentially catastrophic. Change procedures that allow you to +effectively turn back time through a _rollback_ make enhancements and +experimentation safer. Blue/green deployments give you a method to +quickly retract the changes if things go wrong. In this deployment +strategy, you create an environment for the new version. This +environment is identical to the current version of the application being +updated. Once the new environment is provisioned, traffic is routed to +the new environment. If the new version produces the desired results +without generating errors, the old environment is terminated. Otherwise, +traffic is restored to the old version. + +You can perform blue/green deployments in Kubernetes by creating a new +Deployment that is identical to the existing version’s Deployment. Once +you verify that the Pods in the new Deployment are running without +errors, you can start sending traffic to the new Deployment by changing +the `+selector+` spec in the Service that routes traffic to your +application’s Pods. + +Many continuous integration tools such as https://fluxcd.io[Flux], +https://www.jenkins.io[Jenkins], and https://spinnaker.io[Spinnaker] let +you automate blue/green deployments. AWS Containers Blog includes a +walkthrough using AWS Load Balancer Controller: +https://aws.amazon.com/blogs/containers/using-aws-load-balancer-controller-for-blue-green-deployment-canary-deployment-and-a-b-testing/[Using +AWS Load Balancer Controller for blue/green deployment, canary +deployment and A/B testing] + +=== Use Canary deployments + +Canary deployments are a variant of blue/green deployments that can +significantly remove risk from changes. In this deployment strategy, you +create a new Deployment with fewer Pods alongside your old Deployment, +and divert a small percentage of traffic to the new Deployment. If +metrics indicate that the new version is performing as well or better +than the existing version, you progressively increase traffic to the new +Deployment while scaling it up until all traffic is diverted to the new +Deployment. If there’s an issue, you can route all traffic to the old +Deployment and stop sending traffic to the new Deployment. + +Although Kubernetes offers no native way to perform canary deployments, +you can use tools such as https://github.com/weaveworks/flagger[Flagger] +with +https://docs.flagger.app/tutorials/istio-progressive-delivery[Istio] or +https://docs.flagger.app/install/flagger-install-on-eks-appmesh[App +Mesh]. + +== Health checks and self-healing + +No software is bug-free, but Kubernetes can help you to minimize the +impact of software failures. In the past, if an application crashed, +someone had to remediate the situation by restarting the application +manually. Kubernetes gives you the ability to detect software failures +in your Pods and automatically replace them with new replicas. With +Kubernetes you can monitor the health of your applications and +automatically replace unhealthy instances. + +Kubernetes supports three types of +https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/[health-checks]: + +[arabic] +. Liveness probe +. Startup probe (supported in Kubernetes version 1.16+) +. Readiness probe + +https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/[Kubelet], +the Kubernetes agent, is responsible for running all the above-mentioned +checks. Kubelet can check a Pods’ health in three ways: kubelet can +either run a shell command inside a Pod’s container, send an HTTP GET +request to its container, or open a TCP socket on a specified port. + +If you choose an `+exec+`-based probe, which runs a shell script inside +a container, ensure that the shell command exits _before_ the +`+timeoutSeconds+` value expires. Otherwise, your node will have +`++` processes, leading to node failure. + +== Recommendations + +=== Use Liveness Probe to remove unhealthy pods + +The Liveness probe can detect _deadlock_ conditions where the process +continues to run, but the application becomes unresponsive. For example, +if you are running a web service that listens on port 80, you can +configure a Liveness probe to send an HTTP GET request on Pod’s port 80. +Kubelet will periodically send a GET request to the Pod and expect a +response; if the Pod responds between 200-399 then the kubelet considers +that Pod is healthy; otherwise, the Pod will be marked as unhealthy. If +a Pod fails health-checks continuously, the kubelet will terminate it. + +You can use `+initialDelaySeconds+` to delay the first probe. + +When using the Liveness Probe, ensure that your application doesn’t run +into a situation in which all Pods simultaneously fail the Liveness +Probe because Kubernetes will try to replace all your Pods, which will +render your application offline. Furthermore, Kubernetes will continue +to create new Pods that will also fail Liveness Probes, putting +unnecessary strain on the control plane. Avoid configuring the Liveness +Probe to depend on an a factor that is external to your Pod, for +example, a external database. In other words, a non-responsive +external-to-your-Pod database shouldn’t make your Pods fail their +Liveness Probes. + +Sandor Szücs’s post +https://srcco.de/posts/kubernetes-liveness-probes-are-dangerous.html[LIVENESS +PROBES ARE DANGEROUS] describes problems that can be caused by +misconfigured probes. + +=== Use Startup Probe for applications that take longer to start + +When your app needs additional time to startup, you can use the Startup +Probe to delay the Liveness and Readiness Probe. For example, a Java app +that needs to hydrate cache from a database may need up to two minutes +before it is fully functional. Any Liveness or Readiness Probe until it +becomes fully functional might fail. Configuring a Startup Probe will +allow the Java app to become _healthy_ before Liveness or Readiness +Probe are executed. + +Until the Startup Probe succeeds, all the other Probes are disabled. You +can define the maximum time Kubernetes should wait for application +startup. If, after the maximum configured time, the Pod still fails +Startup Probes, it will be terminated, and a new Pod will be created. + +The Startup Probe is similar to the Liveness Probe – if they fail, the +Pod is recreated. As Ricardo A. explains in his post +https://medium.com/swlh/fantastic-probes-and-how-to-configure-them-fef7e030bd2f[Fantastic +Probes And How To Configure Them], Startup Probes should be used when +the startup time of an application is unpredictable. If you know your +application needs ten seconds to start, you should use +Liveness/Readiness Probe with `+initialDelaySeconds+` instead. + +=== Use Readiness Probe to detect partial unavailability + +While the Liveness probe detects failures in an app that are resolved by +terminating the Pod (hence, restarting the app), Readiness Probe detects +conditions where the app may be _temporarily_ unavailable. In these +situations, the app may become temporarily unresponsive; however, it is +expected to be healthy again once this operation completes. + +For example, during intense disk I/O operations, applications may be +temporarily unavailable to handle requests. Here, terminating the +application’s Pod is not a remedy; at the same time, additional requests +sent to the Pod can fail. + +You can use the Readiness Probe to detect temporary unavailability in +your app and stop sending requests to its Pod until it becomes +functional again. _Unlike Liveness Probe, where a failure would result +in a recreation of Pod, a failed Readiness Probe would mean that Pod +will not receive any traffic from Kubernetes Service_. When the +Readiness Probe succeeds, Pod will resume receiving traffic from +Service. + +Just like the Liveness Probe, avoid configuring Readiness Probes that +depend on a resource that’s external to the Pod (such as a database). +Here’s a scenario where a poorly configured Readiness can render the +application nonfunctional - if a Pod’s Readiness Probe fails when the +app’s database is unreachable, other Pod replicas will also fail +simultaneously since they share the same health-check criteria. Setting +the probe in this way will ensure that whenever the database is +unavailable, the Pod’s Readiness Probes will fail, and Kubernetes will +stop sending traffic _all_ Pods. + +A side-effect of using Readiness Probes is that they can increase the +time it takes to update Deployments. New replicas will not receive +traffic unless Readiness Probes are successful; until then, old replicas +will continue to receive traffic. + +''''' + +== Dealing with disruptions + +Pods have a finite lifetime - even if you have long-running Pods, it’s +prudent to ensure Pods terminate correctly when the time comes. +Depending on your upgrade strategy, Kubernetes cluster upgrades may +require you to create new worker nodes, which requires all Pods to be +recreated on newer nodes. Proper termination handling and Pod Disruption +Budgets can help you avoid service disruptions as Pods are removed from +older nodes and recreated on newer nodes. + +The preferred way to upgrade worker nodes is by creating new worker +nodes and terminating old ones. Before terminating worker nodes, you +should `+drain+` it. When a worker node is drained, all its pods are +_safely_ evicted. Safely is a key word here; when pods on a worker are +evicted, they are not simply sent a `+SIGKILL+` signal. Instead, a +`+SIGTERM+` signal is sent to the main process (PID 1) of each container +in the Pods being evicted. After the `+SIGTERM+` signal is sent, +Kubernetes will give the process some time (grace period) before a +`+SIGKILL+` signal is sent. This grace period is 30 seconds by default; +you can override the default by using `+grace-period+` flag in kubectl +or declare `+terminationGracePeriodSeconds+` in your Podspec. + +`+kubectl delete pod —grace-period=+` + +It is common to have containers in which the main process doesn’t have +PID 1. Consider this Python-based sample container: + +.... +$ kubectl exec python-app -it ps + PID USER TIME COMMAND + 1 root 0:00 {script.sh} /bin/sh ./script.sh + 5 root 0:00 python app.py +.... + +In this example, the shell script receives `+SIGTERM+`, the main +process, which happens to be a Python application in this example, +doesn’t get a `+SIGTERM+` signal. When the Pod is terminated, the Python +application will be killed abruptly. This can be remediated by changing +the +https://docs.docker.com/engine/reference/builder/#entrypoint[`+ENTRYPOINT+`] +of the container to launch the Python application. Alternatively, you +can use a tool like https://github.com/Yelp/dumb-init[dumb-init] to +ensure that your application can handle signals. + +You can also use +https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks[Container +hooks] to execute a script or an HTTP request at container start or +stop. The `+PreStop+` hook action runs before the container receives a +`+SIGTERM+` signal and must complete before this signal is sent. The +`+terminationGracePeriodSeconds+` value applies from when the +`+PreStop+` hook action begins executing, not when the `+SIGTERM+` +signal is sent. + +== Recommendations + +=== Protect critical workload with Pod Disruption Budgets + +Pod Disruption Budget or PDB can temporarily halt the eviction process +if the number of replicas of an application falls below the declared +threshold. The eviction process will continue once the number of +available replicas is over the threshold. You can use PDB to declare the +`+minAvailable+` and `+maxUnavailable+` number of replicas. For example, +if you want at least three copies of your app to be available, you can +create a PDB. + +.... +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: my-svc-pdb +spec: + minAvailable: 3 + selector: + matchLabels: + app: my-svc +.... + +The above PDB policy tells Kubernetes to halt the eviction process until +three or more replicas are available. Node draining respects +`+PodDisruptionBudgets+`. During an EKS managed node group upgrade, +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-update-behavior.html[nodes +are drained with a fifteen-minute timeout]. After fifteen minutes, if +the update is not forced (the option is called Rolling update in the EKS +console), the update fails. If the update is forced, the pods are +deleted. + +For self-managed nodes, you can also use tools like +https://github.com/aws/aws-node-termination-handler[AWS Node Termination +Handler], which ensures that the Kubernetes control plane responds +appropriately to events that can cause your EC2 instance to become +unavailable, such as +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html[EC2 +maintenance] events and +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html[EC2 +Spot interruptions]. It uses the Kubernetes API to cordon the node to +ensure no new Pods are scheduled, then drains it, terminating any +running Pods. + +You can use Pod anti-affinity to schedule a Deployment‘s Pods on +different nodes and avoid PDB related delays during node upgrades. + +=== Practice chaos engineering + +____ +Chaos Engineering is the discipline of experimenting on a distributed +system in order to build confidence in the system’s capability to +withstand turbulent conditions in production. +____ + +In his blog, Dominik Tornow explains that +https://medium.com/@dominik.tornow/the-mechanics-of-kubernetes-ac8112eaa302[Kubernetes +is a declarative system] where "`__the user supplies a representation of +the desired state of the system to the system. The system then considers +the current state and the desired state to determine the sequence of +commands to transition from the current state to the desired state.__`" +This means Kubernetes always stores the _desired state_ and if the +system deviates, Kubernetes will take action to restore the state. For +example, if a worker node becomes unavailable, Kubernetes will +reschedule the Pods onto another worker node. Similarly, if a +`+replica+` crashes, the +https://kubernetes.io/docs/concepts/architecture/controller/#design[Deployment +Contoller] will create a new `+replica+`. In this way, Kubernetes +controllers automatically fix failures. + +Chaos engineering tools like https://www.gremlin.com[Gremlin] help you +test the resiliency of your Kubernetes cluster and identify single +points of failure. Tools that introduce artificial chaos in your cluster +(and beyond) can uncover systemic weaknesses, present an opportunity to +identify bottlenecks and misconfigurations, and rectify problems in a +controlled environment. The Chaos Engineering philosophy advocates +breaking things on purpose and stress testing infrastructure to minimize +unanticipated downtime. + +=== Use a Service Mesh + +You can use a service mesh to improve your application’s resiliency. +Service meshes enable service-to-service communication and increase the +observability of your microservices network. Most service mesh products +work by having a small network proxy run alongside each service that +intercepts and inspects the application’s network traffic. You can place +your application in a mesh without modifying your application. Using +service proxy’s built-in features, you can have it generate network +statistics, create access logs, and add HTTP headers to outbound +requests for distributed tracing. + +A service mesh can help you make your microservices more resilient with +features like automatic request retries, timeouts, circuit-breaking, and +rate-limiting. + +If you operate multiple clusters, you can use a service mesh to enable +cross-cluster service-to-service communication. + +=== Service Meshes + +* https://aws.amazon.com/app-mesh/[AWS App Mesh] +* https://istio.io[Istio] +* http://linkerd.io[LinkerD] +* https://www.consul.io[Consul] + +''''' + +== Observability + +Observability is an umbrella term that includes monitoring, logging, and +tracing. Microservices based applications are distributed by nature. +Unlike monolithic applications where monitoring a single system is +sufficient, in a distributed application architecture, you need to +monitor each component’s performance. You can use cluster-level +monitoring, logging, and distributed tracing systems to identify issues +in your cluster before they disrupt your customers. + +Kubernetes built-in tools for troubleshooting and monitoring are +limited. The metrics-server collects resource metrics and stores them in +memory but doesn’t persist them. You can view the logs of a Pod using +kubectl, but Kubernetes doesn’t automatically retain logs. And the +implementation of distributed tracing is done either at the application +code level or using services meshes. + +Kubernetes’ extensibility shines here. Kubernetes allows you to bring +your preferred centralized monitoring, logging, and tracing solution. + +== Recommendations + +=== Monitor your applications + +The number of metrics you need to monitor in modern applications is +growing continuously. It helps if you have an automated way to track +your applications so you can focus on solving your customer’s +challenges. Cluster-wide monitoring tools like +https://prometheus.io[Prometheus] or +https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html[CloudWatch +Container Insights] can monitor your cluster and workload and provide +you signals when, or preferably, before things go wrong. + +Monitoring tools allow you to create alerts that your operations team +can subscribe to. Consider rules to activate alarms for events that can, +when exacerbated, lead to an outage or impact application performance. + +If you’re unclear on which metrics you should monitor, you can take +inspiration from these methods: + +* https://www.weave.works/blog/a-practical-guide-from-instrumenting-code-to-specifying-alerts-with-the-red-method[RED +method]. Stands for requests, errors, and duration. +* http://www.brendangregg.com/usemethod.html[USE method]. Stands for +utilization, saturation, and errors. + +Sysdig’s post https://sysdig.com/blog/alerting-kubernetes/[Best +practices for alerting on Kubernetes] includes a comprehensive list of +components that can impact the availability of your applications. + +=== Use Prometheus client library to expose application metrics + +In addition to monitoring the state of the application and aggregating +standard metrics, you can also use the +https://prometheus.io/docs/instrumenting/clientlibs/[Prometheus client +library] to expose application-specific custom metrics to improve the +application’s observability. + +=== Use centralized logging tools to collect and persist logs + +Logging in EKS falls under two categories: control plane logs and +application logs. EKS control plane logging provides audit and +diagnostic logs directly from the control plane to CloudWatch Logs in +your account. Application logs are logs produced by Pods running inside +your cluster. Application logs include logs produced by Pods that run +the business logic applications and Kubernetes system components such as +CoreDNS, Cluster Autoscaler, Prometheus, etc. + +https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html[EKS +provide five types of control plane logs]: + +[arabic] +. Kubernetes API server component logs +. Audit +. Authenticator +. Controller manager +. Scheduler + +The controller manager and scheduler logs can help diagnose control +plane problems such as bottlenecks and errors. By default, EKS control +plane logs aren’t sent to CloudWatch Logs. You can enable control plane +logging and select the types of EKS control plane logs you’d like to +capture for each cluster in your account + +Collecting application logs requires installing a log aggregator tool +like http://fluentbit.io[Fluent Bit], https://www.fluentd.org[Fluentd], +or +https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html[CloudWatch +Container Insights] in your cluster. + +Kubernetes log aggregator tools run as DaemonSets and scrape container +logs from nodes. Application logs are then sent to a centralized +destination for storage. For example, CloudWatch Container Insights can +use either Fluent Bit or Fluentd to collect logs and ship them to +CloudWatch Logs for storage. Fluent Bit and Fluentd support many popular +log analytics systems such as Elasticsearch and InfluxDB giving you the +ability to change the storage backend for your logs by modifying Fluent +bit or Fluentd’s log configuration. + +=== Use a distributed tracing system to identify bottlenecks + +A typical modern application has components distributed over the +network, and its reliability depends on the proper functioning of each +of the components that make up the application. You can use a +distributed tracing solution to understand how requests flow and how +systems communicate. Traces can show you where bottlenecks exist in your +application network and prevent problems that can cause cascading +failures. + +You have two options to implement tracing in your applications: you can +either implement distributed tracing at the code level using shared +libraries or use a service mesh. + +Implementing tracing at the code level can be disadvantageous. In this +method, you have to make changes to your code. This is further +complicated if you have polyglot applications. You’re also responsible +for maintaining yet another library, across your services. + +Service Meshes like http://linkerd.io[LinkerD], http://istio.io[Istio], +and https://aws.amazon.com/app-mesh/[AWS App Mesh] can be used to +implement distributed tracing in your application with minimal changes +to the application code. You can use service mesh to standardize metrics +generation, logging, and tracing. + +Tracing tools like https://aws.amazon.com/xray/[AWS X-Ray], +https://www.jaegertracing.io[Jaeger] support both shared library and +service mesh implementations. + +Consider using a tracing tool like https://aws.amazon.com/xray/[AWS +X-Ray] or https://www.jaegertracing.io[Jaeger] that supports both +(shared library and service mesh) implementations so you will not have +to switch tools if you later adopt service mesh. diff --git a/latest/bpg/reliability/controlplane.adoc b/latest/bpg/reliability/controlplane.adoc new file mode 100644 index 000000000..aa7588b74 --- /dev/null +++ b/latest/bpg/reliability/controlplane.adoc @@ -0,0 +1,362 @@ +[."topic"] +[[control-plane,control-plane.title]] += EKS Control Plane +:info_doctype: section +:info_title: EKS Control Plane +:info_abstract: EKS Control Plane +:info_titleabbrev: EKS Control Plane +:imagesdir: images/ +:idprefix: reliability-cp + + +Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service +that makes it easy for you to run Kubernetes on AWS without needing to +install, operate, and maintain your own Kubernetes control plane or +worker nodes. It runs upstream Kubernetes and is certified Kubernetes +conformant. This conformance ensures that EKS supports the Kubernetes +APIs, just like the open-source community version that you can install +on EC2 or on-premises. Existing applications running on upstream +Kubernetes are compatible with Amazon EKS. + +EKS automatically manages the availability and scalability of the +Kubernetes control plane nodes, and it automatically replaces unhealthy +control plane nodes. + +== EKS Architecture + +EKS architecture is designed to eliminate any single points of failure +that may compromise the availability and durability of the Kubernetes +control plane. + +The Kubernetes control plane managed by EKS runs inside an EKS managed +VPC. The EKS control plane comprises the Kubernetes API server nodes, +etcd cluster. Kubernetes API server nodes that run components like the +API server, scheduler, and `kube-controller-manager` run in an +auto-scaling group. EKS runs a minimum of two API server nodes in +distinct Availability Zones (AZs) within in AWS region. Likewise, for +durability, the etcd server nodes also run in an auto-scaling group that +spans three AZs. EKS runs a NAT Gateway in each AZ, and API servers and +etcd servers run in a private subnet. This architecture ensures that an +event in a single AZ doesn’t affect the EKS cluster’s availability. + +When you create a new cluster, Amazon EKS creates a highly-available +endpoint for the managed Kubernetes API server that you use to +communicate with your cluster (using tools like `kubectl`). The +managed endpoint uses NLB to load balance Kubernetes API servers. EKS +also provisions two +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html[ENI] s +in different AZs to facilitate communication to your worker nodes. + +EKS Data plane network connectivity + +image::reliability_eks-data-plane-connectivity.jpeg + +You can +https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[configure +whether your Kubernetes cluster’s API server] is reachable from the +public internet (using the public endpoint) or through your VPC (using +the EKS-managed ENIs) or both. + +Whether users and worker nodes connect to the API server using the +public endpoint or the EKS-managed ENI, there are redundant paths for +connection. + +[[cp-recs,cp-recs.title]] +== Recommendations +Learn more. + + +== Monitor Control Plane Metrics + +Monitoring Kubernetes API metrics can give you insights into control +plane performance and identify issues. An unhealthy control plane can +compromise the availability of the workloads running inside the cluster. +For example, poorly written controllers can overload the API servers, +affecting your application’s availability. + +Kubernetes exposes control plane metrics at the `+/metrics+` endpoint. + +You can view the metrics exposed using `+kubectl+`: + +[source,shell] +---- +kubectl get --raw /metrics +---- + +These metrics are represented in a +https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md[Prometheus +text format]. + +You can use Prometheus to collect and store these metrics. In May 2020, +CloudWatch added support for monitoring Prometheus metrics in CloudWatch +Container Insights. So you can also use Amazon CloudWatch to monitor the +EKS control plane. You can use +https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights-Prometheus-Setup-configure.html#ContainerInsights-Prometheus-Setup-new-exporters[Tutorial +for Adding a New Prometheus Scrape Target: Prometheus KPI Server +Metrics] to collect metrics and create CloudWatch dashboard to monitor +your cluster’s control plane. + +You can find Kubernetes API server metrics +https://github.com/kubernetes/apiserver/blob/master/pkg/endpoints/metrics/metrics.go[here]. +For example, `+apiserver_request_duration_seconds+` can indicate how +long API requests are taking to run. + +Consider monitoring these control plane metrics: + +=== API Server + +[width="100%",cols="<50%,<50%",options="header",] +|=== +|Metric |Description +|`+apiserver_request_total+` |Counter of apiserver requests broken out +for each verb, dry run value, group, version, resource, scope, +component, and HTTP response code. + +|`+apiserver_request_duration_seconds*+` |Response latency distribution +in seconds for each verb, dry run value, group, version, resource, +subresource, scope, and component. + +|`+apiserver_admission_controller_admission_duration_seconds+` +|Admission controller latency histogram in seconds, identified by name +and broken out for each operation and API resource and type (validate or +admit). + +|`+apiserver_admission_webhook_rejection_count+` |Count of admission +webhook rejections. Identified by name, operation, rejection_code, type +(validating or admit), error_type (calling_webhook_error, +apiserver_internal_error, no_error) + +|`+rest_client_request_duration_seconds+` |Request latency in seconds. +Broken down by verb and URL. + +|`+rest_client_requests_total+` |Number of HTTP requests, partitioned by +status code, method, and host. +|=== + +=== etcd + +[width="100%",cols="<99%,<1%",options="header",] +|=== +|Metric |Description +|`+etcd_request_duration_seconds+` |Etcd request latency in seconds for +each operation and object type. + +|`+etcd_db_total_size_in_bytes+` or +`+apiserver_storage_db_total_size_in_bytes+` (starting with EKS v1.26) +or `+apiserver_storage_size_bytes+` (starting with EKS v1.28) |Etcd +database size. +|=== + +Consider using the +https://grafana.com/grafana/dashboards/14623[Kubernetes Monitoring +Overview Dashboard] to visualize and monitor Kubernetes API server +requests and latency and etcd latency metrics. + +The following Prometheus query can be used to monitor the current size +of etcd. The query assumes there is job called `+kube-apiserver+` for +scraping metrics from API metrics endpoint and the EKS version is below +v1.26. + +[source,text] +---- +max(etcd_db_total_size_in_bytes{job="kube-apiserver"} / (8 * 1024 * 1024 * 1024)) +---- + +!!! attention When the database size limit is exceeded, etcd emits a no +space alarm and stops taking further write requests. In other words, the +cluster becomes read-only, and all requests to mutate objects such as +creating new pods, scaling deployments, etc., will be rejected by the +cluster’s API server. + +== Cluster Authentication + +EKS currently supports two types of authentication: +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens[bearer/service +account tokens] and IAM authentication which uses +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication[webhook +token authentication]. When users call the Kubernetes API, a webhook +passes an authentication token included in the request to IAM. The +token, a base 64 signed URL, is generated by the AWS Command Line +Interface (https://aws.amazon.com/cli/[AWS CLI]). + +The IAM user or role that creates the EKS Cluster automatically gets +full access to the cluster. You can manage access to the EKS cluster by +editing the +https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html[aws-auth +configmap]. + +If you misconfigure the `+aws-auth+` configmap and lose access to the +cluster, you can still use the cluster creator’s user or role to access +your EKS cluster. + +In the unlikely event that you cannot use the IAM service in the AWS +region, you can also use the Kubernetes service account’s bearer token +to manage the cluster. + +Create a `super-admin` account that is permitted to perform all +actions in the cluster: + +.... +kubectl -n kube-system create serviceaccount super-admin +.... + +Create a role binding that gives super-admin cluster-admin role: + +.... +kubectl create clusterrolebinding super-admin-rb --clusterrole=cluster-admin --serviceaccount=kube-system:super-admin +.... + +Get service account’s secret: + +.... +SECRET_NAME=`kubectl -n kube-system get serviceaccount/super-admin -o jsonpath='{.secrets[0].name}'` +.... + +Get token associated with the secret: + +.... +TOKEN=`kubectl -n kube-system get secret $SECRET_NAME -o jsonpath='{.data.token}'| base64 --decode` +.... + +Add service account and token to `+kubeconfig+`: + +.... +kubectl config set-credentials super-admin --token=$TOKEN +.... + +Set the current-context in `+kubeconfig+` to use super-admin account: + +.... +kubectl config set-context --current --user=super-admin +.... + +Final `+kubeconfig+` should look like this: + +.... +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: + server: https://.gr7.us-west-2.eks.amazonaws.com + name: arn:aws:eks:us-west-2::cluster/ +contexts: +- context: + cluster: arn:aws:eks:us-west-2::cluster/ + user: super-admin + name: arn:aws:eks:us-west-2::cluster/ +current-context: arn:aws:eks:us-west-2::cluster/ +kind: Config +preferences: {} +users: +#- name: arn:aws:eks:us-west-2::cluster/ +# user: +# exec: +# apiVersion: client.authentication.k8s.io/v1alpha1 +# args: +# - --region +# - us-west-2 +# - eks +# - get-token +# - --cluster-name +# - <> +# command: aws +# env: null +- name: super-admin + user: + token: <> +.... + +== Admission Webhooks + +Kubernetes has two types of admission webhooks: +https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers[validating +admission webhooks and mutating admission webhooks]. These allow a user +to extend the kubernetes API and validate or mutate objects before they +are accepted by the API. Poor configurations of these webhooks can +distabilize the EKS control plane by blocking cluster critical +operations. + +In order to avoid impacting cluster critical operations either avoid +setting "`catch-all`" webhooks like the following: + +.... +- name: "pod-policy.example.com" + rules: + - apiGroups: ["*"] + apiVersions: ["*"] + operations: ["*"] + resources: ["*"] + scope: "*" +.... + +Or make sure the webhook has a fail open policy with a timeout shorter +than 30 seconds to ensure that if your webhook is unavailable it will +not impair cluster critical workloads. + +=== Block Pods with unsafe `+sysctls+` + +`+Sysctl+` is a Linux utility that allows users to modify kernel +parameters during runtime. These kernel parameters control various +aspects of the operating system’s behavior, such as network, file +system, virtual memory, and process management. + +Kubernetes allows assigning `+sysctl+` profiles for Pods. Kubernetes +categorizes `+systcls+` as safe and unsafe. Safe `+sysctls+` are +namespaced in the container or Pod, and setting them doesn’t impact +other Pods on the node or the node itself. In contrast, unsafe sysctls +are disabled by default since they can potentially disrupt other Pods or +make the node unstable. + +As unsafe `+sysctls+` are disabled by default, the kubelet will not +create a Pod with unsafe `+sysctl+` profile. If you create such a Pod, +the scheduler will repeatedly assign such Pods to nodes, while the node +fails to launch it. This infinite loop ultimately strains the cluster +control plane, making the cluster unstable. + +Consider using +https://github.com/open-policy-agent/gatekeeper-library/blob/377cb915dba2db10702c25ef1ee374b4aa8d347a/src/pod-security-policy/forbidden-sysctls/constraint.tmpl[OPA +Gatekeeper] or +https://kyverno.io/policies/pod-security/baseline/restrict-sysctls/restrict-sysctls/[Kyverno] +to reject Pods with unsafe `+sysctls+`. + +== Handling Cluster Upgrades + +Since April 2021, Kubernetes release cycle has been changed from four +releases a year (once a quarter) to three releases a year. A new minor +version (like 1.*21* or 1.*22*) is released approximately +https://kubernetes.io/blog/2021/07/20/new-kubernetes-release-cadence/#what-s-changing-and-when[every +fifteen weeks]. Starting with Kubernetes 1.19, each minor version is +supported for approximately twelve months after it’s first released. +With the advent of Kubernetes v1.28, the compatibility skew between the +control plane and worker nodes has expanded from n-2 to n-3 minor +versions. To learn more, see xref:cluster-upgrades[Best Practices +for Cluster Upgrades]. + +== Running large clusters + +EKS actively monitors the load on control plane instances and +automatically scales them to ensure high performance. However, you +should account for potential performance issues and limits within +Kubernetes and quotas in AWS services when running large clusters. + +* Clusters with more than 1000 services may experience network latency +with using `+kube-proxy+` in `+iptables+` mode according to the +https://www.projectcalico.org/comparing-kube-proxy-modes-iptables-or-ipvs/[tests +performed by the ProjectCalico team]. The solution is to switch to +https://medium.com/@jeremy.i.cowan/the-problem-with-kube-proxy-enabling-ipvs-on-eks-169ac22e237e[running +`+kube-proxy+` in `+ipvs+` mode]. +* You may also experience +https://docs.aws.amazon.com/AWSEC2/latest/APIReference/throttling.html[EC2 +API request throttling] if the CNI needs to request IP addresses for +Pods or if you need to create new EC2 instances frequently. You can +reduce calls EC2 API by configuring the CNI to cache IP addresses. You +can use larger EC2 instance types to reduce EC2 scaling events. + +== Additional Resources: + +* https://aws.amazon.com/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes/[De-mystifying +cluster networking for Amazon EKS worker nodes] +* https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[Amazon +EKS cluster endpoint access control] +* https://www.youtube.com/watch?v=7vxDWDD2YnM[AWS re:Invent 2019: Amazon +EKS under the hood (CON421-R1)] diff --git a/latest/bpg/reliability/dataplane.adoc b/latest/bpg/reliability/dataplane.adoc new file mode 100644 index 000000000..a9d56093b --- /dev/null +++ b/latest/bpg/reliability/dataplane.adoc @@ -0,0 +1,547 @@ +[."topic"] +[[data-plane,data-plane.title]] += EKS Data Plane +:info_doctype: section +:info_title: EKS Data Plane +:info_abstract: EKS Data Plane +:info_titleabbrev: EKS Data Plane +:imagesdir: images/ + +To operate high-available and resilient applications, you need a +highly-available and resilient data plane. An elastic data plane ensures +that Kubernetes can scale and heal your applications automatically. A +resilient data plane consists of two or more worker nodes, can grow and +shrink with the workload, and automatically recover from failures. + +You have two choices for worker nodes with EKS: +https://docs.aws.amazon.com/eks/latest/userguide/worker.html[EC2 +instances] and +https://docs.aws.amazon.com/eks/latest/userguide/fargate.html[Fargate]. +If you choose EC2 instances, you can manage the worker nodes yourself or +use +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[EKS +managed node groups]. You can have a cluster with a mix of managed, +self-managed worker nodes, and Fargate. + +EKS on Fargate offers the easiest path to a resilient data plane. +Fargate runs each Pod in an isolated compute environment. Each Pod +running on Fargate gets its own worker node. Fargate automatically +scales the data plane as Kubernetes scales pods. You can scale both the +data plane and your workload by using the +https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html[horizontal +pod autoscaler]. + +The preferred way to scale EC2 worker nodes is by using +https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md[Kubernetes +Cluster Autoscaler], +https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html[EC2 +Auto Scaling groups] or community projects like +https://github.com/atlassian/escalator[Atlassian’s Escalator]. + +== Recommendations + +=== Use EC2 Auto Scaling Groups to create worker nodes + +It is a best practice to create worker nodes using EC2 Auto Scaling +groups instead of creating individual EC2 instances and joining them to +the cluster. Auto Scaling Groups will automatically replace any +terminated or failed nodes ensuring that the cluster always has the +capacity to run your workload. + +=== Use Kubernetes Cluster Autoscaler to scale nodes + +Cluster Autoscaler adjusts the size of the data plane when there are +pods that cannot be run because the cluster has insufficient resources, +and adding another worker node would help. Although Cluster Autoscaler +is a reactive process, it waits until pods are in _Pending_ state due to +insufficient capacity in the cluster. When such an event occurs, it adds +EC2 instances to the cluster. Whenever the cluster runs out of capacity, +new replicas - or new pods - will be unavailable (_in Pending state_) +until worker nodes are added. This delay may impact your applications’ +reliability if the data plane cannot scale fast enough to meet the +demands of the workload. If a worker node is consistently underutilized +and all of its pods can be scheduled on other worker nodes, Cluster +Autoscaler terminates it. + +=== Configure over-provisioning with Cluster Autoscaler + +Cluster Autoscaler triggers a scale-up of the data-plane when Pods in +the cluster are already _Pending_. Hence, there may be a delay between +the time your application needs more replicas, and when it, in fact, +gets more replicas. An option to account for this possible delay is +through adding more than required replicas, inflating the number of +replicas for the application. + +Another pattern that Cluster Autoscaler recommends uses +https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-can-i-configure-overprovisioning-with-cluster-autoscaler[_pause_ +Pods and the Priority Preemption feature]. The _pause Pod_ runs a +https://github.com/kubernetes/kubernetes/tree/master/build/pause[pause +container], which as the name suggests, does nothing but acts as a +placeholder for compute capacity that can be used by other Pods in your +cluster. Because it runs with a _very low assigned priority_, the pause +Pod gets evicted from the node when another Pod needs to be created, and +the cluster doesn’t have available capacity. The Kubernetes Scheduler +notices the eviction of the pause Pod and tries to reschedule it. But +since the cluster is running at capacity, the pause Pod remains +_Pending_, to which the Cluster Autoscaler reacts by adding nodes. + +A Helm chart is available to install +https://github.com/helm/charts/tree/master/stable/cluster-overprovisioner[cluster +overprovisioner]. + +=== Using Cluster Autoscaler with multiple Auto Scaling Groups + +Run the Cluster Autoscaler with the `+--node-group-auto-discovery+` flag +enabled. Doing so will allow the Cluster Autoscaler to find all +autoscaling groups that include a particular defined tag and prevents +the need to define and maintain each autoscaling group in the manifest. + +=== Using Cluster Autoscaler with local storage + +By default, the Cluster Autoscaler does not scale-down nodes that have +pods deployed with local storage attached. Set the +`+--skip-nodes-with-local-storage+` flag to false to allow Cluster +Autoscaler to scale-down these nodes. + +=== Spread worker nodes and workload across multiple AZs + +You can protect your workloads from failures in an individual AZ by +running worker nodes and pods in multiple AZs. You can control the AZ +the worker nodes are created in using the subnets you create the nodes +in. + +If you are using Kubernetes 1.18+, the recommended method for spreading +pods across AZs is to use +https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods[Topology +Spread Constraints for Pods]. + +The deployment below spreads pods across AZs if possible, letting those +pods run anyway if not: + +.... +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web-server +spec: + replicas: 3 + selector: + matchLabels: + app: web-server + template: + metadata: + labels: + app: web-server + spec: + topologySpreadConstraints: + - maxSkew: 1 + whenUnsatisfiable: ScheduleAnyway + topologyKey: topology.kubernetes.io/zone + labelSelector: + matchLabels: + app: web-server + containers: + - name: web-app + image: nginx + resources: + requests: + cpu: 1 +.... + +!!! note `+kube-scheduler+` is only aware of topology domains via nodes +that exist with those labels. If the above deployment is deployed to a +cluster with nodes only in a single zone, all of the pods will schedule +on those nodes as `+kube-scheduler+` isn’t aware of the other zones. For +this topology spread to work as expected with the scheduler, nodes must +already exist in all zones. This issue will be resolved in Kubernetes +1.24 with the addition of the `+MinDomainsInPodToplogySpread+` +https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#api[feature +gate] which allows specifying a `+minDomains+` property to inform the +scheduler of the number of eligible domains. + +!!! warning Setting `+whenUnsatisfiable+` to `+DoNotSchedule+` will +cause pods to be unschedulable if the topology spread constraint can’t +be fulfilled. It should only be set if its preferable for pods to not +run instead of violating the topology spread constraint. + +On older versions of Kubernetes, you can use pod anti-affinity rules to +schedule pods across multiple AZs. The manifest below informs Kubernetes +scheduler to _prefer_ scheduling pods in distinct AZs. + +.... +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web-server + labels: + app: web-server +spec: + replicas: 4 + selector: + matchLabels: + app: web-server + template: + metadata: + labels: + app: web-server + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - web-server + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + containers: + - name: web-app + image: nginx +.... + +!!! warning Do not require that pods be scheduled across distinct AZs +otherwise, the number of pods in a deployment will never exceed the +number of AZs. + +=== Ensure capacity in each AZ when using EBS volumes + +If you use +https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html[Amazon EBS +to provide Persistent Volumes], then you need to ensure that the pods +and associated EBS volume are located in the same AZ. At the time of +writing, EBS volumes are only available within a single AZ. A Pod cannot +access EBS-backed persistent volumes located in a different AZ. +Kubernetes +https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone[scheduler +knows which AZ a worker node] is located in. Kubernetes will always +schedule a Pod that requires an EBS volume in the same AZ as the volume. +However, if there are no worker nodes available in the AZ where the +volume is located, then the Pod cannot be scheduled. + +Create Auto Scaling Group for each AZ with enough capacity to ensure +that the cluster always has capacity to schedule pods in the same AZ as +the EBS volumes they need. In addition, you should enable the +`+--balance-similar-node-groups+` feature in Cluster Autoscaler. + +If you are running an application that uses EBS volume but has no +requirements to be highly available, then you can restrict the +deployment of the application to a single AZ. In EKS, worker nodes are +automatically added `+failure-domain.beta.kubernetes.io/zone+` label, +which contains the name of the AZ. You can see the labels attached to +your nodes by running `+kubectl get nodes --show-labels+`. More +information about built-in node labels is available +https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#built-in-node-labels[here]. +You can use node selectors to schedule a pod in a particular AZ. + +In the example below, the pod will only be scheduled in `+us-west-2c+` +AZ: + +.... +apiVersion: v1 +kind: Pod +metadata: + name: single-az-pod +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: failure-domain.beta.kubernetes.io/zone + operator: In + values: + - us-west-2c + containers: + - name: single-az-container + image: kubernetes/pause +.... + +Persistent volumes (backed by EBS) are also automatically labeled with +the name of AZ; you can see which AZ your persistent volume belongs to +by running `+kubectl get pv -L topology.ebs.csi.aws.com/zone+`. When a +pod is created and claims a volume, Kubernetes will schedule the Pod on +a node in the same AZ as the volume. + +Consider this scenario; you have an EKS cluster with one node group. +This node group has three worker nodes spread across three AZs. You have +an application that uses an EBS-backed Persistent Volume. When you +create this application and the corresponding volume, its Pod gets +created in the first of the three AZs. Then, the worker node that runs +this Pod becomes unhealthy and subsequently unavailable for use. Cluster +Autoscaler will replace the unhealthy node with a new worker node; +however, because the autoscaling group spans across three AZs, the new +worker node may get launched in the second or the third AZ, but not in +the first AZ as the situation demands. As the AZ-constrained EBS volume +only exists in the first AZ, but there are no worker nodes available in +that AZ, the Pod cannot be scheduled. Therefore, you should create one +node group in each AZ, so there is always enough capacity available to +run pods that cannot be scheduled in other AZs. + +Alternatively, +https://github.com/kubernetes-sigs/aws-efs-csi-driver[EFS] can simplify +cluster autoscaling when running applications that need persistent +storage. Clients can access EFS file systems concurrently from all the +AZs in the region. Even if a Pod using EFS-backed Persistent Volume gets +terminated and gets scheduled in different AZ, it will be able to mount +the volume. + +=== Run node-problem-detector + +Failures in worker nodes can impact the availability of your +applications. +https://github.com/kubernetes/node-problem-detector[node-problem-detector] +is a Kubernetes add-on that you can install in your cluster to detect +worker node issues. You can use a +https://github.com/kubernetes/node-problem-detector#remedy-systems[npd’s +remedy system] to drain and terminate the node automatically. + +=== Reserving resources for system and Kubernetes daemons + +You can improve worker nodes’ stability by +https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/[reserving +compute capacity for the operating system and Kubernetes daemons]. Pods +- especially ones without `+limits+` declared - can saturate system +resources putting nodes in a situation where operating system processes +and Kubernetes daemons (`+kubelet+`, container runtime, etc.) compete +with pods for system resources. You can use `+kubelet+` flags +`+--system-reserved+` and `+--kube-reserved+` to reserve resources for +system process (`+udev+`, `+sshd+`, etc.) and Kubernetes daemons +respectively. + +If you use the +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS-optimized +Linux AMI], the CPU, memory, and storage are reserved for the system and +Kubernetes daemons by default. When worker nodes based on this AMI +launch, EC2 user-data is configured to trigger the +https://github.com/awslabs/amazon-eks-ami/blob/master/files/bootstrap.sh[`+bootstrap.sh+` +script]. This script calculates CPU and memory reservations based on the +number of CPU cores and total memory available on the EC2 instance. The +calculated values are written to the `+KubeletConfiguration+` file +located at `+/etc/kubernetes/kubelet/kubelet-config.json+`. + +You may need to increase the system resource reservation if you run +custom daemons on the node and the amount of CPU and memory reserved by +default is insufficient. + +`+eksctl+` offers the easiest way to customize +https://eksctl.io/usage/customizing-the-kubelet/[resource reservation +for system and Kubernetes daemons]. + +=== Implement QoS + +For critical applications, consider defining `+requests+`=`+limits+` for +the container in the Pod. This will ensure that the container will not +be killed if another Pod requests resources. + +It is a best practice to implement CPU and memory limits for all +containers as it prevents a container inadvertently consuming system +resources impacting the availability of other co-located processes. + +=== Configure and Size Resource Requests/Limits for all Workloads + +Some general guidance can be applied to sizing resource requests and +limits for workloads: + +* Do not specify resource limits on CPU. In the absence of limits, the +request acts as a weight on +https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#how-pods-with-resource-limits-are-run[how +much relative CPU time containers get]. This allows your workloads to +use the full CPU without an artificial limit or starvation. +* For non-CPU resources, configuring `+requests+`=`+limits+` provides +the most predictable behavior. If `+requests+`!=`+limits+`, the +container also has its +https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#qos-classes[QOS] +reduced from Guaranteed to Burstable making it more likely to be evicted +in the event of +https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/[node +pressure]. +* For non-CPU resources, do not specify a limit that is much larger than +the request. The larger `+limits+` are configured relative to +`+requests+`, the more likely nodes will be overcommitted leading to +high chances of workload interruption. +* Correctly sized requests are particularly important when using a node +auto-scaling solution like +https://aws.github.io/aws-eks-best-practices/karpenter/[Karpenter] or +https://aws.github.io/aws-eks-best-practices/cluster-autoscaling/[Cluster +AutoScaler]. These tools look at your workload requests to determine the +number and size of nodes to be provisioned. If your requests are too +small with larger limits, you may find your workloads evicted or OOM +killed if they have been tightly packed on a node. + +Determining resource requests can be difficult, but tools like the +https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler[Vertical +Pod Autoscaler] can help you '`right-size`' the requests by observing +container resource usage at runtime. Other tools that may be useful for +determining request sizes include: + +* https://github.com/FairwindsOps/goldilocks[Goldilocks] +* https://www.parca.dev/[Parca] +* https://prodfiler.com/[Prodfiler] +* https://mhausenblas.info/right-size-guide/[rsg] + +=== Configure resource quotas for namespaces + +Namespaces are intended for use in environments with many users spread +across multiple teams, or projects. They provide a scope for names and +are a way to divide cluster resources between multiple teams, projects, +workloads. You can limit the aggregate resource consumption in a +namespace. The +https://kubernetes.io/docs/concepts/policy/resource-quotas/[`+ResourceQuota+`] +object can limit the quantity of objects that can be created in a +namespace by type, as well as the total amount of compute resources that +may be consumed by resources in that project. You can limit the total +sum of storage and/or compute (CPU and memory) resources that can be +requested in a given namespace. + +____ +If resource quota is enabled for a namespace for compute resources like +CPU and memory, users must specify requests or limits for each container +in that namespace. +____ + +Consider configuring quotas for each namespace. Consider using +`+LimitRanges+` to automatically apply preconfigured limits to +containers within a namespaces. + +=== Limit container resource usage within a namespace + +Resource Quotas help limit the amount of resources a namespace can use. +The +https://kubernetes.io/docs/concepts/policy/limit-range/[`+LimitRange+` +object] can help you implement minimum and maximum resources a container +can request. Using `+LimitRange+` you can set a default request and +limits for containers, which is helpful if setting compute resource +limits is not a standard practice in your organization. As the name +suggests, `+LimitRange+` can enforce minimum and maximum compute +resources usage per Pod or Container in a namespace. As well as, enforce +minimum and maximum storage request per PersistentVolumeClaim in a +namespace. + +Consider using `+LimitRange+` in conjunction with `+ResourceQuota+` to +enforce limits at a container as well as namespace level. Setting these +limits will ensure that a container or a namespace does not impinge on +resources used by other tenants in the cluster. + +== CoreDNS + +CoreDNS fulfills name resolution and service discovery functions in +Kubernetes. It is installed by default on EKS clusters. For +interoperability, the Kubernetes Service for CoreDNS is still named +https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/[kube-dns]. +CoreDNS Pods run as part of a Deployment in `+kube-system+` namespace, +and in EKS, by default, it runs two replicas with declared requests and +limits. DNS queries are sent to the `+kube-dns+` Service that runs in +the `+kube-system+` Namespace. + +== Recommendations + +=== Monitor CoreDNS metrics + +CoreDNS has built in support for +https://github.com/coredns/coredns/tree/master/plugin/metrics[Prometheus]. +You should especially consider monitoring CoreDNS latency +(`+coredns_dns_request_duration_seconds_sum+`, before +https://github.com/coredns/coredns/blob/master/notes/coredns-1.7.0.md[1.7.0] +version the metric was called `+core_dns_response_rcode_count_total+`), +errors (`+coredns_dns_responses_total+`, NXDOMAIN, SERVFAIL, FormErr) +and CoreDNS Pod’s memory consumption. + +For troubleshooting purposes, you can use kubectl to view CoreDNS logs: + +[source,shell] +---- +for p in $(kubectl get pods -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[*].metadata.name}'); do kubectl logs $p -n kube-system; done +---- + +=== Use NodeLocal DNSCache + +You can improve the Cluster DNS performance by running +https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/[NodeLocal +DNSCache]. This feature runs a DNS caching agent on cluster nodes as a +DaemonSet. All the pods use the DNS caching agent running on the node +for name resolution instead of using `+kube-dns+` Service. + +=== Configure cluster-proportional-scaler for CoreDNS + +Another method of improving Cluster DNS performance is by +https://kubernetes.io/docs/tasks/administer-cluster/dns-horizontal-autoscaling/#enablng-dns-horizontal-autoscaling[automatically +horizontally scaling the CoreDNS Deployment] based on the number of +nodes and CPU cores in the cluster. +https://github.com/kubernetes-sigs/cluster-proportional-autoscaler/blob/master/README.md[Horizontal +cluster-proportional-autoscaler] is a container that resizes the number +of replicas of a Deployment based on the size of the schedulable +data-plane. + +Nodes and the aggregate of CPU cores in the nodes are the two metrics +with which you can scale CoreDNS. You can use both metrics +simultaneously. If you use larger nodes, CoreDNS scaling is based on the +number of CPU cores. Whereas, if you use smaller nodes, the number of +CoreDNS replicas depends on the CPU cores in your data-plane. +Proportional autoscaler configuration looks like this: + +.... +linear: '{"coresPerReplica":256,"min":1,"nodesPerReplica":16}' +.... + +=== Choosing an AMI with Node Group + +EKS provides optimized EC2 AMIs that are used by customers to create +both self-managed and managed nodegroups. These AMIs are published in +every region for every supported Kubernetes version. EKS marks these +AMIs as deprecated when any CVEs or bugs are discovered. Hence, the +recommendation is not to consume deprecated AMIs while choosing an AMI +for the node group. + +Deprecated AMIs can be filtered using Ec2 describe-images api using +below command: + +.... +aws ec2 describe-images --image-id ami-0d551c4f633e7679c --no-include-deprecated +.... + +You can also recognize a deprecated AMI by verifying if the +describe-image output contains a DeprecationTime as a field. For ex: + +.... +aws ec2 describe-images --image-id ami-xxx --no-include-deprecated +{ + "Images": [ + { + "Architecture": "x86_64", + "CreationDate": "2022-07-13T15:54:06.000Z", + "ImageId": "ami-xxx", + "ImageLocation": "123456789012/eks_xxx", + "ImageType": "machine", + "Public": false, + "OwnerId": "123456789012", + "PlatformDetails": "Linux/UNIX", + "UsageOperation": "RunInstances", + "State": "available", + "BlockDeviceMappings": [ + { + "DeviceName": "/dev/xvda", + "Ebs": { + "DeleteOnTermination": true, + "SnapshotId": "snap-0993a2fc4bbf4f7f4", + "VolumeSize": 20, + "VolumeType": "gp2", + "Encrypted": false + } + } + ], + "Description": "EKS Kubernetes Worker AMI with AmazonLinux2 image, (k8s: 1.19.15, docker: 20.10.13-2.amzn2, containerd: 1.4.13-3.amzn2)", + "EnaSupport": true, + "Hypervisor": "xen", + "Name": "aws_eks_optimized_xxx", + "RootDeviceName": "/dev/xvda", + "RootDeviceType": "ebs", + "SriovNetSupport": "simple", + "VirtualizationType": "hvm", + "DeprecationTime": "2023-02-09T19:41:00.000Z" + } + ] +} +.... diff --git a/latest/bpg/reliability/images b/latest/bpg/reliability/images new file mode 120000 index 000000000..5e6757319 --- /dev/null +++ b/latest/bpg/reliability/images @@ -0,0 +1 @@ +../images \ No newline at end of file diff --git a/latest/bpg/reliability/index.adoc b/latest/bpg/reliability/index.adoc new file mode 100644 index 000000000..6ff54bbb0 --- /dev/null +++ b/latest/bpg/reliability/index.adoc @@ -0,0 +1,137 @@ +//!!NODE_ROOT +[[reliability,reliability.title]] += Amazon EKS Best Practices Guide for Reliability +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Best Practices for Reliability +:info_abstract: Best Practices for Reliability +:info_titleabbrev: Reliability +:imagesdir: images/ + + + +:imagesdir: images/ + +This section provides guidance about making workloads running on EKS +resilient and highly-available + +== How to use this guide + +This guide is meant for developers and architects who want to develop +and operate highly-available and fault-tolerant services in EKS. The +guide is organized into different topic areas for easier consumption. +Each topic starts with a brief overview, followed by a list of +recommendations and best practices for the reliability of your EKS +clusters. + +== Introduction + +The reliability best practices for EKS have been grouped under the +following topics: + +* Applications +* Control Plane +* Data Plane + +What makes a system reliable? If a system can function consistently and +meet demands in spite of changes in its environment over a period of +time, it can be called reliable. To achieve this, the system has to +detect failures, automatically heal itself, and have the ability to +scale based on demand. + +Customers can use Kubernetes as a foundation to operate mission-critical +applications and services reliably. But aside from incorporating +container-based application design principles, running workloads +reliably also requires a reliable infrastructure. In Kubernetes, +infrastructure comprises the control plane and data plane. + +EKS provides a production-grade Kubernetes control plane that is +designed to be highly-available and fault-tolerant. + +In EKS, AWS is responsible for the reliability of the Kubernetes control +plane. EKS runs Kubernetes control plane across three availability zones +in an AWS Region. It automatically manages the availability and +scalability of the Kubernetes API servers and the etcd cluster. + +The responsibility for the data plane’s reliability is shared between +you, the customer, and AWS. EKS offers three options for Kubernetes data +plane. Fargate, which is the most managed option, handles provisioning +and scaling of the data plane. The second option, managed nodes groups, +handles provisioning, and updates of the data plane. And finally, +self-managed nodes is the least managed option for the data plane. The +more AWS-managed data plane you use, the less responsibility you have + +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[Managed +node groups] automate the provisioning and lifecycle management of EC2 +nodes. You can use the EKS API (using EKS console, AWS API, AWS CLI, +CloudFormation, Terraform, or `eksctl`), to create, scale, and upgrade +managed nodes. Managed nodes run EKS-optimized Amazon Linux 2 EC2 +instances in your account, and you can install custom software packages +by enabling SSH access. When you provision managed nodes, they run as +part of an EKS-managed Auto Scaling Group that can span multiple +Availability Zones; you control this through the subnets you provide +when creating managed nodes. EKS also automatically tags managed nodes +so they can be used with Cluster Autoscaler. + +____ +Amazon EKS follows the shared responsibility model for CVEs and security +patches on managed node groups. Because managed nodes run the Amazon +EKS-optimized AMIs, Amazon EKS is responsible for building patched +versions of these AMIs when bug fixes. However, you are responsible for +deploying these patched AMI versions to your managed node groups. +____ + +EKS also +https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html[manages +updating the nodes] although you have to initiate the update process. +The process of +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-update-behavior.html[updating +managed node] is explained in the EKS documentation. + +If you run self-managed nodes, you can use +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[Amazon +EKS-optimized Linux AMI] to create worker nodes. You are responsible for +patching and upgrading the AMI and the nodes. It is a best practice to +use `+eksctl+`, CloudFormation, or infrastructure as code tools to +provision self-managed nodes because this will make it easy for you to +https://docs.aws.amazon.com/eks/latest/userguide/update-workers.html[upgrade +self-managed nodes]. Consider +https://docs.aws.amazon.com/eks/latest/userguide/migrate-stack.html[migrating +to new nodes] when updating worker nodes because the migration process +*taints* the old node group as `+NoSchedule+` and *drains* the nodes +after a new stack is ready to accept the existing pod workload. However, +you can also perform an +https://docs.aws.amazon.com/eks/latest/userguide/update-stack.html[in-place +upgrade of self-managed nodes]. + +.Shared Responsibility Model - Fargate +image::reliability_SRM-Fargate.jpeg[Shared Responsibility Model - Fargate] + +.Shared Responsibility Model - MNG +image::reliability_SRM-MNG.jpeg[Shared Responsibility Model - MNG] + +This guide includes a set of recommendations that you can use to improve +the reliability of your EKS data plane, Kubernetes core components, and +your applications. + +== Feedback + +This guide is being released on GitHub to collect direct feedback and +suggestions from the broader EKS/Kubernetes community. If you have a +best practice that you feel we ought to include in the guide, please +file an issue or submit a PR in the GitHub repository. We intend to +update the guide periodically as new features are added to the service +or when a new best practice evolves. + +include::application.adoc[leveloffset=+1] + +include::controlplane.adoc[leveloffset=+1] + +include::dataplane.adoc[leveloffset=+1] From 1c77d2e79b7d8b89046b00a0535c1e9b93be2ea2 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 26 Jun 2024 22:02:49 +0000 Subject: [PATCH 07/56] copy security section to adoc --- content/security/docs/compliance.ko.md | 54 - content/security/docs/data.ko.md | 125 -- content/security/docs/detective.ko.md | 278 ----- content/security/docs/hosts.ko.md | 193 --- content/security/docs/iam.ko.md | 501 -------- content/security/docs/image.ko.md | 234 ---- content/security/docs/incidents.ko.md | 145 --- content/security/docs/index.ko.md | 53 - content/security/docs/multitenancy.ko.md | 329 ----- content/security/docs/network.ko.md | 548 --------- content/security/docs/pods.ko.md | 466 ------- content/security/docs/runtime.ko.md | 77 -- latest/bpg/security/compliance.adoc | 142 +++ latest/bpg/security/data.adoc | 246 ++++ latest/bpg/security/detective.adoc | 351 ++++++ latest/bpg/security/hosts.adoc | 357 ++++++ latest/bpg/security/iam.adoc | 1435 ++++++++++++++++++++++ latest/bpg/security/image.adoc | 500 ++++++++ latest/bpg/security/incidents.adoc | 248 ++++ latest/bpg/security/index.adoc | 127 ++ latest/bpg/security/multiaccount.adoc | 422 +++++++ latest/bpg/security/multitenancy.adoc | 630 ++++++++++ latest/bpg/security/network.adoc | 971 +++++++++++++++ latest/bpg/security/pods.adoc | 828 +++++++++++++ latest/bpg/security/runtime.adoc | 216 ++++ 25 files changed, 6473 insertions(+), 3003 deletions(-) delete mode 100644 content/security/docs/compliance.ko.md delete mode 100644 content/security/docs/data.ko.md delete mode 100644 content/security/docs/detective.ko.md delete mode 100644 content/security/docs/hosts.ko.md delete mode 100644 content/security/docs/iam.ko.md delete mode 100644 content/security/docs/image.ko.md delete mode 100644 content/security/docs/incidents.ko.md delete mode 100644 content/security/docs/index.ko.md delete mode 100644 content/security/docs/multitenancy.ko.md delete mode 100644 content/security/docs/network.ko.md delete mode 100644 content/security/docs/pods.ko.md delete mode 100644 content/security/docs/runtime.ko.md create mode 100644 latest/bpg/security/compliance.adoc create mode 100644 latest/bpg/security/data.adoc create mode 100644 latest/bpg/security/detective.adoc create mode 100644 latest/bpg/security/hosts.adoc create mode 100644 latest/bpg/security/iam.adoc create mode 100644 latest/bpg/security/image.adoc create mode 100644 latest/bpg/security/incidents.adoc create mode 100644 latest/bpg/security/index.adoc create mode 100644 latest/bpg/security/multiaccount.adoc create mode 100644 latest/bpg/security/multitenancy.adoc create mode 100644 latest/bpg/security/network.adoc create mode 100644 latest/bpg/security/pods.adoc create mode 100644 latest/bpg/security/runtime.adoc diff --git a/content/security/docs/compliance.ko.md b/content/security/docs/compliance.ko.md deleted file mode 100644 index ddcd70714..000000000 --- a/content/security/docs/compliance.ko.md +++ /dev/null @@ -1,54 +0,0 @@ -# 컴플라이언스 - -컴플라이언스는 AWS와 해당 서비스 소비자 간의 공동 책임입니다. 일반적으로 AWS는 "클라우드의 보안"을 책임지고, 사용자는 "클라우드에서의 보안"을 담당합니다. AWS와 해당 사용자가 책임져야 할 책임을 설명하는 선은 서비스에 따라 달라집니다. 예를 들어 Fargate를 통해 AWS는 데이터 센터, 하드웨어, 가상 인프라(Amazon EC2) 및 컨테이너 런타임(Docker)의 물리적 보안을 관리할 책임이 있습니다. Fargate 사용자는 컨테이너 이미지와 해당 애플리케이션을 보호할 책임이 있습니다. 컴플라이언스 표준을 준수해야 하는 워크로드를 실행할 때 고려해야 할 중요한 사항은 누구의 책임자인지 파악하는 것입니다. - -다음 표는 다양한 컨테이너 서비스가 준수하는 규정 준수 프로그램을 보여줍니다. - -| 컴플라이언스 프로그램 | Amazon ECS 오케스트레이터 | Amazon EKS 오케스트레이터| ECS Fargete | 아마존 ECR | -| --- |:----------:|:----------:|:---- -------:|:----------:| -| PCI DSS Level 1 | 1 | 1 | 1 | 1 | -| HIPAA Eligible | 1 | 1 | 1 | 1 | -| SOC I | 1 | 1 | 1 | 1 | -| SOC II | 1 | 1 | 1 | 1 | -| SOC III | 1 | 1 | 1 | 1 | -| ISO 27001:2013 | 1 | 1 | 1 | 1 | -| ISO 9001:2015 | 1 | 1 | 1 | 1 | -| ISO 27017:2015 | 1 | 1 | 1 | 1 | -| ISO 27018:2019 | 1 | 1 | 1 | 1 | -| IRAP | 1 | 1 | 1 | 1 | -| FedRAMP Moderate (East/West) | 1 | 1 | 0 | 1 | -| FedRAMP High (GovCloud) | 1 | 1 | 0 | 1 | -| DOD CC SRG | 1 | DISA Review (IL5) | 0 | 1 | -| HIPAA BAA | 1 | 1 | 1 | 1 | -| MTCS | 1 | 1 | 0 | 1 | -| C5 | 1 | 1 | 0 | 1 | -| K-ISMS | 1 | 1 | 0 | 1 | -| ENS High | 1 | 1 | 0 | 1 | -| OSPAR | 1 | 1 | 0 | 1 | -| HITRUST CSF | 1 | 1 | 1 | 1 | - -컴플라이언스 상태는 시간이 지남에 따라 변경됩니다. 최신 상태는 항상 [https://aws.amazon.com/compliance/services-in-scope/](https://aws.amazon.com/compliance/services-in-scope/)를 참조하십시오. - -클라우드 인증 모델 및 모범 사례에 대한 자세한 내용은 AWS 백서인 [안전한 클라우드 채택을 위한 인증 모델](https://d1.awsstatic.com/whitepapers/accreditation-models-for-secure-cloud-adoption.pdf)을 참조하십시오. - -## 시프트 레프트(Shift Left) - -시프트 레프트 개념은 소프트웨어 개발 수명 주기 초기에 정책 위반 및 오류를 포착하는 것이 포함됩니다. 보안 관점에서 이것은 매우 유익할 수 있습니다. 예를 들어 개발자는 애플리케이션을 클러스터에 배포하기 전에 구성 문제를 수정할 수 있습니다. 이와 같은 실수를 조기에 포착하면 정책을 위반하는 구성이 배포되는 것을 방지할 수 있습니다. - -### 코드로서의 정책 (PaC, Policy as Code) - -정책은 행동, 즉 허용된 행동 또는 금지된 행동을 규제하기 위한 일련의 규칙으로 생각할 수 있습니다. 예를 들어 모든 Dockerfile에는 컨테이너를 루트 사용자가 아닌 사용자로 실행하도록 하는 USER 지시문이 포함되어야 한다는 정책이 있을 수 있습니다. 문서로서 이와 같은 정책은 발견하고 적용하기 어려울 수 있습니다. 요구 사항이 변경됨에 따라 이 정책이 시대에 뒤처질 수도 있습니다. PaC 솔루션을 사용하면 알려진 위협과 지속적인 위협을 탐지, 예방, 감소 및 대응하는 보안, 규정 준수 및 개인 정보 보호 제어를 자동화할 수 있습니다. 또한 정책을 체계화하고 다른 코드 아티팩트와 마찬가지로 관리할 수 있는 메커니즘을 제공합니다. 이 접근 방식의 이점은 DevOps 및 GitOps 전략을 재사용하여 Kubernetes 클러스터 전체에 정책을 관리하고 일관되게 적용할 수 있다는 것입니다. PAC 옵션과 PSP의 미래에 대한 자세한 내용은 [파드 보안](https://aws.github.io/aws-eks-best-practices/security/docs/pods/#pod-security)을 참조하십시오. - -### 파이프라인에서 PaC 도구를 사용하여 배포 전에 위반 감지 - -+ [OPA](https://www.openpolicyagent.org/)는 CNCF의 일부인 오픈 소스 정책 엔진입니다. 정책 결정을 내리는 데 사용되며 언어 라이브러리 또는 서비스 등 다양한 방식으로 실행할 수 있습니다. OPA 정책은 Rego라는 도메인 특정 언어(DSL)로 작성됩니다. OPA는 쿠버네티스 동적 어드미션 컨트롤러의 일부로 [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) 프로젝트로 실행되는 경우가 많지만, OPA는 CI/CD 파이프라인에 통합될 수도 있습니다. 이를 통해 개발자는 릴리스 주기 초기에 구성에 대한 피드백을 받을 수 있으며, 이를 통해 프로덕션에 들어가기 전에 문제를 해결하는 데 도움이 될 수 있습니다. 일반적인 OPA 정책 모음은 이 프로젝트의 GitHub [리포지토리](https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa)에서 찾을 수 있습니다. -+ [Conftest](https://github.com/open-policy-agent/conftest)는 OPA를 기반으로 구축되었으며 쿠버네티스 구성을 테스트하기 위한 개발자 중심의 경험을 제공합니다. -+ [Kyverno](https://kyverno.io/)는 쿠버네티스용으로 설계된 정책 엔진입니다.Kyverno를 사용하면 정책이 쿠버네티스 리소스로 관리되므로 정책을 작성하는 데 새로운 언어가 필요하지 않습니다. 이를 통해 kubectl, git, kustomize와 같은 친숙한 도구를 사용하여 정책을 관리할 수 있습니다. Kyverno 정책은 Kubernetes 리소스를 검증, 변경 및 생성하고 OCI 이미지 공급망 보안을 보장할 수 있습니다. [Kyverno CLI](https://kyverno.io/docs/kyverno-cli/)는 CI/CD 파이프라인의 일부로 정책을 테스트하고 리소스를 검증하는 데 사용할 수 있습니다. 모든 Kyverno 커뮤니티 정책은 [Kyverno 웹 사이트](https://kyverno.io/policies/)에서 확인할 수 있으며, Kyverno CLI를 사용하여 파이프라인에서 테스트를 작성하는 예는 [정책 리포지토리](https://github.com/kyverno/policies)를 참조하십시오. - -## 도구 및 리소스 - -+ [Amazon EKS Security Immersion Workshop - Regulatory Compliance](https://catalog.workshops.aws/eks-security-immersionday/en-US/10-regulatory-compliance) -+ [kube-bench](https://github.com/aquasecurity/kube-bench) -+ [docker-bench-security](https://github.com/docker/docker-bench-security) -+ [AWS Inspector](https://aws.amazon.com/inspector/) -+ [Kubernetes Security Review](https://github.com/kubernetes/community/blob/master/sig-security/security-audit-2019/findings/Kubernetes%20Final%20Report.pdf) 쿠버네티스 버전 1.13.4에 대한 서드파티 보안 평가(2019) diff --git a/content/security/docs/data.ko.md b/content/security/docs/data.ko.md deleted file mode 100644 index 4f9ace736..000000000 --- a/content/security/docs/data.ko.md +++ /dev/null @@ -1,125 +0,0 @@ -# 데이터 암호화 및 시크릿 관리 - -## 저장 시 암호화 - -쿠버네티스와 함께 사용할 수 있는 AWS 네이티브 스토리지 옵션은 [EBS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html), [EFS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html), [FSx for Lustre](https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html)등 세 가지가 있습니다. 세 가지 모두 서비스 관리 키 또는 고객 관리 키 (CMK)를 사용하여 저장 시 암호화를 제공합니다. EBS의 경우 인트리 스토리지 드라이버 또는 [EBS CSI드라이버](https://github.com/kubernetes-sigs/aws-ebs-csi-driver)를 사용할 수 있습니다.둘 다 볼륨 암호화 및 CMK 제공을 위한 파라미터를 포함합니다. EFS의 경우 [EFS CSI 드라이버](https://github.com/kubernetes-sigs/aws-efs-csi-driver)를 사용할 수 있지만 EBS와 달리 EFS CSI 드라이버는 동적 프로비저닝을 지원하지 않습니다. EKS와 함께 EFS를 사용하려면 PV를 생성하기 전에 파일 시스템에 대한 저장 중 암호화를 프로비저닝하고 구성해야 합니다. EFS 파일 암호화에 대한 자세한 내용은 [저장 데이터 암호화](https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html)를 참조합니다. EFS와 FSx for Lustre에는 저장 시 암호화를 제공하는 것 외에도 전송 데이터를 암호화하는 옵션이 포함되어 있습니다. FSx for Luster는 기본적으로 이 작업을 수행합니다. EFS의 경우 다음 예와 같이 PV의 `MountOptions`에 `tls` 파라미터를 추가하여 전송 암호화를 추가할 수 있습니다: - -```yaml -apiVersion: v1 -kind: PersistentVolume -metadata: - name: efs-pv -spec: - capacity: - storage: 5Gi - volumeMode: Filesystem - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain - storageClassName: efs-sc - mountOptions: - - tls - csi: - driver: efs.csi.aws.com - volumeHandle: -``` - -[FSx CSI 드라이버](https://github.com/kubernetes-sigs/aws-fsx-csi-driver)는 Lustre 파일 시스템의 동적 프로비저닝을 지원합니다. 기본적으로 서비스 관리 키를 사용하여 데이터를 암호화하지만, 다음 예와 같이 자체 CMK를 제공하는 옵션이 있습니다: - -```yaml -kind: StorageClass -apiVersion: storage.k8s.io/v1 -metadata: - name: fsx-sc -provisioner: fsx.csi.aws.com -parameters: - subnetId: subnet-056da83524edbe641 - securityGroupIds: sg-086f61ea73388fb6b - deploymentType: PERSISTENT_1 - kmsKeyId: -``` - -!!! attention - 2020년 5월 28일부터 EKS Fargate 파드의 임시 볼륨에 기록되는 모든 데이터는 업계 표준 AES-256 암호화 알고리즘을 사용하여 기본적으로 암호화됩니다. 서비스에서 암호화 및 복호화를 원활하게 처리하므로 애플리케이션을 수정할 필요가 없습니다. - -### 저장된 데이터 암호화 - -저장된 데이터를 암호화하는 것은 모범 사례로 간주됩니다. 암호화가 필요한지 확실하지 않은 경우 데이터를 암호화하세요. - -### CMK를 주기적으로 교체하세요 - -CMK를 자동으로 교체하도록 KMS를 구성합니다. 이렇게 하면 1년에 한 번 키가 교체되고 이전 키는 무기한 저장되므로 데이터를 계속 해독할 수 있습니다. 자세한 내용은 [고객 마스터 키 교체 문서](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html)를 참조합니다. - -### EFS 액세스 포인트를 사용하여 공유 데이터세트에 대한 액세스를 간소화합니다 - -서로 다른 POSIX 파일 권한으로 데이터 세트를 공유했거나 다른 마운트 지점을 생성하여 공유 파일 시스템의 일부에 대한 액세스를 제한하려는 경우 EFS 액세스 포인트를 사용하는 것이 좋습니다. 액세스 포인트 사용에 대한 자세한 내용은 [AWS 문서](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html)를 참조합니다. 현재 액세스 포인트(AP)를 사용하려면 PV의 `VolumeHandle` 파라미터에서 AP를 참조해야 합니다. - -!!! attention - 2021년 3월 23일부터 EFS CSI 드라이버는 EFS 액세스 포인트의 동적 프로비저닝을 지원합니다. 액세스 포인트는 여러 파드 간에 파일 시스템을 쉽게 공유할 수 있게 해주는 EFS 파일 시스템의 애플리케이션 별 진입점입니다. 각 EFS 파일 시스템에는 최대 120개의 PV가 있을 수 있습니다. 자세한 내용은 [Amazon EFS CSI 동적 프로비저닝 소개](https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/)를 참조하십시오. - -## 시크릿 관리 - -쿠버네티스 시크릿은 사용자 인증서, 암호 또는 API 키와 같은 민감한 정보를 저장하는 데 사용됩니다. 이들은 etcd에 base64로 인코딩된 문자열로 유지됩니다. EKS에서는 etcd 노드의 EBS 볼륨이 [EBS 암호화](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html)로 암호화됩니다. 파드는 `PodSpec`의 시크릿을 참조하여 쿠버네티스 시크릿 객체를 검색할 수 있습니다. 이런 시크릿은 환경 변수에 매핑하거나 볼륨으로 마운트할 수 있습니다. 시크릿 생성에 대한 자세한 내용은 [쿠버네티스 문서](https://kubernetes.io/docs/concepts/configuration/secret/)를 참조하십시오. - -!!! caution - 특정 네임스페이스의 시크릿은 네임스페이스의 모든 파드에서 참조할 수 있습니다. - -!!! caution - 노드 권한 부여자는 Kubelet이 노드에 마운트된 모든 시크릿을 읽을 수 있도록 허용합니다. - -### 쿠버네티스 시크릿 봉투 암호화에 AWS KMS 사용 - -이를 통해 고유한 DEK(데이터 암호화 키)으로 시크릿을 암호화할 수 있습니다. 그런 다음 DEK는 AWS KMS의 KEK (키 암호화 키) 를 사용하여 암호화되며, 이 KEK (키 암호화 키) 는 반복 일정에 따라 자동으로 교체될 수 있습니다. 쿠버네티스용 KMS 플러그인을 사용하면 모든 쿠버네티스 암호가 일반 텍스트 대신 암호문의 etcd에 저장되며 쿠버네티스 API 서버에서만 해독할 수 있습니다. -자세한 내용은 [심층 방어를 위한 EKS 암호화 공급자 지원 사용 블로그](https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/)을 참조하십시오. - -### 쿠버네티스 시크릿 사용 감사 - -EKS에서 감사 로깅을 켜고 CloudWatch 지표 필터 및 알람을 생성하여 시크릿이 사용될 때 알림을 보냅니다 (선택 사항). 다음은 쿠버네티스 감사 로그에 대한 메트릭 필터의 예시입니다, `{($.verb="get") && ($.ObjectRef.resource="Secret")}`. CloudWatch Log Insights에서는 다음 쿼리를 사용할 수도 있습니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| stats count(*) by objectRef.name as secret -| filter verb="get" and objectRef.resource="secrets" -``` - -위 쿼리는 특정 기간 내에 시크릿에 액세스한 횟수를 표시합니다. - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter verb="get" and objectRef.resource="secrets" -| display objectRef.namespace, objectRef.name, user.username, responseStatus.code -``` - -이 쿼리에는 시크릿에 액세스하려고 시도한 사용자의 네임스페이스 및 사용자 이름 및 응답 코드와 함께 시크릿이 표시됩니다. - -### 주기적으로 시크릿 교체하기 - -쿠버네티스는 시크릿을 자동으로 교체하지 않습니다. 암호를 교체해야 하는 경우 Vault 또는 AWS Secrets Manager와 같은 외부 암호 저장소를 사용하는 것이 좋습니다. - -### 다른 애플리케이션으로부터 시크릿을 분리하는 방법으로 별도의 네임스페이스를 사용하십시오 - -네임스페이스의 애플리케이션 간에 공유할 수 없는 시크릿이 있는 경우 해당 애플리케이션에 대해 별도의 네임스페이스를 생성하십시오. - -### 환경 변수 대신 볼륨 마운트 사용 - -환경 변수 값이 실수로 로그에 나타날 수 있습니다. 볼륨으로 마운트된 시크릿은 tmpfs 볼륨(RAM 백업 파일 시스템)으로 인스턴스화되며, 파드가 삭제되면 노드에서 자동으로 제거됩니다. - -### 외부 시크릿 제공자 사용 - -[AWS Secret Manager](https://aws.amazon.com/secrets-manager/)와 Hishcorp의 [Vault](https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar/)를 포함하여 쿠버네티스 시크릿을 사용할 수 있는 몇 가지 실행 가능한 대안이 있습니다. 이런 서비스는 쿠버네티스 시크릿에서는 사용할 수 없는 세밀한 액세스 제어, 강력한 암호화, 암호 자동 교체 등의 기능을 제공합니다. Bitnami의 [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)는 비대칭 암호화를 사용하여 "봉인된 시크릿"을 생성하는 또 다른 접근 방식입니다. 공개 키는 시크릿을 암호화하는 데 사용되는 반면 암호 해독에 사용된 개인 키는 클러스터 내에 보관되므로 Git과 같은 소스 제어 시스템에 봉인된 시크릿을 안전하게 저장할 수 있습니다. 자세한 내용은 [실드 시크릿을 사용한 쿠버네티스의 시크릿 배포 관리](https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/)를 참조합니다. - -외부 시크릿 스토어의 사용이 증가함에 따라 이를 쿠버네티스와 통합해야 할 필요성도 커졌습니다. [Secret Store CSI 드라이버](https://github.com/kubernetes-sigs/secrets-store-csi-driver)는 CSI 드라이버 모델을 사용하여 외부 시크릿 스토어로부터 시크릿을 가져오는 커뮤니티 프로젝트입니다. 현재 이 드라이버는 [AWS Secret Manager](https://github.com/aws/secrets-store-csi-driver-provider-aws), Azure, Vault 및 GCP를 지원합니다. AWS 공급자는 AWS 시크릿 관리자**와** AWS 파라미터 스토어를 모두 지원합니다. 또한 암호가 만료되면 암호가 교체되도록 구성할 수 있으며, AWS Secrets Manager 암호를 쿠버네티스 암호와 동기화할 수 있습니다. 암호의 동기화는 볼륨에서 암호를 읽는 대신 암호를 환경 변수로 참조해야 할 때 유용할 수 있습니다. - -!!! note - 시크릿 스토어 CSI 드라이버는 시크릿을 가져와야 하는 경우 시크릿을 참조하는 파드에 할당된 IRSA 역할을 사용합니다. 이 작업의 코드는 [Github](https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go)에서 찾을 수 있습니다. - -AWS 보안 및 설정 공급자(ASCP) 에 대한 추가 정보는 다음 리소스를 참조하십시오: - -- [쿠버네티스 시크릿 스토어 CSI 드라이버와 함께 AWS 보안 및 설정 공급자를 사용하는 방법](https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-configuration-provider-with-kubernetes-secrets-store-csi-driver/) -- [Secret manager 시크릿을 쿠버네티스 시크릿 스토어 CSI 드라이버와 통합](https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_csi_driver.html) - -[external-secrets](https://github.com/external-secrets/kubernetes-external-secrets)는 쿠버네티스와 함께 외부 시크릿 저장소를 사용하는 또 다른 방법입니다. CSI 드라이버와 마찬가지로 외부 시크릿은 AWS Secrets Manager를 비롯한 다양한 백엔드에서 작동합니다. 차이점은 외부 시크릿이 외부 시크릿 스토어에서 시크릿을 검색하는 대신 이런 백엔드의 시크릿을 시크릿으로 Kubernetes에 복사한다는 점입니다. 이를 통해 선호하는 시크릿 스토어를 사용하여 시크릿을 관리하고 쿠버네티스 네이티브 방식으로 시크릿과 상호작용할 수 있다. diff --git a/content/security/docs/detective.ko.md b/content/security/docs/detective.ko.md deleted file mode 100644 index a1a84e8bf..000000000 --- a/content/security/docs/detective.ko.md +++ /dev/null @@ -1,278 +0,0 @@ -# 감사(Audit) 및 로깅 - -\[감사\] 로그를 수집하고 분석하는 것은 여러 가지 이유로 유용합니다. 로그는 근본 원인 분석(RCA) 및 책임 분석(예: 특정 변경에 대한 사용자 추적)에 도움이 될 수 있습니다. 로그가 충분히 수집되면 이를 사용하여 이상 행동을 탐지할 수도 있습니다. EKS에서는 감사 로그가 Amazon Cloudwatch 로그로 전송됩니다. EKS의 감사 정책은 다음과 같습니다. - -```yaml -apiVersion: audit.k8s.io/v1beta1 -kind: Policy -rules: - # Log aws-auth configmap changes - - level: RequestResponse - namespaces: ["kube-system"] - verbs: ["update", "patch", "delete"] - resources: - - group: "" # core - resources: ["configmaps"] - resourceNames: ["aws-auth"] - omitStages: - - "RequestReceived" - - level: None - users: ["system:kube-proxy"] - verbs: ["watch"] - resources: - - group: "" # core - resources: ["endpoints", "services", "services/status"] - - level: None - users: ["kubelet"] # legacy kubelet identity - verbs: ["get"] - resources: - - group: "" # core - resources: ["nodes", "nodes/status"] - - level: None - userGroups: ["system:nodes"] - verbs: ["get"] - resources: - - group: "" # core - resources: ["nodes", "nodes/status"] - - level: None - users: - - system:kube-controller-manager - - system:kube-scheduler - - system:serviceaccount:kube-system:endpoint-controller - verbs: ["get", "update"] - namespaces: ["kube-system"] - resources: - - group: "" # core - resources: ["endpoints"] - - level: None - users: ["system:apiserver"] - verbs: ["get"] - resources: - - group: "" # core - resources: ["namespaces", "namespaces/status", "namespaces/finalize"] - - level: None - users: - - system:kube-controller-manager - verbs: ["get", "list"] - resources: - - group: "metrics.k8s.io" - - level: None - nonResourceURLs: - - /healthz* - - /version - - /swagger* - - level: None - resources: - - group: "" # core - resources: ["events"] - - level: Request - users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"] - verbs: ["update","patch"] - resources: - - group: "" # core - resources: ["nodes/status", "pods/status"] - omitStages: - - "RequestReceived" - - level: Request - userGroups: ["system:nodes"] - verbs: ["update","patch"] - resources: - - group: "" # core - resources: ["nodes/status", "pods/status"] - omitStages: - - "RequestReceived" - - level: Request - users: ["system:serviceaccount:kube-system:namespace-controller"] - verbs: ["deletecollection"] - omitStages: - - "RequestReceived" - # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data, - # so only log at the Metadata level. - - level: Metadata - resources: - - group: "" # core - resources: ["secrets", "configmaps"] - - group: authentication.k8s.io - resources: ["tokenreviews"] - omitStages: - - "RequestReceived" - - level: Request - resources: - - group: "" - resources: ["serviceaccounts/token"] - - level: Request - verbs: ["get", "list", "watch"] - resources: - - group: "" # core - - group: "admissionregistration.k8s.io" - - group: "apiextensions.k8s.io" - - group: "apiregistration.k8s.io" - - group: "apps" - - group: "authentication.k8s.io" - - group: "authorization.k8s.io" - - group: "autoscaling" - - group: "batch" - - group: "certificates.k8s.io" - - group: "extensions" - - group: "metrics.k8s.io" - - group: "networking.k8s.io" - - group: "policy" - - group: "rbac.authorization.k8s.io" - - group: "scheduling.k8s.io" - - group: "settings.k8s.io" - - group: "storage.k8s.io" - omitStages: - - "RequestReceived" - # Default level for known APIs - - level: RequestResponse - resources: - - group: "" # core - - group: "admissionregistration.k8s.io" - - group: "apiextensions.k8s.io" - - group: "apiregistration.k8s.io" - - group: "apps" - - group: "authentication.k8s.io" - - group: "authorization.k8s.io" - - group: "autoscaling" - - group: "batch" - - group: "certificates.k8s.io" - - group: "extensions" - - group: "metrics.k8s.io" - - group: "networking.k8s.io" - - group: "policy" - - group: "rbac.authorization.k8s.io" - - group: "scheduling.k8s.io" - - group: "settings.k8s.io" - - group: "storage.k8s.io" - omitStages: - - "RequestReceived" - # Default level for all other requests. - - level: Metadata - omitStages: - - "RequestReceived" -``` - -## 권장 사항 - -### 감사 로그 활성화 - -감사 로그는 EKS에서 관리하는 EKS 관리형 쿠버네티스 컨트롤 플레인 로그의 일부입니다. 쿠버네티스 API 서버, 컨트롤러 관리자 및 스케줄러에 대한 로그와 감사 로그를 포함하는 컨트롤 플레인 로그의 활성화/비활성화 지침은 [AWS 문서](https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export)에서 확인할 수 있습니다. - -!!! info - 컨트롤 플레인 로깅을 활성화하면 로그를 CloudWatch에 저장하는 데 [비용](https://aws.amazon.com/cloudwatch/pricing/)이 발생합니다. 이로 인해 지속적인 보안 비용에 대한 광범위한 문제가 제기됩니다. 궁극적으로 이런 비용을 보안 침해 비용 (예: 재정적 손실, 평판 훼손 등)과 비교해야 합니다. 이 가이드의 권장 사항 중 일부만 구현하면 환경을 적절하게 보호할 수 있을 것입니다. - -!!! warning - 클라우드워치 로그 항목의 최대 크기는 [256KB](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html)인 반면 쿠버네티스 API 요청 최대 크기는 1.5MiB입니다. 256KB를 초과하는 로그 항목은 잘리거나 요청 메타데이터만 포함됩니다. - -### 감사 메타데이터 활용 - -쿠버네티스 감사 로그에는 요청이 승인되었는지 여부를 나타내는 `authorization.k8s.io/decision`와 결정의 이유를 나타내는 `authorization.k8s.io/reason`, 두 개의 어노테이션이 포함되어 있습니다. 이런 속성을 사용하여 특정 API 호출이 허용된 이유를 확인할 수 있습니다. - -### 의심스러운 이벤트에 대한 알람 생성 - -403 Forbidden 및 401 Unauthorized 응답이 증가하는 위치를 자동으로 알리는 경보를 생성한 다음 `host` , `sourceIPs` 및 `k8s_user.username` 과 같은 속성을 사용 하여 이런 요청의 출처를 찾아냅니다. - -### Log Insights로 로그 분석 - -CloudWatch Log Insights를 사용하여 RBAC 객체 (예: 롤, 롤바인딩, 클러스터롤, 클러스터 롤바인딩) 에 대한 변경 사항을 모니터링할 수 있습니다. 몇 가지 샘플 쿼리는 다음과 같습니다. - -`aws-auth` 컨피그맵 에 대한 업데이트를 나열합니다: - -```bash -fields @timestamp, @message -| filter @logStream like "kube-apiserver-audit" -| filter verb in ["update", "patch"] -| filter objectRef.resource = "configmaps" and objectRef.name = "aws-auth" and objectRef.namespace = "kube-system" -| sort @timestamp desc -``` - -Validation 웹훅에 대한 생성 또는 변경 사항을 나열합니다: - -```bash -fields @timestamp, @message -| filter @logStream like "kube-apiserver-audit" -| filter verb in ["create", "update", "patch"] and responseStatus.code = 201 -| filter objectRef.resource = "validatingwebhookconfigurations" -| sort @timestamp desc -``` - -롤에 대한 생성, 업데이트, 삭제 작업을 나열합니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"] -``` - -롤바인딩에 대한 생성, 업데이트, 삭제 작업을 나열합니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"] -``` - -클러스터롤에 대한 생성, 업데이트, 삭제 작업을 나열합니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"] -``` - -클러스터롤바인딩에 대한 생성, 업데이트, 삭제 작업을 나열합니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"] -``` - -시크릿에 대한 무단 읽기 작업을 표시합니다: - -```bash -fields @timestamp, @message -| sort @timestamp desc -| limit 100 -| filter objectRef.resource="secrets" and verb in ["get", "watch", "list"] and responseStatus.code="401" -| stats count() by bin(1m) -``` - -실패한 익명 요청 목록: - -```bash -fields @timestamp, @message, sourceIPs.0 -| sort @timestamp desc -| limit 100 -| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"] -``` - -### CloudTrail 로그 감사 - -IAM Roles for Service Account(IRSA)을 활용하는 파드에서 호출한 AWS API는 서비스 어카운트 이름과 함께 CloudTrail에 자동으로 로깅됩니다. API 호출 권한이 명시적으로 부여되지 않은 서비스 어카운트의 이름이 로그에 표시되면 IAM 역할의 신뢰 정책이 잘못 구성되었다는 표시일 수 있습니다. 일반적으로 Cloudtrail은 AWS API 호출을 특정 IAM 보안 주체에 할당할 수 있는 좋은 방법입니다. - -### CloudTrail Insights를 사용하여 의심스러운 활동 발견 - -CloudTrail Insights는 CloudTrail 트레일에서 쓰기 관리 이벤트를 자동으로 분석하고 비정상적인 활동이 발생하면 알려줍니다. 이를 통해 IRSA 기능을 사용하여 IAM 역할을 맡는 파드 등 AWS 계정의 쓰기 API에 대한 호출량이 증가하는 시기를 파악할 수 있습니다. 자세한 내용은 [CloudTrail Insights 발표: 비정상적인 API 활동 식별 및 대응](https://aws.amazon.com/blogs/aws/announcing-cloudtrail-insights-identify-and-respond-to-unusual-api-activity/)을 참조하십시오. - -### 추가 리소스 - -로그의 양이 증가하면 Log Insights 또는 다른 로그 분석 도구를 사용하여 로그를 파싱하고 필터링하는 것이 비효율적일 수 있습니다. 대안으로 [Sysdig Falco](https://github.com/falcosecurity/falco)와 [ekscloudwatch](https://github.com/sysdiglabs/ekscloudwatch)를 실행하는 것도 고려해 볼 수 있습니다. Falco는 감사 로그를 분석하고 오랜 기간 동안 이상 징후나 악용에 대해 플래그를 지정합니다. ekscloudwatch 프로젝트는 분석을 위해 CloudWatch의 감사 로그 이벤트를 팔코로 전달합니다. 팔코는 일련의 [기본 감사 규칙](https://github.com/falcosecurity/plugins/blob/master/plugins/k8saudit/rules/k8s_audit_rules.yaml)과 함께 자체 감사 규칙을 추가할 수 있는 기능을 제공합니다. - -또 다른 옵션은 감사 로그를 S3에 저장하고 SageMaker [Random Cut Forest](https://docs.aws.amazon.com/sagemaker/latest/dg/randomcutforest.html) 알고리즘을 사용하여 추가 조사가 필요한 이상 동작에 사용하는 것일 수 있습니다. - -## 도구 및 리소스 - -다음 상용 및 오픈 소스 프로젝트를 사용하여 클러스터가 확립된 모범 사례와 일치하는지 평가할 수 있습니다. - -- [kubeaudit](https://github.com/Shopify/kubeaudit) -- [kube-scan](https://github.com/octarinesec/kube-scan) 쿠버네티스 공통 구성 점수 산정 시스템 프레임워크에 따라 클러스터에서 실행 중인 워크로드에 위험 점수를 할당합니다. -- [kubesec.io](https://kubesec.io/) -- [polaris](https://github.com/FairwindsOps/polaris) -- [Starboard](https://github.com/aquasecurity/starboard) -- [Snyk](https://support.snyk.io/hc/en-us/articles/360003916138-Kubernetes-integration-overview) -- [Kubescape](https://github.com/kubescape/kubescape) Kubescape는 클러스터, YAML 파일 및 헬름 차트를 스캔하는 오픈 소스 쿠버네티스 보안 도구입니다. 여러 프레임워크 ([NSA-CISA](https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo/?utm_source=github&utm_medium=repository) 및 [MITRE ATT&CK®](https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/))에 따라 설정 오류를 탐지합니다. diff --git a/content/security/docs/hosts.ko.md b/content/security/docs/hosts.ko.md deleted file mode 100644 index 57a1f313f..000000000 --- a/content/security/docs/hosts.ko.md +++ /dev/null @@ -1,193 +0,0 @@ -# 인프라(호스트) 보호 - -컨테이너 이미지를 보호하는 것도 중요하지만 이미지를 실행하는 인프라를 보호하는 것도 마찬가지로 중요합니다. 이 섹션에서는 호스트를 대상으로 직접 시작된 공격으로 인한 위험을 완화하는 다양한 방법을 살펴봅니다. 이 지침은 [런타임 보안](runtime.md) 섹션에 설명된 지침과 함께 사용해야 합니다. - -## 권장 사항 - -### 컨테이너 실행에 최적화된 OS 사용 - -Flatcar Linux, Project Atomic, RancherOS 및 리눅스 컨테이너 실행을 위해 설계된 AWS의 컨테이너 실행 최적화 OS인 [Bottlerocket](https://github.com/bottlerocket-os/bottlerocket/)을 사용해 보세요. 이것은 공격 표면 감소, 부팅 시 검증된 디스크 이미지, SELinux를 사용한 권한 제한 등이 포함하고 있습니다. - -또는 쿠버네티스 워커 노드에 [EKS 최적화 AMI][eks-ami]를 사용할 수 있습니다. EKS 최적화 AMI는 정기적으로 릴리스되며 컨테이너식 워크로드를 실행하는 데 필요한 최소한의 OS 패키지 및 바이너리 세트를 포함합니다. - -[eks-ami]: https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html - -### 워커 노드 OS를 최신 상태로 유지 - -Bottlerocket과 같은 컨테이너에 최적화된 호스트 OS를 사용하거나 EKS 최적화 AMI와 같은 Amazon 머신 이미지를 사용하고 최신 보안 패치를 사용하여 이런 호스트 OS 이미지를 최신 상태로 유지하는 것이 가장 좋습니다. - -EKS 최적화 AMI의 경우 [변경 로그][eks-ami-changes] 또는 [릴리스 노트 채널][eks-ami-releases]를 정기적으로 확인하고 업데이트된 워커 노드 이미지를 클러스터로 자동 롤아웃합니다. - -[eks-ami-changes]: https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md -[eks-ami-releases]: https://github.com/awslabs/amazon-eks-ami/releases - -### 인프라를 변경할 수 없는 대상으로 분류하고 워커 노드 교체를 자동화하십시오 - -전체 업그레이드를 수행하는 대신 새 패치 또는 업데이트가 제공되면 워커 노드를 교체합니다. 몇 가지 방법으로 이 문제를 해결할 수 있습니다. 그룹의 모든 노드가 최신 AMI로 교체될 때까지 순차적으로 노드를 차단하고 드레이닝하는 최신 AMI를 사용하여 기존 자동 확장 그룹에 인스턴스를 추가할 수도 있습니다. 또는 모든 노드가 교체될 때까지 이전 노드 그룹에서 노드를 순차적으로 차단하고 제거하면서 새 노드 그룹에 인스턴스를 추가할 수도 있습니다. EKS [관리형 노드 그룹](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)은 첫 번째 접근 방식을 사용하며 새 AMI를 사용할 수 있게 되면 콘솔에 작업자를 업그레이드하라는 메시지를 표시합니다. 또한 'eksctl'에는 최신 AMI로 노드 그룹을 생성하고 인스턴스가 종료되기 전에 노드 그룹에서 파드를 정상적으로 차단하고 드레이닝하는 메커니즘이 있습니다. 워커 노드를 교체하는 데 다른 방법을 사용하기로 결정한 경우, 새 업데이트/패치가 릴리스되고 컨트롤 플레인이 업그레이드될 때 작업자를 정기적으로 교체해야 할 수 있으므로 프로세스를 자동화하여 사람의 감독을 최소화하는 것이 좋습니다. - -EKS Fargate를 사용하면 AWS는 업데이트가 제공되는 대로 기본 인프라를 자동으로 업데이트합니다.이 작업을 원활하게 수행할 수 있는 경우가 많지만 업데이트로 인해 파드 일정이 변경되는 경우가 있을 수 있습니다.따라서 애플리케이션을 Fargate 파드로 실행할 때는 여러 복제본으로 배포를 생성하는 것이 좋습니다. - -### kube-bench를 주기적으로 실행하여 [쿠버네티스에 대한 CIS 벤치마크](https://www.cisecurity.org/benchmark/kubernetes/) 준수 여부를 확인합니다 - -kube-bench는 쿠버네티스의 CIS 벤치마크와 비교하여 클러스터를 평가하는 Aqua의 오픈 소스 프로젝트입니다. 벤치마크는 관리되지 않는 쿠버네티스 클러스터를 보호하는 모범 사례를 설명합니다. CIS 쿠버네티스 벤치마크는 컨트롤 플레인과 데이터 플레인을 포함합니다. Amazon EKS는 완전 관리형 컨트롤 플레인을 제공하므로 CIS 쿠버네티스 벤치마크의 모든 권장 사항이 적용되는 것은 아닙니다. 이 범위에 Amazon EKS 구현 방식이 반영되도록 AWS는 *CIS Amazon EKS 벤치마크*를 만들었습니다. EKS 벤치마크는 CIS 쿠버네티스 벤치마크를 계승하고 EKS 클러스터의 특정 구성 고려 사항과 함께 커뮤니티의 추가 의견을 반영합니다. - -EKS 클러스터에 대해 [kube-bench](https://github.com/aquasecurity/kube-bench)를 실행할 때는 아쿠아 시큐리티의 [이 지침](https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster)을 따릅니다. 자세한 내용은 [CIS Amazon EKS 벤치마크 소개](https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/)를 참조합니다. - -### 워커 노드에 대한 액세스 최소화 - -호스트에 원격으로 접속해야 할 때는 SSH 액세스를 활성화하는 대신 [SSM Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)를 사용합니다. 분실, 복사 또는 공유될 수 있는 SSH 키와 달리 세션 관리자에서는 IAM을 사용하여 EC2 인스턴스에 대한 액세스를 제어할 수 있습니다. 또한 인스턴스에서 실행된 명령에 대한 감사 추적 및 로그를 제공합니다. - -2020년 8월 19일부터 관리형 노드 그룹은 사용자 지정 AMI와 EC2 시작 템플릿(Launch Template)을 지원합니다. 이를 통해 SSM 에이전트를 AMI에 내장하거나 워커 노드가 부트스트랩될 때 설치할 수 있습니다. 최적화된 AMI 또는 ASG의 시작 템플릿을 수정하지 않는 경우, 이 [예시](https://github.com/aws-samples/ssm-agent-daemonset-installer)에서처럼 데몬셋을 사용하여 SSM 에이전트를 설치할 수 있습니다. - -#### SSM 기반 SSH 액세스를 위한 최소 IAM 정책 - -`AmazonSSMManagedInstanceCore` AWS 관리형 정책에는 SSH 액세스를 피하려는 경우 SSM Session Manager 및 SSM RunCommand에 필요하지 않은 여러 권한이 포함되어 있습니다. -특히 우려되는 것은 `SSM:GetParameter (s)`에 대한 `*` 권한입니다. 이렇게 하면 해당 역할이 파라미터 스토어의 모든 파라미터(AWS 관리형 KMS 키가 구성된 SecureString 포함)에 액세스할 수 있게 됩니다. - -다음 IAM 정책에는 SSM Systems Manager를 통해 노드 액세스를 활성화하기 위한 최소 권한 세트가 포함되어 있습니다. - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "EnableAccessViaSSMSessionManager", - "Effect": "Allow", - "Action": [ - "ssmmessages:OpenDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:CreateControlChannel", - "ssm:UpdateInstanceInformation" - ], - "Resource": "*" - }, - { - "Sid": "EnableSSMRunCommand", - "Effect": "Allow", - "Action": [ - "ssm:UpdateInstanceInformation", - "ec2messages:SendReply", - "ec2messages:GetMessages", - "ec2messages:GetEndpoint", - "ec2messages:FailMessage", - "ec2messages:DeleteMessage", - "ec2messages:AcknowledgeMessage" - ], - "Resource": "*" - } - ] -} -``` - -이 정책을 적용하고 [Session Manager 플러그인](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)을 설치하면 다음을 실행하여 노드에 접속합니다. - -```bash -aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE] -``` - -!!! note - [Session Manager 로깅 활성화](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging)에 권한을 추가하는 것도 고려해 볼 수 있습니다. - -### 프라이빗 서브넷에 워커 노드 배포 - -워커 노드를 프라이빗 서브넷에 배치하면 공격이 자주 발생하는 인터넷에 대한 노출을 최소화할 수 있습니다. 2020년 4월 22일부터 관리형 노드 그룹의 노드에 대한 퍼블릭 IP 주소 할당은 해당 노드가 배포되는 서브넷에 의해 제어됩니다. 이전에는 관리형 노드 그룹의 노드에 퍼블릭 IP가 자동으로 할당되었습니다. 워커 노드를 퍼블릭 서브넷에 배포하기로 선택한 경우, 제한적인 AWS 보안 그룹 규칙을 구현하여 노출을 제한합니다. - -### Amazon Inspector를 실행하여 호스트의 노출, 취약성 및 모범 사례와의 편차를 평가하십시오 - -[Amazon Inspector](https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html)를 사용하여 노드에 대한 의도하지 않은 네트워크 액세스와 기본 Amazon EC2 인스턴스의 취약성을 확인할 수 있습니다. - -Amazon Inspector는 Amazon EC2 Systems Manager(SSM) 에이전트가 설치되고 활성화된 경우에만 Amazon EC2 인스턴스에 대한 일반적인 취약성 및 노출 (CVE) 데이터를 제공할 수 있습니다. 이 에이전트는 [EKS 최적화 Amazon Linux AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html)를 비롯한 여러 [Amazon 머신 이미지 (AMI)](https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html)에 사전 설치되어 있습니다. SSM 에이전트 상태에 관계없이 모든 Amazon EC2 인스턴스는 네트워크 연결 문제 여부를 검사합니다.Amazon EC2용 스캔 구성에 대한 자세한 내용은 [Amazon EC2 인스턴스 스캔](https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html)을 참조합니다. - -!!! attention - Fargate 파드를 실행하는 데 사용되는 인프라에서는 Inspector를 실행할 수 없습니다. - -## 대안으로 선택 가능한 옵션 - -### SELinux 실행 - -!!! info - RHEL(Red Hat Enterprise Linux), CentOS, Bottlerocket과 Amazon Linux 2023 에서 사용 가능 - -SELinux는 컨테이너를 서로 격리하고 호스트로부터 격리된 상태로 유지하기 위한 추가 보안 계층을 제공합니다. SELinux를 통해 관리자는 모든 사용자, 애플리케이션, 프로세스 및 파일에 대해 필수 액세스 제어(MAC)를 적용할 수 있습니다. 레이블 집합을 기반으로 특정 리소스에 대해 수행할 수 있는 작업을 제한하는 안정장치라고 생각하면 됩니다. EKS에서는 SELinux를 사용하여 컨테이너가 서로의 리소스에 액세스하는 것을 방지할 수 있습니다. - -컨테이너 SELinux 정책은 [container-selinux](https://github.com/containers/container-selinux) 패키지에 정의되어 있습니다. Docker CE에는 Docker(또는 다른 컨테이너 런타임)에서 생성한 프로세스와 파일이 제한된 시스템 액세스로 실행되도록 하려면 이 패키지 (종속 항목 포함)가 필요합니다.컨테이너는 `svirt_lxc_net_t`의 별칭인 `container_t` 레이블을 활용합니다. 이런 정책은 컨테이너가 호스트의 특정 기능에 액세스하는 것을 효과적으로 방지합니다. - -Docker용 SELinux를 구성하면 Docker는 워크로드에 `container_t` 레이블링하여 타입으로 자동으로 인식하고 각 컨테이너에 고유한 MCS 레벨을 부여합니다. 이렇게 하면 컨테이너가 서로 격리됩니다. 보다 엄격한 제한이 필요한 경우 SELinux에서 파일 시스템의 특정 영역에 대한 컨테이너 권한을 부여하는 자체 프로파일을 만들 수 있습니다. 이는 컨테이너/파드마다 다른 프로파일을 생성할 수 있다는 점에서 PSP와 비슷합니다. 예를 들어, 일련의 제한적인 제어가 포함된 일반 워크로드용 프로파일과 권한 있는 액세스가 필요한 항목에 대한 프로파일을 각각 가질 수 있습니다. - -컨테이너용 SELinux에는 기본 제한을 수정하도록 구성할 수 있는 옵션 세트가 있습니다. 필요에 따라 다음과 같은 SELinux Booleans를 활성화하거나 비활성화할 수 있습니다. - -| Boolean | Default | Description| -|---|:--:|---| -| `container_connect_any` | `off` | 컨테이너가 호스트의 권한 있는 포트에 액세스할 수 있도록 허용합니다. 호스트의 443 또는 80에 포트를 매핑해야 하는 컨테이너가 있는 경우를 예로 들 수 있습니다. | -| `container_manage_cgroup` | `off` | 컨테이너가 cgroup 구성을 관리할 수 있도록 허용합니다. 예를 들어 systemd를 실행하는 컨테이너는 이 기능을 활성화해야 합니다. | -| `container_use_cephfs` | `off` | 컨테이너가 ceph 파일 시스템을 사용할 수 있도록 허용합니다. | - -기본적으로 컨테이너는 `/usr`에서 읽고 실행할 수 있으며 `/etc`에서 대부분의 콘텐츠를 읽을 수 있습니다. `/var/lib/docker` 및 `/var/lib/containers` 아래의 파일에는 `container_var_lib_t`라는 레이블이 붙어 있습니다. 기본 레이블의 전체 목록을 보려면 [container.fc](https://github.com/containers/container-selinux/blob/master/container.fc) 파일을 참조합니다. - -```bash -docker container run -it \ - -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ - centos:7 cat /host/repositories.json -# cat: /host/repositories.json: Permission denied - -docker container run -it \ - -v /etc/passwd:/host/etc/passwd \ - centos:7 cat /host/etc/passwd -# cat: /host/etc/passwd: Permission denied -``` - -`container_file_t`로 레이블이 지정된 파일은 컨테이너에서 쓸 수 있는 유일한 파일입니다. 볼륨 마운트를 쓰기 가능하게 하려면 끝에 `:z` 또는 `:Z`를 지정해야 합니다. - -- `:z` 는 컨테이너가 읽고 쓸 수 있도록 파일의 레이블을 다시 지정합니다. -- `:Z` 는 컨테이너**만** 읽고 쓸 수 있도록 파일에 레이블을 다시 지정합니다. - -```bash -ls -Z /var/lib/misc -# -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp - -docker container run -it \ - -v /var/lib/misc:/host/var/lib/misc:z \ - centos:7 echo "Relabeled!" - -ls -Z /var/lib/misc -#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp -``` - -```bash -docker container run -it \ - -v /var/log:/host/var/log:Z \ - fluentbit:latest -``` - -쿠버네티스에서는 레이블을 다시 지정하는 방식이 약간 다릅니다. Docker가 파일의 레이블을 자동으로 다시 지정하도록 하는 대신 사용자 지정 MCS 레이블을 지정하여 파드를 실행할 수 있습니다. 레이블 재지정을 지원하는 볼륨은 액세스할 수 있도록 자동으로 레이블이 다시 지정됩니다. MCS 레이블이 일치하는 파드는 해당 볼륨에 접근할 수 있다. 엄격한 격리가 필요한 경우 각 파드에 다른 MCS 레이블을 설정하세요. - -```yaml -securityContext: - seLinuxOptions: - # Provide a unique MCS label per container - # You can specify user, role, and type also - # enforcement based on type and level (svert) - level: s0:c144:c154 -``` - -이 예제에서 `s0:c144:c154`는 컨테이너의 액세스가 허용된 파일에 할당된 MCS 레이블에 해당합니다. - -EKS에서는 FluentD와 같은 권한 있는 컨테이너를 실행할 수 있는 정책을 생성하고 호스트 디렉터리에 레이블을 다시 지정할 필요 없이 호스트의 /var/log에서 읽을 수 있도록 허용하는 SELinux 정책을 생성할 수 있습니다. 레이블이 같은 파드는 동일한 호스트 볼륨에 액세스할 수 있습니다. - -CentOS7 및 RHEL7에 SELinux가 구성된 [Amazon EKS 샘플 AMI](https://github.com/aws-samples/amazon-eks-custom-amis)를 구현했습니다. 이런 AMI는 STIG, CJIS, C2S와 같이 규제가 엄격한 고객의 요구 사항을 충족하는 샘플 구현을 시연하기 위해 개발되었습니다. - -!!! caution - SELinux는 타입이 제한되지 않은 컨테이너를 무시합니다. - -## 도구 및 리소스 - -- [온프레미스 애플리케이션을 위한 SELinux, 쿠버네티스 RBAC 및 보안 정책](https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/) -- [쿠버네티스의 반복적 하드닝](https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html) -- [Audit2Allow](https://linux.die.net/man/1/audit2allow) -- [SEAlert](https://linux.die.net/man/8/sealert) -- [Udica를 사용하여 컨테이너에 대한 SELinux 정책 생성](https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica)은 Linux 기능에 대한 컨테이너 사양 파일을 확인하는 도구를 설명합니다. 포트, 마운트 지점, 컨테이너가 제대로 실행되도록 하는 일련의 SELinux 규칙을 생성합니다. -- [AMI Hardening](https://github.com/aws-samples/amazon-eks-custom-amis#hardening)은 다양한 규제 요구 사항을 충족하기 위해 OS를 강화하기 위한 플레이북입니다. -- [Keiko Upgrade Manager](https://github.com/keikoproj/upgrade-manager)는 워커 노드의 회전을 오케스트레이션하는 Intuit의 오픈 소스 프로젝트입니다. -- [Sysdig Secure](https://sysdig.com/products/kubernetes-security/) -- [eksctl](https://eksctl.io/) diff --git a/content/security/docs/iam.ko.md b/content/security/docs/iam.ko.md deleted file mode 100644 index ee8e6e4d7..000000000 --- a/content/security/docs/iam.ko.md +++ /dev/null @@ -1,501 +0,0 @@ -# 인증 및 접근 관리 - -[AWS IAM(Identity and Access Management)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)은 인증 및 권한 부여라는 두 가지 필수 기능을 수행하는 AWS 서비스입니다. 인증에는 자격 증명 확인이 포함되는 반면 권한 부여는 AWS 리소스에서 수행할 수 있는 작업을 관리합니다. AWS 내에서 리소스는 다른 AWS 서비스(예: EC2) 또는 [IAM 사용자](https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-users) 또는 [IAM 역할](https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-roles)과 같은 AWS [보안 주체](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal)일 수 있습니다. 리소스가 수행할 수 있는 작업을 관리하는 규칙은 [IAM 정책]( https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)으로 표현됩니다. - -## EKS 클러스터에 대한 접근 제어 - -쿠버네티스 프로젝트는 베어러(Bearer) 토큰, X.509 인증서, OIDC 등 kube-apiserver 서비스에 대한 요청을 인증하기 위한 다양한 방식을 지원합니다. EKS는 현재 [웹훅(Webhook) 토큰 인증](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication), [서비스 어카운트 토큰]( https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens) 및 2021년 2월 21일부터 OIDC 인증을 기본적으로 지원합니다. - -웹훅 인증 방식은 베어러 토큰을 확인하는 웹훅을 호출합니다. EKS에서 이런 베어러 토큰은 `kubectl` 명령 실행 시 AWS CLI 또는 [aws-iam-authenticator](https://github.com/kubernetes-sigs/aws-iam-authenticator) 클라이언트에 의해 생성됩니다. 명령을 실행하면 토큰은 kube-apiserver로 전달되고 다시 웹훅으로 포워딩됩니다. 요청이 올바른 형식이면 웹훅은 토큰 본문에 포함된 미리 서명된 URL을 호출합니다. 이 URL은 요청 서명의 유효성을 검사하고 사용자 정보(사용자 어카운트, ARN 및 사용자 ID 등)를 kube-apiserver에 반환합니다. - -인증 토큰을 수동으로 생성하려면 터미널 창에 다음 명령을 입력합니다. - -```bash -aws eks get-token --cluster-name <클러스터_이름> -``` - -프로그래밍 방식으로 토큰을 얻을 수도 있습니다. 다음은 Go 언어로 작성된 예입니다. - -```golang -package main - -import ( - "fmt" - "log" - "sigs.k8s.io/aws-iam-authenticator/pkg/token" -) - -func main() { - g, _ := token.NewGenerator(false, false) - tk, err := g.Get("") - if err != nil { - log.Fatal(err) - } - fmt.Println(tk) -} -``` - -출력 응답은 다음과 형태를 가집니다. - -```json -{ - "kind": "ExecCredential", - "apiVersion": "client.authentication.k8s.io/v1alpha1", - "spec": {}, - "status": { - "expirationTimestamp": "2020-02-19T16:08:27Z", - "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" - } -} -``` - -각 토큰은 `k8s-aws-v1.`으로 시작하고 base64로 인코딩된 문자열이 뒤따릅니다. 문자열은 디코딩하면 다음과 같은 형태를 가집니다. - -```bash -https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=0KIAJPFRILKNSRC2W5QA%2F20200219%2F$REGION%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=BB0f8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393 -``` - -토큰은 Amazon 자격 증명 크리덴셜 및 서명이 포함된 미리 서명된 URL로 구성됩니다. 자세한 내용은 [GetCallerIdentity API 문서](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html)를 참조합니다. - -토큰은 15분의 TTL 수명이 있고, 수명 종류 후에는 새 토큰을 생성해야 합니다. 이는 `kubectl`과 같은 클라이언트를 사용할 때 자동으로 처리 되지만 쿠버네티스 대시보드를 사용하는 경우 토큰이 만료될 때마다 새 토큰을 생성하고 다시 인증해야 합니다. - -사용자 ID가 AWS IAM 서비스에 의해 인증되면 kube-apiserver 는 'kube-system' 네임스페이스에서 'aws-auth' 컨피그맵을 읽어 사용자와 연결할 RBAC 그룹을 결정합니다. `aws-auth` 컨피그맵 은 IAM 보안 주체(예: IAM 사용자 및 역할)와 쿠버네티스 RBAC 그룹 간의 정적 매핑을 생성하는 데 사용됩니다. RBAC 그룹은 쿠버네티스 롤바인딩 또는 클러스터롤바인딩에서 참조할 수 있습니다. 쿠버네티스 리소스(객체) 모음에 대해 수행할 수 있는 일련의 작업(동사)을 정의한다는 점에서 IAM 역할과 유사합니다. - -## 권장 사항 - -### 인증에 서비스 어카운트 토큰을 사용하지 마세요 - -서비스 어카운트 토큰은 수명이 긴 정적 사용자 인증 정보입니다. 손상, 분실 또는 도난된 경우 공격자는 서비스 어카운트이 삭제될 때까지 해당 토큰과 관련된 모든 작업을 수행할 수 있습니다. 경우에 따라 클러스터 외부에서 쿠버네티스 API를 사용해야 하는 애플리케이션(예: CI/CD 파이프라인 애플리케이션)에 대한 예외를 부여해야 할 수 있습니다. 이런 애플리케이션이 EC2 인스턴스와 같은 AWS 인프라에서 실행되는 경우 대신 인스턴스 프로파일을 사용하고 이를 'aws-auth' 컨피그맵의 쿠버네티스 RBAC 역할에 매핑하는 것이 좋습니다. - -### AWS 리소스에 대한 최소 권한 액세스 사용 - -쿠버네티스 API에 액세스하기 위해 IAM 사용자에게 AWS 리소스에 대한 권한을 할당할 필요가 없습니다. IAM 사용자에게 EKS 클러스터에 대한 액세스 권한을 부여해야 하는 경우 특정 쿠버네티스 RBAC 그룹에 매핑되는 해당 사용자 의 'aws-auth' 컨피그맵에 항목을 생성합니다. - -### 여러 사용자가 클러스터에 대해 동일한 액세스 권한이 필요한 경우 IAM 역할 사용 - -'aws-auth' 컨피그맵 에서 각 개별 IAM 사용자에 대한 항목을 생성하는 대신 해당 사용자가 IAM 역할을 수임하고 해당 역할을 쿠버네티스 RBAC 그룹에 매핑하도록 허용합니다. 특히 액세스가 필요한 사용자 수가 증가함에 따라 유지 관리가 더 쉬워집니다. - -!!! attention - aws-auth 컨피그맵에 의해 매핑된 IAM 보안 주체로 EKS 클러스터에 액세스할 때 aws-auth 컨피그맵에 설명된 사용자 이름이 쿠버네티스 감사 로그의 사용자 필드에 기록됩니다. IAM 역할을 사용하는 경우 해당 역할을 맡는 실제 사용자는 기록되지 않으며 감사할 수 없습니다. - -aws-auth 컨피그맵에서 mapRoles를 사용하여 K8s RBAC 권한을 IAM 역할에 할당할 때 사용자 이름에 {{SessionName}}을 포함해야 합니다. 이렇게 하면 감사 로그에 세션 이름이 기록되므로 CloudTrail 로그와 함께 이 역할을 맡은 실제 사용자를 추적할 수 있습니다. - -```yaml -- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole - username: testRole:{{SessionName}} - groups: - - system:masters -``` - -쿠버네티스 1.20 또는 이후 버전에서는 ```User.Extra.sessionName.0```이 쿠버네티스 감사 로그에 추가되었으므로 이런 변경이 더 이상 필요하지 않습니다. - -### 롤바인딩(RoleBinding) 및 클러스터롤바인딩(ClusterRoleBinding) 생성 시 최소 권한 접근 허용 - -AWS 리소스에 대한 액세스 권한 부여에 대한 이전 항목과 마찬가지로 롤바인딩 및 클러스터롤바인딩에는 특정 기능을 수행하는 데 필요한 권한 집합만 포함되어야 합니다. 절대적으로 필요한 경우가 아니면 롤(Role) 및 클러스터롤(ClusterRole)에서 `["*"]` 를 사용하지 마십시오. 할당할 권한이 확실하지 않은 경우 [audit2rbac](https://github.com/liggitt/audit2rbac)과 같은 도구를 사용하여 쿠버네티스 감사 로그에서 관찰된 API 호출을 기반으로 역할 및 바인딩을 자동으로 생성하는 것이 좋습니다. - -### EKS 클러스터 엔드포인트를 프라이빗으로 설정 - -기본적으로 EKS 클러스터를 프로비저닝할 때 API 클러스터 엔드포인트는 퍼블릭으로 설정됩니다. 즉, 인터넷에서 액세스할 수 있습니다. 인터넷에서 액세스할 수 있음에도 불구하고 모든 API 요청이 IAM에 의해 인증되고 쿠버네티스 RBAC에 의해 승인되어야 하기 때문에 엔드포인트는 여전히 안전한 것으로 간주됩니다. 즉, 회사 보안 정책에 따라 인터넷에서 API에 대한 액세스를 제한하거나 클러스터 VPC 외부로 트래픽을 라우팅하지 못하도록 하는 경우 다음을 수행할 수 있습니다. - -- EKS 클러스터 엔드포인트를 프라이빗으로 구성합니다. 이 주제에 대한 자세한 내용은 [클러스터 엔드포인트 액세스 수정](https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html)을 참조하십시오. -- 클러스터 엔드포인트를 퍼블릭으로 두고 클러스터 엔드포인트와 통신할 수 있는 CIDR 블록을 지정합니다. 해당 블록은 클러스터 엔드포인트에 액세스할 수 있도록 허용된 퍼블릭 IP 주소 집합입니다. -- 퍼블릭 엔드포인트는 접근이 허용된 화이트리스트 기반의 일부 CIDR 블록에만 허용하고 프라이빗 엔드포인트를 활성화합니다. 이렇게 하면 컨트롤 플레인이 프로비저닝될 때 클러스터 VPC에 프로비저닝되는 크로스 어카운트 ENI를 통해 kubelet과 쿠버네티스 API 사이의 모든 네트워크 트래픽을 강제하는 동시에 특정 퍼블릭 IP 범위의 퍼블릭 액세스가 허용됩니다. - -### 전용 IAM 역할로 클러스터 생성 - -Amazon EKS 클러스터를 생성하면 클러스터를 생성하는 연동 사용자와 같은 IAM 엔터티 사용자 또는 역할에 클러스터의 RBAC 구성에서 `system:masters` 권한이 자동으로 부여됩니다. 이 액세스는 제거할 수 없으며 `aws-auth` 컨피그맵을 통해 관리되지 않습니다. 따라서 전용 IAM 역할로 클러스터를 생성하고 이 역할을 맡을 수 있는 사람을 정기적으로 감사하는 것이 좋습니다. 이 역할은 클러스터에서 일상적인 작업을 수행하는 데 사용되어서는 안 되며, 대신 이런 목적을 위해 `aws-auth` 컨피그맵을 통해 추가 사용자에게 클러스터에 대한 액세스 권한을 부여해야 합니다. `aws-auth` 컨피그맵이 구성된 이후에는 역할을 삭제할 수 있으며 `aws-auth` 컨피그맵이 손상되고 그렇지 않으면 클러스터에 액세스할 수 없는 긴급/유리 파손 시나리오에서만 다시 생성 할 수 있습니다. 이는 일반적으로 직접 사용자 액세스가 구성되지 않은 운영 클러스터에서 특히 유용할 수 있습니다. - -### 도구를 사용하여 aws-auth 컨피그맵 변경 - -잘못된 형식의 aws-auth 컨피그맵으로 인해 클러스터에 대한 접근 권한을 잃을 수 있습니다. 컨피그맵을 변경해야 하는 경우 도구를 사용하십시오. - -#### eksctl - -`eksctl` CLI에는 aws-auth 컨피그맵에 ID 매핑을 추가하기 위한 명령이 포함되어 있습니다. - -CLI 도움말 보기: - -```bash -eksctl create iamidentitymapping --help -``` - -IAM 역할을 클러스터 관리자로 지정: - -```bash - eksctl create iamidentitymapping --cluster --region= --arn arn:aws:iam::123456:role/testing --group system:masters --username admin -``` - -자세한 내용은 [`eksctl` 문서]( https://eksctl.io/usage/iam-identity-mappings/)를 참조하십시오. - -**keikoproj의 [aws-auth](https://github.com/keikoproj/aws-auth)** - -keikoproj의 `aws-auth` 에는 cli 및 go 라이브러리가 모두 포함되어 있습니다. - -CLI 도움말 다운로드 및 보기: - -```bash -go get github.com/keikoproj/aws-auth -aws-auth help -``` - -또는 kubectl용 [krew 플러그인 관리자](https://krew.sigs.k8s.io)로 `aws-auth` 를 설치 합니다. - -```bash -kubectl krew install aws-auth -kubectl aws-auth -``` - -go 라이브러리를 비롯한 자세한 내용은 [GitHub 내 aws-auth 문서를 확인](https://github.com/keikoproj/aws-auth/blob/master/README.md)하십시오. - -**[AWS IAM Authenticator CLI](https://github.com/kubernetes-sigs/aws-iam-authenticator/tree/master/cmd/aws-iam-authenticator)** - -`aws-iam-authenticator` 프로젝트에는 컨피그맵을 업데이트하기 위한 CLI가 포함되어 있습니다. - -GitHub에서 [릴리스 다운로드]( https://github.com/kubernetes-sigs/aws-iam-authenticator/releases)하세요. - -IAM 역할에 클러스터 권한을 추가합니다: - -```bash -./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config -``` - -### 클러스터에 대한 접근을 정기적으로 감사합니다 - -클러스터에 접근이 필요한 사람은 시간이 지남에 따라 변경될 수 있습니다. 주기적으로 `aws-auth` 컨피그맵을 감사하여 접근 권한이 부여된 사람과 할당된 권한을 확인하십시오. 특정 서비스 어카운트, 사용자 또는 그룹에 바인딩된 역할을 검사하기 위해 [kubectl-who-can](https://github.com/aquasecurity/kubectl-who-can) 또는 [rbac-lookup](https://github.com/FairwindsOps/)과 같은 오픈 소스 도구를 사용할 수도 있습니다. 해당 주제에 대해서는 [감사](detective.md)섹션에서 더 자세히 살펴 보겠습니다. 추가 아이디어는 NCC Group의 이 [기사](https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D)에서 찾을 수 있습니다. - -### 인증 및 액세스 관리에 대한 대체 접근 방식 - -IAM은 EKS 클러스터에 액세스해야 하는 사용자를 인증하는 데 선호되는 방법이지만, 인증 프록시 또는 쿠버네티스 [impersonation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation)등을 사용하는 GitHub와 같은 OIDC ID 공급자를 사용할 수 있습니다. 이런 두 가지 솔루션에 대한 게시물이 AWS 오픈 소스 블로그에 게시되었습니다. - -- [Teleport와 함께 GitHub 자격 증명을 사용하여 EKS에 인증](https://aws.amazon.com/blogs/opensource/authenticating-eks-github-credentials-teleport/) -- [kube-oidc-proxy를 사용하여 여러 EKS 클러스터에서 일관된 OIDC 인증](https://aws.amazon.com/blogs/opensource/consistent-oidc-authentication-across-multiple-eks-clusters-using-kube-oidc-proxy/) - -!!! attention - EKS는 기본적으로 프록시를 사용하지 않고 OIDC 인증을 지원합니다. 자세한 내용은 [Amazon EKS에 대한 OIDC 자격 증명 공급자 인증 소개](https://aws.amazon.com/blogs/containers/introducing-oidc-identity-provider-authentication-amazon-eks/)블로그를 참조하십시오. 다양한 인증 방법에 대한 커넥터를 제공하는 인기 있는 오픈 소스 OIDC 공급자인 Dex로 EKS를 구성하는 방법을 보여주는 예는 [Dex 및 dex-k8s-authenticator를 사용하여 Amazon EKS 인증](https://aws.amazon.com/blogs/containers/using-dex-dex-k8s-authenticator-to-authenticate-to-amazon-eks/ ) 블로그를 참조하세요. 블로그에 설명된 대로 OIDC 공급자가 인증한 사용자 이름/사용자 그룹은 쿠버네티스 감사 로그에 나타납니다. - -또한 [AWS SSO](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html)를 사용하여 Azure AD와 같은 외부 자격 증명 공급자와 AWS를 페더레이션할 수 있습니다. 이를 사용하기로 결정한 경우 AWS CLI v2.0에는 SSO 세션을 현재 CLI 세션과 쉽게 연결하고 IAM 역할을 수임할 수 있는 명명된 프로파일을 생성하는 옵션이 포함되어 있습니다. 사용자의 쿠버네티스 RBAC 그룹을 결정하는 데 IAM 역할이 사용되므로 `kubectl` 을 실행하기 "전" 역할을 수임(Assume)하여야 합니다. - -### 추가 리소스 - -[rbac.dev](https://github.com/mhausenblas/rbac.dev) 쿠버네티스 RBAC에 대한 블로그 및 도구를 포함한 추가 리소스 목록 - -## 파드 아이덴티티 - -쿠버네티스 클러스터 내에서 실행되는 특정 애플리케이션은 제대로 작동하기 위해 쿠버네티스 API를 호출할 수 있는 권한이 필요합니다. 예를 들어 [AWS 로드밸런서 컨트롤러](https://github.com/kubernetes-sigs/aws-load-balancer-controller)는 서비스의 엔드포인트를 나열할 수 있어야 합니다. 또한 컨트롤러는 ALB를 프로비저닝하고 구성하기 위해 AWS API를 호출할 수 있어야 합니다. 이 섹션에서는 파드에 권한을 할당하는 모범 사례를 살펴봅니다. - -### 쿠버네티스 서비스 어카운트 - -서비스 어카운트는 파드에 쿠버네티스 RBAC 역할을 할당할 수 있는 특수한 유형의 개체입니다. 클러스터 내의 각 네임스페이스에 대해 기본 서비스 어카운트이 자동으로 생성됩니다. 특정 서비스 어카운트을 참조하지 않고 네임스페이스에 파드를 배포하면, 해당 네임스페이스의 기본 서비스 어카운트이 자동으로 파드에 할당되고 시크릿, 즉 해당 서비스 아카운트의 서비스 어카운트 (JWT) 토큰은 `/var/run/secrets/kubernetes.io/serviceaccount`에서 볼륨으로 파드에 마운트됩니다. 해당 디렉터리의 서비스 어카운트 토큰을 디코딩하면 다음과 같은 메타데이터가 나타납니다. - -```json -{ - "iss": "kubernetes/serviceaccount", - "kubernetes.io/serviceaccount/namespace": "default", - "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", - "kubernetes.io/serviceaccount/service-account.name": "default", - "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", - "sub": "system:serviceaccount:default:default" -} -``` - -기본 서비스 어카운트에는 쿠버네티스 API에 대한 다음 권한이 있습니다. - -```yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: - rbac.authorization.kubernetes.io/autoupdate: "true" - creationTimestamp: "2020-01-30T18:13:25Z" - labels: - kubernetes.io/bootstrapping: rbac-defaults - name: system:discovery - resourceVersion: "43" - selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery - uid: 350d2ab8-438c-11ea-9438-063a49b60fba -rules: -- nonResourceURLs: - - /api - - /api/* - - /apis - - /apis/* - - /healthz - - /openapi - - /openapi/* - - /version - - /version/ - verbs: - - get -``` - -이 역할은 인증되지 않은 사용자와 인증된 사용자가 API 정보를 읽을 수 있는 권한을 부여하며 공개적으로 액세스해도 안전한 것으로 간주됩니다. - -파드 내에서 실행 중인 애플리케이션이 쿠버네티스 API를 호출할 때 해당 API를 호출할 수 있는 권한을 명시적으로 부여하는 서비스 어카운트를 파드에 할당해야 합니다. 사용자 접근에 대한 지침과 유사하게 서비스 어카운트에 바인딩된 Role 또는 ClusterRole은 애플리케이션이 작동하는 데 필요한 API 리소스 및 메서드로 제한되어야 합니다. 기본이 아닌 서비스 어카운트를 사용하려면 파드의 `spec.serviceAccountName` 필드를 사용하려는 서비스 어카운트의 이름으로 설정하기만 하면 됩니다. 서비스 어카운트 생성에 대한 추가 정보는 [해당 문서](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions)를 참조하십시오. - -!!! note - 쿠버네티스 1.24 이전에는 쿠버네티스가 각 서비스 어카운트에 대한 암호를 자동으로 생성했습니다. 이 시크릿은 파드 내 /var/run/secrets/kubernetes.io/serviceaccount 경로로 마운트되었으며 파드에서 쿠버네티스 API 서버를 인증하는 데 사용됩니다. 쿠버네티스 1.24에서는 파드가 실행될 때 서비스 어카운트 토큰이 동적으로 생성되며 기본적으로 1시간 동안만 유효합니다. 서비스 어카운트의 시크릿은 생성되지 않습니다. Jenkins와 같이 쿠버네티스 API에 인증해야 하는 클러스터 외부에서 실행되는 애플리케이션이 있는 경우, `metadata.annotations.kubernetes.io/service-account.name: `와 같은 서비스 어카운트를 참조하는 어노테이션과 함께 `kubernetes.io/service-account-token` 유형의 시크릿을 생성해야 한다. 이 방법으로 생성된 시크릿은 만료되지 않습니다. - -### 서비스 어카운트용 IAM 역할(IRSA) - -IRSA는 쿠버네티스 서비스 어카운트에 IAM 역할을 할당할 수 있는 기능입니다. [Service Account Token Volume Projection](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection)이라는 쿠버네티스 기능을 활용하여 작동합니다. 파드가 IAM 역할을 참조하는 서비스 어카운트으로 구성된 경우 쿠버네티스 API 서버는 시작 시 클러스터에 대한 공개 OIDC 검색 엔드포인트를 호출합니다. 엔드포인트는 Kubernetes에서 발행한 OIDC 토큰에 암호로 서명하고, 생성된 토큰은 볼륨으로 마운트됩니다. 이 서명된 토큰을 통해 파드는 IAM 역할과 연결된 AWS API를 호출할 수 있습니다. AWS API가 호출되면 AWS SDK는 `sts:AssumeRoleWithWebIdentity`를 호출합니다. 토큰의 서명을 확인한 후 IAM은 쿠버네티스에서 발행한 토큰을 임시 AWS 역할 자격 증명으로 교환합니다. - -IRSA에 대한 (JWT)토큰을 디코딩하면 아래에 표시된 예와 유사한 출력이 생성됩니다. - -```json -{ - "aud": [ - "sts.amazonaws.com" - ], - "exp": 1582306514, - "iat": 1582220114, - "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", - "kubernetes.io": { - "namespace": "default", - "pod": { - "name": "alpine-57b5664646-rf966", - "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" - }, - "serviceaccount": { - "name": "s3-read-only", - "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" - } - }, - "nbf": 1582220114, - "sub": "system:serviceaccount:default:s3-read-only" -} -``` - -이 특정 토큰은 파드에 S3 보기 전용 권한을 부여합니다. 애플리케이션이 S3에서 읽기를 시도하면 토큰이 다음과 유사한 임시 IAM 자격 증명 세트로 교환됩니다. - -```json -{ - "AssumedRoleUser": { - "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", - "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" - }, - "Audience": "sts.amazonaws.com", - "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", - "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", - "Credentials": { - "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1", - "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", - "Expiration": "2020-02-20T18:49:50Z", - "AccessKeyId": "0SIA12CFWWEJUMHACL7Z" - } -} -``` - -EKS 컨트롤 플레인의 일부로 실행되는 Mutating 웹훅은 AWS 역할 ARN과 웹 자격 증명 토큰 파일의 경로를 환경 변수로 파드에 주입합니다. 이런 값은 수동으로 제공할 수도 있습니다. - -```bash -AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME -AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token -``` - -kubelet은 총 TTL의 80%보다 오래되거나 24시간이 지나면 프로젝션된 토큰을 자동으로 교체합니다. AWS SDK는 토큰이 회전할 때 토큰을 다시 로드하는 역할을 합니다. IRSA에 대한 자세한 내용은 [AWS 문서](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html)를 참조합니다. - -## 포드 ID 권장 사항 - -### IRSA를 사용하도록 aws-node 데몬셋 업데이트 - -현재 aws-node 데몬셋은 EC2 인스턴스에 할당된 역할을 사용하여 파드에 IP를 할당하도록 구성되어 있습니다. 이 역할에는 AmazonEKS_CNI_Policy 및 EC2ContainerRegistryReadOnly와 같이 노드에서 실행 중인 **모든** 파드가 ENI를 연결/분리하거나, IP 주소를 할당/할당 해제하거나, ECR에서 이미지를 가져오도록 효과적으로 허용하는 몇 가지 AWS 관리형 정책이 포함됩니다. 이는 클러스터에 위험을 초래하므로 IRSA를 사용하도록 aws-node 데몬셋을 업데이트하는 것이 좋습니다. 이 작업을 수행하기 위한 스크립트는 이 가이드의 [리파지토리](https://github.com/aws/aws-eks-best-practices/tree/master/projects/enable-irsa/src)에서 찾을 수 있습니다. - -### 워커 노드에 할당된 인스턴스 프로파일에 대한 접근 제한 - -IRSA를 사용하면 IRSA 토큰을 사용하도록 파드의 자격 증명 체인을 업데이트하지만 파드는 _워커 노드에 할당된 인스턴스 프로파일의 권한을 계속 상속할 수 있습니다_. IRSA 사용 시 허용되지 않은 권한의 범위를 최소화하기 위해 [인스턴스 메타데이터](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) 액세스를 차단하는 것이 **강력하게** 권장됩니다. - -!!! caution - 인스턴스 메타데이터에 대한 액세스를 차단하면 IRSA를 사용하지 않는 파드가 워커 노드에 할당된 역할을 상속받지 못합니다. - -아래 예와 같이 인스턴스가 IMDSv2만 사용하도록 하고 홉 제한을 1로 업데이트하여 인스턴스 메타데이터에 대한 액세스를 차단할 수 있습니다. 노드 그룹의 시작 템플릿에 이런 설정을 포함할 수도 있습니다. 인스턴스 메타데이터를 **비활성화 하지마세요**. 이렇게 하면 노드 종료 핸들러와 같은 구성 요소와 인스턴스 메타데이터에 의존하는 기타 요소가 제대로 작동하지 않습니다. - -```bash -aws ec2 modify-instance-metadata-options --instance-id --http-tokens required --http-put-response-hop-limit 1 -``` - -Terraform을 사용하여 관리형 노드 그룹과 함께 사용할 시작 템플릿을 만드는 경우 메타데이터 블록을 추가하여 다음 코드 스니펫에 표시된 대로 홉 수를 구성하십시오. - -```tf hl_lines="7" -resource "aws_launch_template" "foo" { - name = "foo" - ... - metadata_options { - http_endpoint = "enabled" - http_tokens = "required" - http_put_response_hop_limit = 1 - instance_metadata_tags = "enabled" - } - ... -``` - -노드에서 iptables를 조작하여 EC2 메타데이터에 대한 파드의 액세스를 차단할 수도 있습니다. 이 방법에 대한 자세한 내용은 [인스턴스 메타데이터 서비스에 대한 액세스 제한](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access) 문서를 참조하세요. - -IRSA를 지원하지 않는 이전 버전의 AWS SDK를 사용하는 애플리케이션이 있는 경우 SDK 버전을 업데이트해야 합니다. - -### IRSA에 대한 IAM 역할 신뢰 정책의 범위를 서비스 어카운트 이름으로 지정합니다 - -신뢰 정책은 네임스페이스 또는 네임스페이스 내의 특정 서비스 어카운트로 범위를 지정할 수 있습니다. IRSA를 사용하는 경우 서비스 어카운트 이름을 포함하여 역할 신뢰 정책을 가능한 한 명시적으로 만드는 것이 가장 좋습니다. 이렇게 하면 동일한 네임스페이스 내의 다른 파드가 역할을 맡는 것을 효과적으로 방지할 수 있습니다. CLI `eksctl` 은 서비스 어카운트/IAM 역할을 생성하는 데 사용할 때 이 작업을 자동으로 수행합니다. 자세한 내용은 [eksctl 문서](https://eksctl.io/usage/iamserviceaccounts/)를 참조하세요. - -### 애플리케이션이 IMDS에 액세스해야 하는 경우 IMDSv2를 사용하고 EC2 인스턴스의 홉 제한을 2로 늘리세요 - -[IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)에서는 PUT 요청을 사용하여 세션 토큰을 가져와야 합니다. 초기 PUT 요청에는 세션 토큰에 대한 TTL이 포함되어야 합니다. 최신 버전의 AWS SDK는 이를 처리하고 해당 토큰의 갱신을 자동으로 처리합니다. 또한 IP 전달을 방지하기 위해 EC2 인스턴스의 기본 홉 제한이 의도적으로 1로 설정되어 있다는 점에 유의해야 합니다. 결과적으로 EC2 인스턴스에서 실행되는 세션 토큰을 요청하는 파드는 결국 시간 초과되어 IMDSv1 데이터 흐름을 사용하도록 대체될 수 있습니다. EKS는 v1과 v2를 모두 _활성화_하고 eksctl 또는 공식 CloudFormation 템플릿으로 프로비저닝된 노드에서 홉 제한을 2로 변경하여 지원 IMDSv2를 추가합니다. - -### 서비스 어카운트 토큰 자동 마운트 비활성화 - -애플리케이션이 Kubernetes API를 호출할 필요가 없는 경우 애플리케이션 의 PodSpec에서 `automountServiceAccountToken` 속성을 `false`로 설정하거나 각 네임스페이스의 기본 서비스 어카운트을 패치하여 더 이상 파드에 자동으로 마운트되지 않도록 합니다. 예: - -```bash -kubectl patch serviceaccount default -p $'automountServiceAccountToken: false' -``` - -### 각 애플리케이션에 전용 서비스 어카운트 사용 - -각 애플리케이션에는 고유한 전용 서비스 어카운트이 있어야 합니다. 이는 쿠버네티스 API 및 IRSA의 서비스 어카운트에 적용됩니다. - -!!! attention - 전체 클러스터 업그레이드를 수행하는 대신 클러스터 업그레이드에 블루/그린 접근 방식을 사용하는 경우 각 IRSA IAM 역할의 신뢰 정책을 새 클러스터의 OIDC 엔드포인트로 업데이트해야 합니다. 블루/그린 클러스터 업그레이드는 이전 클러스터와 함께 최신 버전의 쿠버네티스를 실행하는 클러스터를 생성하고 로드밸런서 또는 서비스 메시를 사용하여 이전 클러스터에서 실행되는 서비스에서 새 클러스터로 트래픽을 원활하게 이동하는 것입니다. - -### 루트가 아닌 사용자로 애플리케이션 실행 - -컨테이너는 기본적으로 루트로 실행됩니다. 이렇게 하면 웹 자격 증명 토큰 파일을 읽을 수 있지만 컨테이너를 루트로 실행하는 것은 모범 사례로 간주되지 않습니다. 또는 PodSpec에 `spec.securityContext.runAsUser` 속성을 추가하는 것이 좋습니다. `runAsUser` 의 값 은 임의의 값입니다. - -다음 예제에서 파드 내의 모든 프로세스는 `RunAsUser` 필드에 지정된 사용자 ID로 실행됩니다. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: security-context-demo -spec: - securityContext: - runAsUser: 1000 - runAsGroup: 3000 - containers: - - name: sec-ctx-demo - image: busybox - command: [ "sh", "-c", "sleep 1h" ] -``` - -루트가 아닌 사용자로 컨테이너를 실행하면 기본적으로 토큰에 0600 [Root] 권한이 할당되기 때문에 컨테이너가 IRSA 서비스 어카운트 토큰을 읽을 수 없습니다. fsgroup=65534 [Nobody]를 포함하도록 컨테이너의 securityContext를 업데이트하면 컨테이너가 토큰을 읽을 수 있습니다. - -```yaml -spec: - securityContext: - fsGroup: 65534 -``` - -Kubernetes 1.19 및 이후 버전에서는 이 변경이 더 이상 필요하지 않습니다. - -### 애플리케이션에 대한 최소 접근 권한 부여 - -[Action Hero](https://github.com/princespaghetti/actionhero)는 애플리케이션이 제대로 작동하는 데 필요한 AWS API 호출 및 해당 IAM 권한을 식별하기 위해 애플리케이션과 함께 실행할 수 있는 유틸리티입니다. 애플리케이션에 할당된 IAM 역할의 범위를 점진적으로 제한하는 데 도움이 된다는 점에서 [IAM Access Advisor](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html)와 유사합니다. 자세한 내용은 AWS 리소스에 [최소 접근 권한](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) 부여에 대한 설명서를 참조하십시오. - -### 불필요한 익명 접근 검토 및 철회 - -이상적으로는 모든 API 작업에 대해 익명의 접근을 비활성화하여야 합니다. 쿠버네티스 기본 제공 사용자 system:anonymous에 대한 RoleBinding 또는 ClusterRoleBinding을 생성하여 익명 액세스 권한을 부여합니다. [rbac-lookup](https://github.com/FairwindsOps/rbac-lookup) 도구를 사용하여 system:anonymous 사용자가 클러스터에 대해 갖는 권한을 식별할 수 있습니다. - -```bash -./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' -system:anonymous cluster-wide ClusterRole/system:discovery -system:unauthenticated cluster-wide ClusterRole/system:discovery -system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer -``` - -system:public-info-viewer외의 ClusterRole 또는 모든 역할은 system:anonymous 사용자 또는 system:unauthenticated 그룹에 바인딩되지 않아야 합니다. - -특정 API에서 익명 액세스를 활성화해야 하는 정당한 이유가 있을 수 있습니다. 클러스터의 경우 익명 사용자가 특정 API만 액세스할 수 있도록 하고 인증 없이 해당 API를 노출해도 클러스터가 취약해지지 않도록 해야 합니다. - -Kubernetes/EKS 버전 1.14 이전에는 system:unauthenticated 그룹이 기본적으로 system:discovery 및 system:basic-user 클러스터 역할에 연결되었습니다. 클러스터를 버전 1.14 이상으로 업데이트했더라도 클러스터를 업데이트해도 이런 권한이 취소되지 않으므로 클러스터에서 이런 권한이 계속 활성화될 수 있습니다. -system:public-info-viewer를 제외하고 어떤 ClusterRole에 "system:unauthenticated"가 있는지 확인하려면 다음 명령을 실행할 수 있습니다(jq 유틸리티가 필요합니다): - -```bash -kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name' -``` - -그리고 "system:unauthenticated"는 아래 명령을 사용하여 "system:public-info-viewer"를 제외한 모든 역할에서 제거할 수 있습니다. - -```bash -kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f - -``` - -또는 kubectl describe 및 kubectl edit을 사용하여 수동으로 확인하고 제거할 수 있다. system:unauthenticated 그룹에 클러스터에 대한 system:discovery 권한이 있는지 확인하려면 다음 명령을 실행하십시오. - -```bash -kubectl describe clusterrolebindings system:discovery - -Name: system:discovery -Labels: kubernetes.io/bootstrapping=rbac-defaults -Annotations: rbac.authorization.kubernetes.io/autoupdate: true -Role: - Kind: ClusterRole - Name: system:discovery -Subjects: - Kind Name Namespace - ---- ---- --------- - Group system:authenticated - Group system:unauthenticated -``` - -system:unauthenticated 그룹에 클러스터에 대한 system:basic-user 권한이 있는지 확인하려면 다음 명령을 실행합니다. - -```bash -kubectl describe clusterrolebindings system:basic-user - -Name: system:basic-user -Labels: kubernetes.io/bootstrapping=rbac-defaults -Annotations: rbac.authorization.kubernetes.io/autoupdate: true -Role: - Kind: ClusterRole - Name: system:basic-user -Subjects: - Kind Name Namespace - ---- ---- --------- - Group system:authenticated - Group system:unauthenticated -``` - -system:unauthenticated 그룹이 클러스터의 system:discovery 및/또는 system:basic-user ClusterRoles에 바인딩된 경우 이런 역할을 system:unauthenticated 그룹에서 분리해야 합니다. 다음 명령을 사용하여 system:discovery ClusterRoleBinding을 편집합니다: - -```bash -kubectl edit clusterrolebindings system:discovery -``` - -위 명령은 아래와 같이 편집기에서 system:discovery ClusterRoleBinding의 현재 정의를 엽니다: - -```yaml -# Please edit the object below. Lines beginning with a '#' will be ignored, -# and an empty file will abort the edit. If an error occurs while saving this file will be -# reopened with the relevant failures. -# -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - annotations: - rbac.authorization.kubernetes.io/autoupdate: "true" - creationTimestamp: "2021-06-17T20:50:49Z" - labels: - kubernetes.io/bootstrapping: rbac-defaults - name: system:discovery - resourceVersion: "24502985" - selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery - uid: b7936268-5043-431a-a0e1-171a423abeb6 -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:discovery -subjects: -- apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated -- apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:unauthenticated -``` - -위 편집기 화면의 "Subjects" 섹션에서 system:unauthenticated 그룹 항목을 삭제합니다. - -system:basic-user ClusterRoleBinding에 대해 동일한 단계를 반복합니다. - -### 대체 접근 방식 - -IRSA는 파드에 AWS "ID"를 할당하는 _선호 되는 방법_이지만 애플리케이션에 최신 버전의 AWS SDK를 포함해야 합니다. 현재 IRSA를 지원하는 SDK의 전체 목록은 [AWS 문서](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html)를 참조합니다. IRSA 호환 SDK로 즉시 업데이트할 수 없는 애플리케이션이 있는 경우, [kube2iam](https://github.com/jtblin/kube2iam) 및 [kiam](https://github.com/uswitch/kiam) 을 포함하여 쿠버네티스 파드에 IAM 역할을 할당하는 데 사용할 수 있는 몇 가지 커뮤니티 구축 솔루션이 있습니다. AWS는 이런 솔루션의 사용을 보증하거나 용인하지 않지만 IRSA와 유사한 결과를 얻기 위해 커뮤니티에서 자주 사용합니다. diff --git a/content/security/docs/image.ko.md b/content/security/docs/image.ko.md deleted file mode 100644 index 5f834bb3c..000000000 --- a/content/security/docs/image.ko.md +++ /dev/null @@ -1,234 +0,0 @@ -# 이미지 보안 - -컨테이너 이미지는 공격에 대한 첫 번째 방어선으로 고려하여야 합니다. 안전하지 않고 잘못 구성된 이미지는 공격자는 컨테이너의 경계를 벗어나 호스트에 액세스할 수 있도록 허용합니다. 호스트에 들어가면 공격자는 민감한 정보에 액세스하거나 클러스터 내 또는 AWS 계정 내에 접근할 수 있습니다. 다음 모범 사례는 이런 상황이 발생할 위험을 완화하는 데 도움이 됩니다. - -## 권장 사항 - -### 최소 이미지 생성 - -먼저 컨테이너 이미지에서 필요없는 바이너리를 모두 제거합니다. Dockerhub로부터 검증되지 않은 이미지를 사용하는 경우 각 컨테이너 레이어의 내용을 볼 수 있는 [Dive](https://github.com/wagoodman/dive)와 같은 애플리케이션을 사용하여 이미지를 검사합니다. 권한을 상승할 수 있는 SETUID 및 SETGID 비트가 있는 모든 바이너리를 제거하고 nc나 curl과 같이 악의적인 용도로 사용될 수 있는 셸과 유틸리티를 모두 제거하는 것을 고려합니다. 다음 명령을 사용하여 SETUID 및 SETGID 비트가 있는 파일을 찾을 수 있습니다. - -```bash -find / -perm /6000 -type f -exec ls -ld {} \; -``` - -이런 파일에서 특수 권한을 제거하려면 컨테이너 이미지에 다음 지시문을 추가합니다. - -```docker -RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true -``` - -### 멀티 스테이지 빌드 사용 - -멀티 스테이지 빌드를 사용하면 최소한의 이미지를 만들 수 있습니다. 지속적 통합 주기의 일부를 자동화하는 데 멀티 스테이지 빌드를 사용하는 경우가 많습니다. 예를 들어 멀티 스테이지 빌드를 사용하여 소스 코드를 린트하거나 정적 코드 분석을 수행할 수 있습니다. 이를 통해 개발자는 파이프라인 실행을 기다릴 필요 없이 거의 즉각적인 피드백을 받을 수 있습니다. 멀티 스테이지 빌드는 컨테이너 레지스트리로 푸시되는 최종 이미지의 크기를 최소화할 수 있기 때문에 보안 관점에서 매력적입니다. 빌드 도구 및 기타 관련 없는 바이너리가 없는 컨테이너 이미지는 이미지의 공격 표면을 줄여 보안 상태를 개선합니다. 멀티 스테이지 빌드에 대한 추가 정보는 [본 문서](https://docs.docker.com/develop/develop-images/multistage-build/)를 참조합니다. - -### 컨테이너 이미지를 위한 소프트웨어 재료 명세서 (SBOM, Software Bill of Materials) 생성 - -SBOM은 컨테이너 이미지를 구성하는 소프트웨어 아티팩트의 중첩된 인벤토리입니다. -SBOM은 소프트웨어 보안 및 소프트웨어 공급망 위험 관리의 핵심 구성 요소입니다. [SBOM을 생성하여 중앙 리포지토리에 저장하고 SBOM의 취약성 검사](https://anchore.com/SBOM/)는 다음과 같은 문제를 해결하는 데 도움이 됩니다. - -- **가시성**: 컨테이너 이미지를 구성하는 구성 요소를 이해합니다. 중앙 리포지토리에 저장하면 배포 이후에도 언제든지 SBOM을 감사 및 스캔하여 제로 데이 취약성과 같은 새로운 취약성을 탐지하고 이에 대응할 수 있습니다. -- **출처 검증**: 아티팩트의 출처 및 출처에 대한 기존 가정이 사실이고 빌드 또는 제공 프로세스 중에 아티팩트 또는 관련 메타데이터가 변조되지 않았음을 보증합니다. -- **신뢰성**: 특정 유물과 그 내용물이 의도한 작업, 즉 목적에 적합하다는 것을 신뢰할 수 있다는 보장. 여기에는 코드를 실행하기에 안전한지 판단하고 코드 실행과 관련된 위험에 대해 정보에 입각한 결정을 내리는 것이 포함됩니다. 인증된 SBOM 및 인증된 CVE 스캔 보고서와 함께 검증된 파이프라인 실행 보고서를 작성하여 이미지 소비자에게 이 이미지가 실제로 보안 구성 요소를 갖춘 안전한 수단 (파이프라인) 을 통해 생성되었음을 확인하면 신뢰성이 보장됩니다. -- **종속성 신뢰 확인**: 아티팩트의 종속성 트리가 사용하는 아티팩트의 신뢰성과 출처를 반복적으로 검사합니다. SBOM의 드리프트는 신뢰할 수 없는 무단 종속성, 침입 시도 등 악의적인 활동을 탐지하는 데 도움이 될 수 있습니다. - -다음 도구를 사용하여 SBOM을 생성할 수 있습니다: - -- [Amazon Inspector](https://docs.aws.amazon.com/inspector)를 사용하여 [SBOM 생성 및 내보내기](https://docs.aws.amazon.com/inspector/latest/user/SBOM-export.html)를 수행할 수 있습니다. -- [Syft from Anchore](https://github.com/anchore/syft) 는 SBOM 생성에도 사용할 수 있습니다. 취약성 스캔을 더 빠르게 하기 위해 컨테이너 이미지에 대해 생성된 SBOM을 스캔을 위한 입력으로 사용할 수 있습니다. 그런 다음 검토 및 감사 목적으로 이미지를 Amazon ECR과 같은 중앙 OCI 리포지토리로 푸시하기 전에 SBOM 및 스캔 보고서를 이미지에 [증명 및 첨부](https://github.com/sigstore/cosign/blob/main/doc/cosign_attach_attestation.md)합니다. - -[CNCF 소프트웨어 공급망 모범 사례 가이드](https://project.linuxfoundation.org/hubfs/CNCF_SSCP_v1.pdf)를 검토하고 소프트웨어 공급망 보안에 대해 자세히 알아보세요. - -### 취약점이 있는지 이미지를 정기적으로 스캔 - -가상 머신과 마찬가지로 컨테이너 이미지에는 취약성이 있는 바이너리와 애플리케이션 라이브러리가 포함되거나 시간이 지남에 따라 취약성이 발생할 수 있습니다. 악용으로부터 보호하는 가장 좋은 방법은 이미지 스캐너로 이미지를 정기적으로 스캔하는 것입니다. Amazon ECR에 저장된 이미지는 푸시 또는 온디맨드로 스캔할 수 있습니다. (24시간 동안 한 번) ECR은 현재 [두 가지 유형의 스캔 - 기본 및 고급](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html)을 지원합니다. 기본 스캔은 [Clair](https://github.com/quay/clair)의 오픈 소스 이미지 스캔 솔루션을 무료로 활용합니다. [고급 스캔](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html)은 [추가 비용](https://aws.amazon.com/inspector/pricing/)이 과금되며 Amazon Inspector를 사용하여 자동 연속 스캔을 제공합니다. 이미지를 스캔한 후 결과는 EventBridge의 ECR용 이벤트 스트림에 기록됩니다. ECR 콘솔 내에서 스캔 결과를 볼 수도 있습니다. 심각하거나 심각한 취약성이 있는 이미지는 삭제하거나 다시 빌드해야 합니다. 배포된 이미지에서 취약점이 발견되면 가능한 한 빨리 교체해야 합니다. - -취약성이 있는 이미지가 배포된 위치를 아는 것은 환경을 안전하게 유지하는 데 필수적입니다. 이미지 추적 솔루션을 직접 구축할 수도 있지만, 다음과 같이 이 기능을 비롯한 기타 고급 기능을 즉시 사용할 수 있는 상용 제품이 이미 여러 개 있습니다. - -- [Grype](https://github.com/anchore/grype) -- [Palo Alto - Prisma Cloud (twistcli)](https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/tools/twistcli_scan_images) -- [Aqua](https://www.aquasec.com/) -- [Kubei](https://github.com/Portshift/kubei) -- [Trivy](https://github.com/aquasecurity/trivy) -- [Snyk](https://support.snyk.io/hc/en-us/articles/360003946917-Test-images-with-the-Snyk-Container-CLI) - -Kubernetes 검증 웹훅을 사용하여 이미지에 심각한 취약점이 없는지 검증할 수도 있습니다.검증 웹훅은 쿠버네티스 API보다 먼저 호출됩니다. 일반적으로 웹훅에 정의된 검증 기준을 준수하지 않는 요청을 거부하는 데 사용됩니다.[이 블로그](https://aws.amazon.com/blogs/containers/building-serverless-admission-webhooks-for-kubernetes-with-aws-sam/)는 ECR DescribeImagesCanVinds API를 호출하여 파드가 심각한 취약성이 있는 이미지를 가져오는지 여부를 확인하는 서버리스 웹훅을 소개합니다. 취약성이 발견되면 파드가 거부되고 CVE 목록이 포함된 메시지가 이벤트로 반환됩니다. - -### 증명(Attestation)을 사용하여 아티팩트 무결성 검증 - -증명이란 특정 사물 (예: 파이프라인 실행, SBOM) 또는 취약성 스캔 보고서와 같은 다른 사물에 대한 "전제 조건" 또는 "주제", 즉 컨테이너 이미지를 주장하는 암호화 방식으로 서명된 "진술"입니다. - -증명을 통해 사용자는 아티팩트가 소프트웨어 공급망의 신뢰할 수 있는 출처에서 나온 것인지 검증할 수 있습니다.예를 들어 이미지에 포함된 모든 소프트웨어 구성 요소나 종속성을 알지 못한 상태에서 컨테이너 이미지를 사용할 수 있습니다. 하지만 컨테이너 이미지 제작자가 어떤 소프트웨어가 존재하는지에 대해 말하는 내용을 신뢰할 수 있다면 제작자의 증명을 이용해 해당 아티팩트를 신뢰할 수 있습니다. 즉, 직접 분석을 수행하는 대신 워크플로우에서 아티팩트를 안전하게 사용할 수 있습니다. - -- 증명은 [AWS Signer](https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html) 또는 [Sigstore cosign](https://github.com/sigstore/cosign/blob/main/doc/cosign_attest.md)을 사용하여 생성할 수 있습니다. -- [Kyverno](https://kyverno.io/)와 같은 쿠버네티스 어드미션 컨트롤러를 사용하여 [증명 확인](https://kyverno.io/docs/writing-policies/verify-images/sigstore/)을 할 수 있습니다. -- 컨테이너 이미지에 증명 생성 및 첨부를 포함한 주제와 함께 오픈 소스 도구를 사용하는 AWS의 소프트웨어 공급망 관리 모범 사례에 대해 자세히 알아보려면 이 [워크샵을](https://catalog.us-east-1.prod.workshops.aws/workshops/49343bb7-2cc5-4001-9d3b-f6a33b3c4442/en-US/0-introduction)을 참조합니다. - -### ECR 리포지토리에 대한 IAM 정책 생성 - -조직에서 공유 AWS 계정 내에서 독립적으로 운영되는 여러 개발 팀이 있는 경우가 드물지 않습니다. 이런 팀이 자산을 공유할 필요가 없는 경우 각 팀이 상호 작용할 수 있는 리포지토리에 대한 액세스를 제한하는 IAM 정책 세트를 만드는 것이 좋습니다. 이를 구현하는 좋은 방법은 ECR [네임스페이스](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html#repository-concepts)를 사용하는 것입니다. 네임스페이스는 유사한 리포지토리를 그룹화하는 방법입니다. 예를 들어 팀 A의 모든 레지스트리 앞에 team-a/를 붙이고 팀 B의 레지스트리 앞에는 team-b/ 접두사를 사용할 수 있습니다. 액세스를 제한하는 정책은 다음과 같을 수 있습니다. - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "AllowPushPull", - "Effect": "Allow", - "Action": [ - "ecr:GetDownloadUrlForLayer", - "ecr:BatchGetImage", - "ecr:BatchCheckLayerAvailability", - "ecr:PutImage", - "ecr:InitiateLayerUpload", - "ecr:UploadLayerPart", - "ecr:CompleteLayerUpload" - ], - "Resource": [ - "arn:aws:ecr:::repository/team-a/*" - ] - } - ] -} -``` - -### ECR 프라이빗 엔드포인트 사용 고려 - -ECR API에는 퍼블릭 엔드포인트가 있습니다. 따라서 IAM에서 요청을 인증하고 승인하기만 하면 인터넷에서 ECR 레지스트리에 액세스할 수 있습니다. 클러스터 VPC에 IGW(인터넷 게이트웨이)가 없는 샌드박스 환경에서 운영해야 하는 경우 ECR용 프라이빗 엔드포인트를 구성할 수 있습니다. 프라이빗 엔드포인트를 생성하면 인터넷을 통해 트래픽을 라우팅하는 대신 프라이빗 IP 주소를 통해 ECR API에 비공개로 액세스할 수 있습니다. 이 주제에 대한 추가 정보는 [Amazon ECR 인터페이스 VPC 엔드포인트](https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html)를 참조합니다. - -### ECR 엔드포인트 정책 구현 - -기본 엔드포인트 정책은 리전 내의 모든 ECR 리포지토리에 대한 액세스를 허용합니다. 이로 인해 공격자/내부자가 데이터를 컨테이너 이미지로 패키징하고 다른 AWS 계정의 레지스트리로 푸시하여 데이터를 유출할 수 있습니다. 이 위험을 완화하려면 ECR 리포지토리에 대한 API 액세스를 제한하는 엔드포인트 정책을 생성해야 합니다. 예를 들어 다음 정책은 계정의 모든 AWS 원칙이 ECR 리포지토리에 대해서만 모든 작업을 수행하도록 허용합니다. - -```json -{ - "Statement": [ - { - "Sid": "LimitECRAccess", - "Principal": "*", - "Action": "*", - "Effect": "Allow", - "Resource": "arn:aws:ecr:::repository/*" - } - ] -} -``` - -AWS 조직에 속하지 않은 IAM 원칙에 의한 이미지 푸시/풀링을 방지하는 새로운 `PrincipalOrGid` 속성을 사용하는 조건을 설정하여 이를 더욱 개선할 수 있습니다. 자세한 내용은 [AWS:PrincipalorgID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid)를 참조하십시오. -`com.amazonaws..ecr.dkr` 및 `com.amazonaws..ecr.api` 엔드포인트 모두에 동일한 정책을 적용하는 것을 권장합니다. -EKS는 ECR에서 kube-proxy, coredns 및 aws-node용 이미지를 가져오므로, 레지스트리의 계정 ID (예: `602401143452.dkr. ecr.us-west-2.amazonaws.com /*`)를 엔드포인트 정책의 리소스 목록에 추가하거나 "*"에서 가져오기를 허용하고 계정 ID에 대한 푸시를 제한하도록 정책을 변경해야 합니다. 아래 표는 EKS 이미지를 제공하는 AWS 계정과 클러스터 지역 간의 매핑을 보여줍니다. - -|Account Number |Region | -| -------------- | ------ | -|602401143452 |All commercial regions except for those listed below | -|--- |--- | -|800184023465 |ap-east-1 - Asia Pacific (Hong Kong) | -|558608220178 |me-south-1 - Middle East (Bahrain) | -|918309763551 |cn-north-1 - China (Beijing) | -|961992271922 |cn-northwest-1 - China (Ningxia) | - -엔드포인트 정책 사용에 대한 자세한 내용은 [VPC 엔드포인트 정책을 사용하여 Amazon ECR 액세스 제어](https://aws.amazon.com/blogs/containers/using-vpc-endpoint-policies-to-control-amazon-ecr-access/)를 참조합니다. - -### ECR에 대한 수명 주기 정책 구현 - -[NIST 애플리케이션 컨테이너 보안 가이드](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf) 는 "레지스트리의 오래된 이미지"의 위험에 대해 경고하며, 시간이 지나면 취약하고 오래된 소프트웨어 패키지가 포함된 오래된 이미지를 제거하여 우발적인 배포 및 노출을 방지해야 한다고 지적합니다. -각 ECR 저장소에는 이미지 만료 시기에 대한 규칙을 설정하는 수명 주기 정책이 있을 수 있습니다. [AWS 공식 문서](https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html)에는 테스트 규칙을 설정하고 평가한 다음 적용하는 방법이 설명되어 있습니다. 공식 문서에는 리포지토리의 이미지를 필터링하는 다양한 방법을 보여주는 여러 [수명 주기 정책 예제](https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html)가 있습니다. - -- 이미지 생성시기 또는 개수로 필터링 -- 태그 또는 태그가 지정되지 않은 이미지로 필터링 -- 여러 규칙 또는 단일 규칙에서 이미지 태그로 필터링 - -???+ 경고 - 장기 실행 애플리케이션용 이미지를 ECR에서 제거하면 애플리케이션을 재배포하거나 수평으로 확장할 때 이미지 가져오기 오류가 발생할 수 있습니다.이미지 수명 주기 정책을 사용할 때는 배포와 해당 배포에서 참조하는 이미지를 최신 상태로 유지하고 릴리스/배포의 빈도를 설명하는 [이미지] 만료 규칙을 항상 만들 수 있도록 CI/CD 모범 사례를 마련해야 합니다. - -### 선별된 이미지 세트 만들기 - -개발자가 직접 이미지를 만들도록 허용하는 대신 조직의 다양한 애플리케이션 스택에 대해 검증된 이미지 세트를 만드는 것을 고려해 보세요. 이렇게 하면 개발자는 Dockerfile 작성 방법을 배우지 않고 코드 작성에 집중할 수 있습니다. 변경 사항이 Master에 병합되면 CI/CD 파이프라인은 자동으로 에셋을 컴파일하고, 아티팩트 리포지토리에 저장하고, 아티팩트를 적절한 이미지에 복사한 다음 ECR과 같은 Docker 레지스트리로 푸시할 수 있습니다. 최소한 개발자가 자체 Dockerfile을 만들 수 있는 기본 이미지 세트를 만들어야 합니다. 이상적으로는 Dockerhub에서 이미지를 가져오지 않는 것이 좋습니다. a) 이미지에 무엇이 들어 있는지 항상 알 수는 없고 b) 상위 1000개 이미지 중 약 [1/5](https://www.kennasecurity.com/blog/one-fifth-of-the-most-used-docker-containers-have-at-least-one-critical-vulnerability/)에는 취약점이 있기 때문입니다. 이런 이미지 및 취약성 목록은 [이 사이트](https://vulnerablecontainers.org/)에서 확인할 수 있습니다. - -### 루트가 아닌 사용자로 실행하려면 Dockerfile에 USER 지시문을 추가 - -파드 보안 섹션에서 언급했듯이 컨테이너를 루트로 실행하는 것은 피해야 합니다. 이를 PodSpec의 일부로 구성할 수 있지만 Dockerfile에는 `USER` 디렉티브를 사용하는 것이 좋습니다. `USER` 지시어는 USER 지시문 뒤에 나타나는 `RUN`, `ENTRYPOINT` 또는 `CMD` 명령을 실행할 때 사용할 UID를 설정합니다. - -### Dockerfile 린트 - -Linting을 사용하여 Dockerfile이 사전 정의된 지침(예: 'USER' 지침 포함 또는 모든 이미지에 태그를 지정해야 함)을 준수하는지 확인할 수 있습니다. [dockerfile_lint](https://github.com/projectatomic/dockerfile_lint)는 일반적인 모범 사례를 검증하고 도커파일 린트를 위한 자체 규칙을 구축하는 데 사용할 수 있는 규칙 엔진을 포함하는 RedHat의 오픈소스 프로젝트입니다. 규칙을 위반하는 Dockerfile이 포함된 빌드는 자동으로 실패한다는 점에서 CI 파이프라인에 통합할 수 있습니다. - -### 스크래치에서 이미지 빌드 - -이미지를 구축할 때 컨테이너 이미지의 공격 표면을 줄이는 것이 주요 목표가 되어야 합니다. 이를 위한 이상적인 방법은 취약성을 악용하는 데 사용할 수 있는 바이너리가 없는 최소한의 이미지를 만드는 것입니다. 다행히 도커에는 [`scratch`](https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch)에서 이미지를 생성하는 메커니즘이 있습니다. Go와 같은 언어를 사용하면 다음 예제와 같이 정적 연결 바이너리를 만들어 Dockerfile에서 참조할 수 있습니다. - -```docker -############################ -# STEP 1 build executable binary -############################ -FROM golang:alpine AS builder# Install git. -# Git is required for fetching the dependencies. -RUN apk update && apk add --no-cache gitWORKDIR $GOPATH/src/mypackage/myapp/COPY . . # Fetch dependencies. -# Using go get. -RUN go get -d -v# Build the binary. -RUN go build -o /go/bin/hello - -############################ -# STEP 2 build a small image -############################ -FROM scratch# Copy our static executable. -COPY --from=builder /go/bin/hello /go/bin/hello# Run the hello binary. -ENTRYPOINT ["/go/bin/hello"] -``` - -이렇게 하면 애플리케이션으로만 구성된 컨테이너 이미지가 생성되어 매우 안전합니다. - -### ECR과 함께 불변 태그 사용 - -[변경 불가능한 태그](https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/)를 사용하면 이미지 저장소로 푸시할 때마다 이미지 태그를 업데이트해야 합니다. 이렇게 하면 공격자가 이미지의 태그를 변경하지 않고도 악성 버전으로 이미지를 덮어쓰는 것을 막을 수 있습니다. 또한 이미지를 쉽고 고유하게 식별할 수 있는 방법을 제공합니다. - -### 이미지, SBOM, 파이프라인 실행 및 취약성 보고서에 서명 - -도커가 처음 도입되었을 때는 컨테이너 이미지를 검증하기 위한 암호화 모델이 없었습니다. v2에서 도커는 이미지 매니페스트에 다이제스트를 추가했습니다. 이를 통해 이미지 구성을 해시하고 해시를 사용하여 이미지의 ID를 생성할 수 있었습니다. 이미지 서명이 활성화되면 도커 엔진은 매니페스트의 서명을 확인하여 콘텐츠가 신뢰할 수 있는 출처에서 생성되었으며 변조가 발생하지 않았는지 확인합니다. 각 계층이 다운로드된 후 엔진은 계층의 다이제스트를 확인하여 콘텐츠가 매니페스트에 지정된 콘텐츠와 일치하는지 확인합니다. 이미지 서명을 사용하면 이미지와 관련된 디지털 서명을 검증하여 안전한 공급망을 효과적으로 구축할 수 있습니다. - -[AWS Signer](https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html) 또는 [Sigstore Cosign](https://github.com/sigstore/cosign)을 사용하여 컨테이너 이미지에 서명하고, SBOM에 대한 증명, 취약성 스캔 보고서 및 파이프라인 실행 보고서를 생성할 수 있습니다. 이런 증명은 이미지의 신뢰성과 무결성을 보장하고, 이미지가 실제로 어떠한 간섭이나 변조 없이 신뢰할 수 있는 파이프라인에 의해 생성되었으며, 이미지 게시자가 검증하고 신뢰하는 SBOM에 문서화된 소프트웨어 구성 요소만 포함한다는 것을 보증합니다. 이런 증명을 컨테이너 이미지에 첨부하여 리포지토리로 푸시할 수 있습니다. - -다음 섹션에서는 감사 및 어드미션 컨트롤러 검증을 위해 입증된 아티팩트를 사용하는 방법을 살펴보겠습니다. - -### 쿠버네티스 어드미션 컨트롤러를 사용한 이미지 무결성 검증 - -[동적 어드미션 컨트롤러](https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/)를 사용하여 대상 쿠버네티스 클러스터에 이미지를 배포하기 전에 자동화된 방식으로 이미지 서명과 입증된 아티팩트를 확인하고 아티팩트의 보안 메타데이터가 어드미션 컨트롤러 정책을 준수하는 경우에만 배포를 승인할 수 있습니다. - -예를 들어 이미지의 서명을 암호로 확인하는 정책, 입증된 SBOM, 입증된 파이프라인 실행 보고서 또는 입증된 CVE 스캔 보고서를 작성할 수 있습니다.보고서에 데이터를 확인하기 위한 조건을 정책에 작성할 수 있습니다. 예를 들어, CVE 스캔에는 중요한 CVE가 없어야 합니다. 이런 조건을 충족하는 이미지에만 배포가 허용되며 다른 모든 배포는 어드미션 컨트롤러에 의해 거부됩니다. - -어드미션 컨트롤러의 예는 다음과 같습니다: - -- [Kyverno](https://kyverno.io/) -- [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper) -- [Portieris](https://github.com/IBM/portieris) -- [Ratify](https://github.com/deislabs/ratify) -- [Kritis](https://github.com/grafeas/kritis) -- [Grafeas tutorial](https://github.com/kelseyhightower/grafeas-tutorial) -- [Voucher](https://github.com/Shopify/voucher) - -### 컨테이너 이미지의 패키지 업데이트 - -이미지의 패키지를 업그레이드하려면 도커파일에 `apt-get update && apt-get upgrade` 실행을 포함해야 합니다. 업그레이드하려면 루트로 실행해야 하지만 이는 이미지 빌드 단계에서 발생합니다. 애플리케이션을 루트로 실행할 필요는 없습니다. 업데이트를 설치한 다음 USER 지시문을 사용하여 다른 사용자로 전환할 수 있습니다. 기본 이미지를 루트 사용자가 아닌 사용자로 실행하는 경우 루트 사용자로 전환했다가 다시 실행하세요. 기본 이미지 관리자에게만 의존하여 최신 보안 업데이트를 설치하지 마십시오. - -`apt-get clean`을 실행하여 `/var/cache/apt/archives/`에서 설치 프로그램 파일을 삭제합니다. 패키지를 설치한 후 `rm -rf /var/lib/apt/lists/*`를 실행할 수도 있습니다. 이렇게 하면 설치할 수 있는 인덱스 파일이나 패키지 목록이 제거됩니다. 이런 명령은 각 패키지 관리자마다 다를 수 있다는 점에 유의하십시오. 예를 들면 다음과 같습니다. - -```docker -RUN apt-get update && apt-get install -y \ - curl \ - git \ - libsqlite3-dev \ - && apt-get clean && rm -rf /var/lib/apt/lists/* -``` - -## 도구 및 리소스 - -- [docker-slim](https://github.com/docker-slim/docker-slim)는 안전한 최소 이미지를 구축합니다. -- [dockle](https://github.com/goodwithtech/dockle)는 Dockerfile이 보안 이미지 생성 모범 사례와 일치하는지 확인합니다. -- [dockerfile-lint](https://github.com/projectatomic/dockerfile_lint) Rule based linter for Dockerfiles -- [hadolint](https://github.com/hadolint/hadolint)는 도커파일용 규칙 기반 린터입니다. -- [Gatekeeper and OPA](https://github.com/open-policy-agent/gatekeeper)는 정책 기반 어드미션 컨트롤러입니다. -- [Kyverno](https://kyverno.io/)는 쿠버네티스 네이티브 정책 엔진입니다. -- [in-toto](https://in-toto.io/)를 통해 공급망의 특정 단계가 수행될 예정이었는지, 해당 단계가 올바른 행위자에 의해 수행되었는지 사용자가 확인할 수 있습니다. -- [Notary](https://github.com/theupdateframework/notary)는 컨테이너 이미지 서명 프로젝트입니다. -- [Notary v2](https://github.com/notaryproject/nv2) -- [Grafeas](https://grafeas.io/)는 소프트웨어 공급망을 감사 및 관리하기 위한 개방형 아티팩트 메타데이터 API입니다. diff --git a/content/security/docs/incidents.ko.md b/content/security/docs/incidents.ko.md deleted file mode 100644 index aea154a23..000000000 --- a/content/security/docs/incidents.ko.md +++ /dev/null @@ -1,145 +0,0 @@ -# 사고 대응 및 포렌식 - -사고에 신속하게 대응할 수 있으면 침해로 인한 피해를 최소화하는 데 도움이 될 수 있습니다. 의심스러운 행동을 경고할 수 있는 신뢰할 수 있는 경고 시스템을 갖추는 것이 올바른 사고 대응 계획의 첫 번째 단계입니다. 사고가 발생하면 영향을 받는 컨테이너를 폐기하여 교체할지 아니면 컨테이너를 격리하고 검사할지 신속하게 결정해야 합니다. 포렌식 조사 및 근본 원인 분석의 일환으로 컨테이너를 격리하기로 선택한 경우 다음과 같은 일련의 활동을 따라야 합니다. - -## 사고 대응 계획 예 - -### 문제가 되는 파드와 워커 노드 식별 - -첫 번째 조치는 침해를 격리하는 것입니다. 먼저 침해가 발생한 위치를 파악하고 해당 파드와 해당 노드를 인프라의 나머지 부분으로부터 격리합니다. - -### 워크로드 이름을 사용하여 문제가 되는 파드와 워커 노드를 식별 - -문제가 되는 파드의 이름과 네임스페이스를 알면 다음과 같이 파드를 실행하는 워커 노드를 식별할 수 있습니다. - -```bash -kubectl get pods --namespace -o=jsonpath='{.spec.nodeName}{"\n"}' -``` - -디플로이먼트와 같은 [워크로드 리소스](https://kubernetes.io/docs/concepts/workloads/controllers/)가 손상된 경우, 워크로드 리소스의 일부인 모든 파드가 손상될 가능성이 있다. 다음 명령어를 사용하여 워크로드 리소스의 모든 파드와 해당 파드가 실행 중인 노드를 나열하세요. - -```bash -selector=$(kubectl get deployments \ - --namespace -o json | jq -j \ -'.spec.selector.matchLabels | to_entries | .[] | "\(.key)=\(.value)"') - -kubectl get pods --namespace --selector=$selector \ --o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"' -``` - -위는 디플로이먼트를 위한 명령입니다. 레플리카셋, 스테이트풀셋 등과 같은 다른 워크로드 리소스에 대해서도 동일한 명령을 실행할 수 있습니다. - -### 서비스 어카운트 이름을 사용하여 문제가 되는 파드와 워커 노드를 식별 - -경우에 따라 서비스 어카운트가 손상된 것으로 확인될 수 있습니다. 식별된 서비스 어카운트를 사용하는 파드가 손상될 가능성이 있습니다. 다음 명령어를 사용하여 서비스 어카운트 및 실행 중인 노드를 사용하여 모든 파드를 식별할 수 있습니다. - -```bash -kubectl get pods -o json --namespace | \ - jq -r '.items[] | - select(.spec.serviceAccount == "") | - "\(.metadata.name) \(.spec.nodeName)"' -``` - -### 취약하거나 손상된 이미지와 워커 노드가 있는 파드를 식별 - -경우에 따라 클러스터의 파드에서 사용 중인 컨테이너 이미지가 악의적이거나 손상된 것을 발견할 수 있습니다. 컨테이너 이미지는 악의적이거나 손상된 것입니다. 멀웨어가 포함되어 있는 것으로 밝혀진 경우, 알려진 잘못된 이미지 또는 악용된 CVE가 있는 경우입니다. 컨테이너 이미지를 사용하는 모든 파드가 손상된 것으로 간주해야 합니다. 다음 명령어로 파드가 실행 중인 이미지와 노드를 사용하여 파드를 식별할 수 있다. - -```bash -IMAGE= - -kubectl get pods -o json --all-namespaces | \ - jq -r --arg image "$IMAGE" '.items[] | - select(.spec.containers[] | .image == $image) | - "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"' -``` - -### 파드에 대한 모든 수신 및 송신 트래픽을 거부하는 네트워크 정책을 생성하여 파드를 격리 - -모든 트래픽 거부 규칙은 파드에 대한 모든 연결을 끊어 이미 진행 중인 공격을 중지하는 데 도움이 될 수 있습니다.다음 네트워크 정책은 레이블이 `app=web`인 파드에 적용됩니다. - -```yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny -spec: - podSelector: - matchLabels: - app: web - policyTypes: - - Ingress - - Egress -``` - -!!! attention - 공격자가 기본 호스트에 대한 액세스 권한을 획득한 경우 네트워크 정책이 효과가 없는 것으로 판명될 수 있습니다. 그런 일이 발생했다고 의심되는 경우 [AWS 보안 그룹](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)을 사용하여 손상된 호스트를 다른 호스트로부터 격리할 수 있습니다.호스트의 보안 그룹을 변경할 때는 해당 호스트에서 실행 중인 모든 컨테이너에 영향을 미치므로 주의하십시오. - -### 필요한 경우 파드 또는 워커 노드에 할당된 임시 보안 자격 증명을 취소 - -워커 노드에 파드가 다른 AWS 리소스에 액세스할 수 있도록 허용하는 IAM 역할을 할당받은 경우, 공격으로 인한 추가 피해를 방지하기 위해 인스턴스에서 해당 역할을 제거해야 합니다. 마찬가지로, 파드에 IAM 역할이 할당된 경우, 다른 워크로드에 영향을 주지 않으면서 역할에서 IAM 정책을 안전하게 제거할 수 있는지 평가해 보세요. - -### 워커 노드 차단(cordon) - -영향을 받는 워커 노드를 차단함으로써 영향을 받는 노드에 파드를 스케줄링하지 않도록 스케줄러에 알리는 것입니다.이렇게 하면 다른 워크로드에 영향을 주지 않으면서 포렌식 연구를 위해 노드를 제거할 수 있습니다. - -!!! info - 이 지침은 각 Fargate 파드가 자체 샌드박스 환경에서 실행되는 Fargate에는 적용되지 않습니다. 차단하는 대신 모든 수신 및 송신 트래픽을 거부하는 네트워크 정책을 적용하여 영향을 받는 Fargate 파드를 격리하십시오. - -### 영향을 받는 워커 노드에서 종료 보호 활성화 - -공격자는 영향을 받은 노드를 종료하여 자신의 흔적을 지우려고 시도할 수 있습니다. [종료 방지 기능](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingDisableAPITermination)을 활성화하면 이런 일이 발생하지 않도록 할 수 있습니다. [인스턴스 스케일-인 보호](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection)는 스케일-인 이벤트로부터 노드를 보호합니다. - -!!! warning - 스팟 인스턴스에서는 종료 방지 기능을 활성화할 수 없습니다. - -### 문제가 되는 파드/노드에 현재 조사 중임을 나타내는 레이블을 지정 - -이는 조사가 완료될 때까지 클러스터 관리자에게 영향을 받는 파드/노드를 변경하지 말라는 경고 역할을 합니다. - -### 워커 노드에서 휘발성 아티팩트 캡처 - -- **운영 체제 메모리 캡처**. 이는 도커 데몬(또는 다른 컨테이너 런타임)과 컨테이너별 하위 프로세스의 메모리를 캡처합니다. 이는 [LiME](https://github.com/504ensicsLabs/LiME) 및 [Volatility](https://www.volatilityfoundation.org/)와 같은 도구를 사용하거나, 이를 기반으로 구축되는 [Amazon EC2용 자동 포렌식 오케스트레이터](https://aws.amazon.com/solutions/implementations/automated-forensics-orchestrator-for-amazon-ec2/)와 같은 상위 수준 도구를 사용하여 수행할 수 있습니다. -- **실행 중인 프로세스와 열린 포트의 netstat 트리 덤프를 수행**. 이는 컨테이너별로 도커 데몬과 해당 하위 프로세스가 캡처됩니다. -- **상태가 변경되기 전에 컨테이너 레벨의 상태를 저장하는 명령을 실행** 컨테이너 런타임의 기능을 사용하여 현재 실행 중인 컨테이너에 대한 정보를 캡처할 수 있습니다. 예를 들어 Docker를 사용하면 다음과 같은 작업을 수행할 수 있습니다. - - `docker top CONTAINER` : 실행 중인 프로세스를 확인 - - `docker logs CONTAINER` : 데몬 레벨 로그 확인 - - `docker inspect CONTAINER` : 컨테이너의 다양한 정보 확인 - - 컨테이너에서 '도커' 대신 [nerdctl](https://github.com/containerd/nerdctl) CLI를 사용하면 동일한 결과를 얻을 수 있다 (예: `nerdctl inspect`). 컨테이너 런타임에 따라 몇 가지 추가 명령을 사용할 수 있습니다. 예를 들어 도커에는 컨테이너 파일 시스템의 변경 사항을 확인하기 위한 `docker diff`와 휘발성 메모리(RAM)를 포함한 모든 컨테이너 상태를 저장하는 `docker checkpoint`가 있습니다. 컨테이너드 또는 CRI-O 런타임의 유사한 기능에 대한 설명은 [이 쿠버네티스 블로그 게시물](https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/)을 참조합니다. - -- **포렌식 캡처를 위해 컨테이너를 일시 중지**. -- **인스턴스의 EBS 볼륨 스냅샷을 생성**. - -### 손상된 파드 또는 워크로드 리소스 재배포 - -포렌식 분석을 위해 데이터를 수집한 후에는 손상된 파드 또는 워크로드 리소스를 재배포할 수 있습니다. - -먼저 손상된 취약점에 대한 수정 사항을 배포하고 새 대체 파드를 시작합니다. 그리고 취약한 파드를 삭제합니다. - -취약한 파드를 상위 수준의 쿠버네티스 워크로드 리소스(예: 디플로이먼트 또는 데몬셋) 에서 관리하는 경우, 이를 삭제하면 새 파드가 스케줄링된다. 따라서 취약한 파드가 다시 실행될 것입니다. 이 경우 취약성을 수정한 후 새로운 대체 워크로드 리소스를 배포해야 합니다. 그런 다음 취약한 워크로드를 삭제해야 합니다. - -## 권장 사항 - -### AWS 보안 사고 대응 백서 검토 - -이 섹션에서는 의심되는 보안 침해를 처리하기 위한 몇 가지 권장 사항과 함께 간략한 개요를 제공하지만, 이 주제는 [AWS 보안 사고 대응 백서](https://d1.awsstatic.com/whitepapers/aws_security_incident_response.pdf)에서 자세히 다룹니다. - -### 보안 게임 데이를 통한 대응 준비 - -보안 실무자를 레드팀과 블루팀, 두 팀으로 나눕니다. 레드 팀은 여러 시스템의 취약점을 조사하는 데 집중하고 파란색 팀은 취약점을 방어하는 데 집중합니다. 별도의 팀을 만들 수 있는 보안 실무자가 충분하지 않은 경우 쿠버네티스 악용에 대한 지식이 있는 외부 법인을 고용하는 것을 고려해 보십시오. - -[Kubesploit](https://github.com/cyberark/kubesploit)는 CyberArk의 침투 테스트 프레임워크로, 게임 데이를 진행하는 데 사용할 수 있습니다. 클러스터에서 취약점을 검사하는 다른 도구와 달리 kubesploit는 실제 공격을 시뮬레이션합니다. 이를 통해 블루 팀은 공격에 대한 대응을 연습하고 그 효과를 측정할 수 있습니다. - -### 클러스터에 대한 침투 테스트 실행 - -자신의 클러스터를 주기적으로 공격하면 취약성과 구성 오류를 발견하는 데 도움이 될 수 있습니다. 시작하기 전에 클러스터를 대상으로 테스트를 수행하기 전에 [침투 테스트 지침](https://aws.amazon.com/security/penetration-testing/)을 따르십시오. - -## 도구 및 리소스 - -- [kube-hunter](https://github.com/aquasecurity/kube-hunter), 쿠버네티스를 위한 침투 테스트 도구 -- [Gremlin](https://www.gremlin.com/product/#kubernetes), 애플리케이션 및 인프라에 대한 공격을 시뮬레이션하는 데 사용할 수 있는 카오스 엔지니어링 툴킷 -- [Attacking and Defending Kubernetes Installations](https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/AtredisPartners_Attacking_Kubernetes-v1.0.pdf) -- [kubesploit](https://www.cyberark.com/resources/threat-research-blog/kubesploit-a-new-offensive-tool-for-testing-containerized-environments) -- [지능적이고 지속적인 위협](https://www.youtube.com/watch?v=CH7S5rE3j8w) -- [쿠버네티스 실무 공격 및 방어](https://www.youtube.com/watch?v=LtCx3zZpOfs) -- [RBAC 권한을 악용하여 쿠버네티스 클러스터 손상](https://www.youtube.com/watch?v=1LMo0CftVC4) diff --git a/content/security/docs/index.ko.md b/content/security/docs/index.ko.md deleted file mode 100644 index 796c14ab1..000000000 --- a/content/security/docs/index.ko.md +++ /dev/null @@ -1,53 +0,0 @@ -# Amazon EKS 보안 모범 사례 가이드 - -이 가이드는 위험 평가 및 완화 전략을 통해 비즈니스 가치를 제공하는 동시에 EKS에 의존하는 정보, 시스템 및 자산을 보호하는 방법에 대한 조언을 제공합니다. 여기의 지침은 고객이 모범 사례에 따라 EKS를 구현하는 데 도움이 되도록 AWS에서 게시하는 일련의 모범 사례 가이드 중 일부입니다. 성능, 운영 우수성, 비용 최적화 및 안정성에 대한 가이드는 앞으로 몇 개월 내에 제공될 예정입니다. - -## 이 가이드를 사용하는 방법 - -이 가이드는 EKS 클러스터와 클러스터가 지원하는 워크로드에 대한 보안 제어의 효과를 구현하고 모니터링하는 책임이 있는 보안 실무자를 대상으로 합니다. 가이드는 더 쉽게 사용할 수 있도록 다양한 주제 영역으로 구성되어 있습니다. 각 주제는 간략한 개요로 시작하여 EKS 클러스터 보안을 위한 권장 사항 및 모범 사례 목록이 이어집니다. 주제는 특정 순서로 읽을 필요가 없습니다. - -## 공동 책임 모델에 대한 이해 - -보안 및 규정 준수는 EKS와 같은 관리형 서비스를 사용할 때 공동 책임으로 간주됩니다. 일반적으로 말해서 AWS는 클라우드"의" 보안을 책임지고 고객은 클라우드"에서의" 보안을 책임집니다. EKS에서 AWS는 EKS 관리형 쿠버네티스 컨트롤 플레인 관리를 담당합니다. 여기에는 쿠버네티스 마스터, ETCD 데이터베이스 및 AWS가 안전하고 안정적인 서비스를 제공하는 데 필요한 기타 인프라가 포함됩니다. EKS의 소비자는 IAM, 파드 보안, 런타임 보안, 네트워크 보안 등과 같은 이 가이드의 주제에 대해 주로 책임이 있습니다. - -인프라 보안과 관련하여 AWS는 자체 관리 작업자에서 관리형 노드 그룹, Fargate로 이동할 때 추가 책임을 맡습니다. 예를 들어 Fargate를 사용하면 AWS가 파드를 실행하는 데 사용되는 기본 인스턴스/런타임을 보호할 책임이 있습니다. - -![ 공동 책임 모델 - Fargate ]( images/SRM-EKS.jpg ) - -AWS는 또한 쿠버네티스 패치 버전 및 보안 패치로 EKS 최적화 AMI를 최신 상태로 유지할 책임이 있습니다. 관리형 노드 그룹를 사용하는 고객은 EKS API, CLI, Cloudformation 또는 AWS 콘솔을 통해 노드 그룹을 최신 AMI로 업그레이드할 책임이 있습니다. 또한 Fargate와 달리 관리형 노드 그룹은 인프라/클러스터를 자동으로 확장하지 않습니다. 이는 [cluster-autoscaler](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md) 또는 [Karpenter](https://karpenter.sh/), 네이티브 AWS 오토스케일링, SpotInst의 [Ocean](https://spot.io/solutions/kubernetes-2/) 또는 Atlassian의 [에스컬레이터](https://github.com/atlassian/escalator)와 같은 다른 기술로 처리할 수 있습니다. - -![공유 책임 모델 - 관리형 노드 그룹](./images/SRM-MNG.jpg) - -시스템을 설계하기 전에 귀하의 책임과 서비스 공급자(AWS) 사이의 경계선이 어디인지 아는 것이 중요합니다. - -공동 책임 모델에 대한 추가 정보는 [AWS 공식 문서](https://aws.amazon.com/compliance/shared-responsibility-model/)를 참조하세요. - -## 소개 - -EKS와 같은 관리형 쿠버네티스 서비스를 사용할 때 관련된 몇 가지 보안 모범 사례 영역이 있습니다. - -- ID 및 액세스 관리 -- 파드 보안 -- 런타임 보안 -- 네트워크 보안 -- 멀티테넌시 -- 탐지 관리 -- 인프라 보안 -- 데이터 암호화 및 시크릿 관리 -- 규정 컴플라이언스 -- 사고 대응 및 법의학 -- 이미지 보안 - -시스템 설계의 일부로 보안 상태에 영향을 미칠 수 있는 보안 관련 사항과 관행에 대해 생각해야 합니다. 예를 들어 리소스 집합에 대해 작업을 수행할 수 있는 사람을 제어해야 합니다. 또한 보안 사고를 신속하게 식별하고 무단 액세스로부터 시스템과 서비스를 보호하며 데이터 보호를 통해 데이터의 기밀성과 무결성을 유지할 수 있는 능력이 필요합니다. 보안 사고에 대응하기 위해 잘 정의되고 연습된 일련의 프로세스를 갖추면 보안 태세도 향상됩니다. 이런 도구와 기술은 재정적 손실 방지 또는 규제 의무 준수와 같은 목표를 지원하기 때문에 중요합니다. - -AWS는 보안에 민감한 다양한 고객의 피드백을 기반으로 진화한 다양한 보안 서비스 세트를 제공하여 조직이 보안 및 규정 준수 목표를 달성할 수 있도록 지원합니다. 매우 안전한 기반을 제공함으로써 고객은 "차별화되지 않은 무거운 작업"에 소요되는 시간을 줄이고 비즈니스 목표를 달성하는 데 더 많은 시간을 할애할 수 있습니다. - -## 피드백 - -이 가이드는 광범위한 EKS/쿠버네티스 커뮤니티에서 직접적인 피드백과 제안을 수집하기 위해 GitHub에 릴리스되고 있습니다. 가이드에 포함해야 한다고 생각하는 모범 사례가 있는 경우 GitHub 리포지토리에 이슈를 제출하거나 PR을 제출하세요. 우리의 의도는 서비스에 새로운 기능이 추가되거나 새로운 모범 사례가 발전할 때 가이드를 주기적으로 업데이트하는 것입니다. - -## 더 읽을 거리 - -[쿠버네티스 보안 백서](https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/Kubernetes%20White%20Paper.pdf), 보안 감사 워킹 그룹에서 작성한 이 백서는 보안 실무자가 건전한 설계 및 구현 결정을 내리는 데 도움을 주기 위해 쿠버네티스 공격 표면 및 보안 아키텍처의 주요 측면을 설명합니다. - -CNCF 또한 클라우드 보안에 대한 [백서](https://github.com/cncf/tag-security/blob/efb183dc4f19a1bf82f967586c9dfcb556d87534/security-whitepaper/v2/CNCF_cloud-native-security-whitepaper-May2022-v2.pdf)를 발행하였습니다. 이 백서에서는 기술 환경이 어떻게 발전했는지 살펴보고, 이런 기술 발전에 맞추어 DevOps 프로세스 및 애자일 방법론 등에 따른 보안 실천사항을 적용하는 것을 권장합니다. diff --git a/content/security/docs/multitenancy.ko.md b/content/security/docs/multitenancy.ko.md deleted file mode 100644 index 875ddc3df..000000000 --- a/content/security/docs/multitenancy.ko.md +++ /dev/null @@ -1,329 +0,0 @@ -# 테넌트 격리 - -멀티테넌시를 생각할 때 공유 인프라에서 실행되는 다른 사용자나 애플리케이션으로부터 사용자나 애플리케이션을 분리하려는 경우가 많습니다. - -쿠버네티스는 _단일 테넌트 오케스트레이터_ 입니다. 즉, 컨트롤 플레인의 단일 인스턴스가 클러스터 내 모든 테넌트 간에 공유됩니다. 하지만 멀티테넌시와 유사한 형태를 만드는 데 사용할 수 있는 다양한 쿠버네티스 객체가 있습니다. 예를 들어 네임스페이스와 역할 기반 접근 제어(RBAC) 를 구현하여 테넌트를 논리적으로 서로 격리할 수 있습니다. 마찬가지로 할당량 및 제한 범위를 사용하여 각 테넌트가 사용할 수 있는 클러스터 리소스의 양을 제어할 수 있습니다. 하지만 클러스터는 강력한 보안 경계를 제공하는 유일한 구조입니다. 클러스터 내 호스트에 대한 액세스 권한을 획득한 공격자는 해당 호스트에 마운트된 _모든_ 시크릿, 컨피그맵, 볼륨을 가져올 수 있기 때문입니다. 또한 Kubelet을 가장하여 노드의 속성을 조작하거나 클러스터 내에서 옆으로 이동할 수도 있습니다. - -다음 섹션에서는 쿠버네티스와 같은 단일 테넌트 오케스트레이터를 사용할 때 발생하는 위험을 줄이면서 테넌트 격리를 구현하는 방법을 설명합니다. - -## 소프트 멀티테넌시 - -소프트 멀티테넌시를 사용하면 네임스페이스, 역할 및 롤바인딩, 네트워크 정책과 같은 네이티브 쿠버네티스 구조를 사용하여 테넌트를 논리적으로 분리할 수 있습니다.예를 들어 RBAC는 테넌트가 서로의 리소스에 액세스하거나 조작하는 것을 방지할 수 있습니다. 쿼터 및 리밋 범위는 각 테넌트가 소비할 수 있는 클러스터 리소스의 양을 제어하는 반면, 네트워크 정책은 서로 다른 네임스페이스에 배포된 애플리케이션이 서로 통신하지 못하도록 하는 데 도움이 될 수 있습니다. - -그러나 이런 컨트롤 중 어느 것도 다른 테넌트의 파드가 노드를 공유하는 것을 막지는 못합니다. 더 강력한 격리가 필요한 경우 노드 셀렉터, 안티-어피니티 규칙 및/또는 테인트 및 톨러레이션을 사용하여 서로 다른 테넌트의 파드를 별도의 노드로 강제로 스케줄링할 수 있습니다. 이를 종종 _단독 테넌트 노드_ 라고 합니다. 테넌트가 많은 환경에서는 이 작업이 다소 복잡하고 비용이 많이 들 수 있습니다. - -!!! attention - 네임스페이스는 전역적으로 범위가 지정된 유형이므로 네임스페이스로 구현된 소프트 멀티테넌시는 필터링된 네임스페이스 목록을 테넌트에 제공할 수 없습니다. 테넌트가 특정 네임스페이스를 볼 수 있는 경우 클러스터 내의 모든 네임스페이스를 볼 수 있습니다. - -!!! warning - 소프트 멀티테넌시를 사용하면 테넌트는 기본적으로 클러스터 내에서 실행되는 모든 서비스에 대해 CoreDNS를 쿼리할 수 있습니다.공격자는 클러스터의 모든 파드에서 `dig SRV *.*.svc.cluster.local`을 실행하여 이를 악용할 수 있습니다.클러스터 내에서 실행되는 서비스의 DNS 레코드에 대한 액세스를 제한해야 하는 경우 CoreDNS용 방화벽 또는 정책 플러그인을 사용하는 것이 좋습니다. 자세한 내용은 [https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy](https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy)을 참조하십시오. - -[Kiosk](https://github.com/kiosk-sh/kiosk)는 소프트 멀티 테넌시의 구현을 지원하는 오픈 소스 프로젝트입니다. 다음 기능을 제공하는 일련의 CRD 및 컨트롤러로 구현됩니다. - -- 공유 쿠버네티스 클러스터에서 테넌트를 분리하기 위한 **계정 및 계정 사용자** -- 계정 사용자를 위한 **셀프 서비스 네임스페이스 프로비저닝** -- 클러스터 공유 시 서비스 품질 및 공정성을 보장하기 위한 **계정 제한** -- 안전한 테넌트 격리 및 셀프 서비스 네임스페이스 초기화를 위한 **네임스페이스 템플릿** - -[Loft](https://loft.sh)는 다음 기능을 추가하는 Kiosk 및 [DevSpace](https://github.com/devspace-cloud/devspace)의 관리자가 제공하는 상용 제품입니다. - -- 다른 클러스터의 공간에 대한 액세스 권한을 부여하기 위한 **멀티 클러스터 액세스** -- **절전 모드** 는 비활성 기간 동안 공간에서 배포를 축소합니다. -- **GitHub와 같은 OIDC 인증 공급자를 사용한 싱글 사인온** - -소프트 멀티 테넌시로 해결할 수 있는 세 가지 주요 사용 사례가 있습니다. - -### 엔터프라이즈 설정 - -첫 번째는 "테넌트"가 직원, 계약자 또는 조직의 승인을 받았다는 점에서 어느정도 신뢰을 받는 기업 환경입니다. 각 테넌트는 일반적으로 부서 또는 팀과 같은 행정 부서에 소속됩니다. - -이런 유형의 설정에서는 일반적으로 클러스터 관리자가 네임스페이스 생성 및 정책 관리를 담당합니다. 또한 특정 개인에게 네임스페이스를 감독하는 위임 관리 모델을 구현하여 배포, 서비스, 파드, 작업 등과 같이 정책과 관련이 없는 개체에 대해 CRUD 작업을 수행할 수 있도록 할 수도 있습니다. - -컨테이너 런타임에서 제공하는 격리는 이 설정 내에서 허용될 수도 있고 파드 보안을 위한 추가 제어 기능으로 보강해야 할 수도 있습니다.더 엄격한 격리가 필요한 경우 서로 다른 네임스페이스에 있는 서비스 간의 통신을 제한해야 할 수도 있습니다. - -### 서비스로서 쿠버네티스 - -대조적으로 소프트 멀티테넌시는 Kuberenetes as a Service(KaaS) 상황에서 사용할 수 있는 설정입니다. KaaS를 사용하면 애플리케이션이 일련의 PaaS 서비스를 제공하는 컨트롤러 및 CRD 컬렉션과 함께 공유 클러스터에서 호스팅됩니다. 테넌트는 쿠버네티스 API 서버와 직접 상호 작용하며 비정책 객체에 대해 CRUD 작업을 수행할 수 있습니다. 테넌트가 자체 네임스페이스를 생성하고 관리할 수 있다는 점에서 셀프 서비스의 요소도 있습니다. 이런 유형의 환경에서는 테넌트는 신뢰할 수 없는 코드도 실행할 수 있는 것으로 간주됩니다. - -이런 유형의 환경에서 테넌트를 격리하려면 엄격한 네트워크 정책과 _파드 샌드박싱_ 을 구현해야 할 수 있습니다. 샌드박싱은 Firecracker와 같은 마이크로 VM 내에서 또는 사용자 공간 커널에서 파드 컨테이너를 실행하는 것입니다. 이제 EKS Fargate를 사용하여 샌드박스가 적용된 파드를 만들 수 있습니다. - -### 서비스형 소프트웨어(SaaS) - -소프트 멀티테넌시의 최종 사용 사례는 서비스형 소프트웨어 (SaaS) 설정입니다.이 환경에서 각 테넌트는 클러스터 내에서 실행되는 애플리케이션의 특정 _인스턴스_ 와 연결됩니다.각 인스턴스는 종종 자체 데이터를 갖고 있으며 일반적으로 쿠버네티스 RBAC와 독립적인 별도의 액세스 제어를 사용합니다. - -다른 사용 사례와 달리 SaaS 설정의 테넌트는 쿠버네티스 API와 직접 인터페이스하지 않습니다. 대신 SaaS 애플리케이션은 쿠버네티스 API와 인터페이스하여 각 테넌트를 지원하는 데 필요한 객체를 생성합니다. - -## 쿠버네티스 구성 - -각 인스턴스에서 다음 구조를 사용하여 테넌트를 서로 격리합니다: - -### 네임스페이스 - -네임스페이스는 소프트 멀티테넌시를 구현하는 데 필수적입니다.클러스터를 논리적 파티션으로 나눌 수 있습니다.멀티테넌시를 구현하는 데 필요한 할당량, 네트워크 정책, 서비스 어카운트 및 기타 개체의 범위는 네임스페이스로 지정됩니다. - -### 네트워크 정책 - -기본적으로 쿠버네티스 클러스터의 모든 파드는 서로 통신할 수 있습니다. 이 동작은 네트워크 정책을 사용하여 변경할 수 있습니다. - -네트워크 정책은 레이블 또는 IP 주소 범위를 사용하여 파드 간 통신을 제한합니다. 테넌트 간 엄격한 네트워크 격리가 필요한 멀티 테넌트 환경에서는 파드 간 통신을 거부하는 기본 규칙과 모든 파드가 DNS 서버에 이름 확인을 쿼리할 수 있도록 허용하는 다른 규칙으로 시작하는 것이 좋습니다. 이를 통해 네임스페이스 내에서 통신을 허용하는 더 많은 허용 규칙을 추가할 수 있습니다. 필요에 따라 이를 더 세분화할 수 있습니다. - -!!! attention - 네트워크 정책은 필요하지만 충분하지는 않습니다. 네트워크 정책을 적용하려면 Calico 또는 Cilium과 같은 정책 엔진이 필요합니다. - -### 역할 기반 접근 제어(RBAC) - -역할 및 롤바인딩은 쿠버네티스에서 역할 기반 접근 제어 (RBAC) 를 적용하는 데 사용되는 쿠버네티스 오브젝트입니다. **역할**에는 클러스터의 오브젝트에 대해 수행할 수 있는 작업 목록이 포함되어 있습니다. **롤바인딩**은 역할이 적용되는 개인 또는 그룹을 지정합니다. 엔터프라이즈 및 KaaS 설정에서 RBAC를 사용하여 선택한 그룹 또는 개인이 개체를 관리할 수 있도록 허용할 수 있습니다. - -### 쿼터 - -쿼터은 클러스터에서 호스팅되는 워크로드에 대한 제한을 정의하는 데 사용됩니다. 쿼터을 사용하면 파드가 소비할 수 있는 최대 CPU 및 메모리 양을 지정하거나 클러스터 또는 네임스페이스에 할당할 수 있는 리소스 수를 제한할 수 있습니다. **Limit Range**를 사용하면 각 제한의 최소값, 최대값 및 기본값을 선언할 수 있습니다. - -공유 클러스터에서 리소스를 오버커밋하면 리소스를 최대화할 수 있으므로 종종 유용합니다. 그러나 클러스터에 대한 무제한 액세스는 리소스 부족을 초래하여 성능 저하 및 애플리케이션 가용성 손실로 이어질 수 있습니다. 파드의 요청이 너무 낮게 설정되고 실제 리소스 사용량이 노드의 용량을 초과하면 노드에 CPU 또는 메모리 압력이 발생하기 시작합니다. 이 경우 파드가 재시작되거나 노드에서 제거될 수 있습니다. - -이를 방지하려면 멀티 테넌트 환경에서 네임스페이스에 할당량을 부과하여 테넌트가 클러스터에서 파드를 예약할 때 요청 및 제한을 지정하도록 계획해야 합니다. 또한 파드가 소비할 수 있는 리소스의 양을 제한하여 잠재적인 서비스 거부를 완화할 수 있습니다. - -또는 쿼터를 사용하여 테넌트의 지출에 맞게 클러스터의 리소스를 할당할 수 있습니다.이는 KaaS 시나리오에서 특히 유용합니다. - -### 파드 우선순위 및 선점 - -파드 우선순위 및 선점은 다른 파드에 비해 파드에 더 많은 중요성을 부여하고자 할 때 유용할 수 있다.예를 들어 파드 우선 순위를 사용하면 고객 A의 파드가 고객 B보다 높은 우선 순위로 실행되도록 구성할 수 있습니다. 사용 가능한 용량이 충분하지 않은 경우 스케줄러는 고객 B의 우선 순위가 낮은 파드를 제외하고 고객 A의 우선 순위가 높은 파드를 수용합니다. 이는 프리미엄을 지불하려는 고객이 더 높은 우선 순위를 받는 SaaS 환경에서 특히 유용할 수 있습니다. - -!!! attention - 파드의 우선순위는 우선순위가 낮은 다른 파드에 원치 않는 영향을 미칠 수 있다. 예를 들어, 대상 파드는 정상적으로 종료되지만 PodDisruptionBudget은 보장되지 않아 파드 쿼럼에 의존하는 우선순위가 낮은 애플리케이션이 중단될 수 있습니다. [선점 제한](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#limitations-of-preemption)을 참조하십시오. - -## 완화 제어 - -멀티 테넌트 환경 관리자의 주된 관심사는 공격자가 기본 호스트에 대한 접근 권한을 얻지 못하도록 하는 것입니다. 이런 위험을 완화하려면 다음 제어 방법을 고려해야 합니다. - -### 컨테이너를 위한 샌드박스 실행 환경 - -샌드박싱은 각 컨테이너를 격리된 자체 가상 시스템에서 실행하는 기술입니다. 파드 샌드박싱을 수행하는 기술로는 [Firecracker](https://firecracker-microvm.github.io/), Weave의 [Firekube](https://www.weave.works/blog/firekube-fast-and-secure-kubernetes-clusters-using-weave-ignite)등이 있습니다. - -Firecracker를 EKS 지원 런타임으로 만들기 위한 노력에 대한 추가 정보는 [이 글](https://threadreaderapp.com/thread/1238496944684597248.html)을 참조하십시오. - -### 개방형 정책 에이전트(OPA) 및 게이트키퍼 - -[Gatekeeper](https://github.com/open-policy-agent/gatekeeper)는 [OPA](https://www.openpolicyagent.org/)로 생성된 정책을 시행하는 Kubernetes 어드미션 컨트롤러입니다. OPA를 사용하면 별도의 인스턴스 또는 다른 테넌트보다 더 높은 우선순위에서 테넌트의 파드를 실행하는 정책을 생성할 수 있습니다. 이 프로젝트에 대한 일반적인 OPA 정책 모음은 GitHub [리포지토리](https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa)에서 찾을 수 있습니다. - -OPA를 사용하여 CoreDNS에서 반환되는 레코드를 필터링/제어할 수 있는 실험적인 [CoreDNS를 위한 OPA 플러그인](https://github.com/coredns/coredns-opa)도 있습니다. - -### Kyverno - -[Kyverno](https://kyverno.io)는 정책을 쿠버네티스 리소스로 사용하여 구성을 검증, 변경 및 생성할 수 있는 쿠버네티스 기본 정책 엔진입니다. Kyverno는 유효성 검사를 위해 Kustomize 스타일 오버레이를 사용하고 변형을 위한 JSON 패치 및 전략적 병합 패치를 지원하며 유연한 트리거를 기반으로 네임스페이스 간에 리소스를 복제할 수 있습니다. - -Kyverno를 사용하여 네임스페이스를 격리하고, 파드 보안 및 기타 모범 사례를 적용하고, 네트워크 정책과 같은 기본 구성을 생성할 수 있습니다. 이 프로젝트의 GitHub [리포지토리](https://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno)에 몇 가지 예제가 포함되어 있습니다. 다른 많은 것들이 Kyverno 웹사이트 내 [정책 라이브러리](https://kyverno.io/policies/)에 포함되어 있습니다. - -### 테넌트 워크로드를 특정 노드로 격리 - -테넌트 워크로드가 특정 노드에서 실행되도록 제한하면 소프트 멀티 테넌시 모델의 격리를 높이는 데 사용할 수 있습니다. 이 접근 방식을 사용하면 테넌트별 워크로드가 각 테넌트용으로 프로비저닝된 노드에서만 실행됩니다. 이런 격리를 달성하기 위해 네이티브 쿠버네티스 속성(노드 어피니티, 테인트 및 톨러레이션)을 사용하여 특정 노드를 파드 스케줄링 대상으로 지정하고 다른 테넌트의 파드가 테넌트별 노드에 스케줄링되지 않도록 합니다. - -#### 파트 1 - 노드 어피니티 - -쿠버네티스 [노드 어피니티](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)는 노드 [레이블](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)을 기반으로 노드를 스케줄링할 대상으로 지정하는 데 사용됩니다. 노드 어피니티 규칙을 사용하면 셀렉터 용어와 일치하는 특정 노드에 파드가 몰리도록 구성할 수 있습니다. 아래 파드 사양에서는 `requiredDuringSchedulingIgnoredDuringExecution` 노드 어피니티가 각 파드에 적용된다. 결과적으로 파드는 `node-restriction.kubernetes.io/tenant: tenants-x`와 같은 키/값으로 레이블이 지정된 노드에 배포됩니다. - -``` yaml -... -spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: node-restriction.kubernetes.io/tenant - operator: In - values: - - tenants-x -... -``` - -이 노드 어피니티를 사용하면 스케줄링 중에 레이블이 필요하지만 실행 중에는 필요하지 않습니다. 기본 노드의 레이블이 변경되더라도 해당 레이블 변경으로 인해 파드가 제거되지는 않습니다. 하지만 향후 스케줄링이 영향을 받을 수 있습니다. - -!!! warning - `node-restriction.kubernetes.io/` 레이블 접두사는 쿠버네티스에서 특별한 의미를 가집니다. EKS 클러스터에 사용할 수 있는 [NodeRestriction](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction)은 'kubelet'이 이 접두사를 가진 레이블을 추가/제거/업데이트하는 것을 방지합니다. 공격자는 `kubelet`의 레이블을 수정할 수 없으므로, `kubelet`의 자격 증명을 사용하여 노드 개체를 업데이트하거나 이런 레이블을 `kubelet`으로 전달하도록 시스템 설정을 수정할 수 없습니다. 이 접두사를 모든 파드의 노드 스케줄링에 사용하면 공격자가 노드 레이블을 수정하여 다른 워크로드 세트를 노드로 끌어들이려는 시나리오를 방지할 수 있습니다. - -!!! info - 노드 어피니티 대신 [노드 셀렉터](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)를 사용할 수도 있습니다. 하지만 노드 어피니티는 표현방식이 더 다양하고 파드 스케줄링 중에 더 복잡한 조건을 정의할 수 있습니다. 차이점과 고급 스케줄링 선택에 대한 추가 정보는 CNCF 블로그 게시물인 [고급 쿠버네티스 파드의 노드 스케줄링](https://www.cncf.io/blog/2021/07/27/advanced-kubernetes-pod-to-node-scheduling/)을 참조하십시오. - -#### 파트 2 - 테인트(Taint) 및 톨러레이션(Toleration) - -파드를 노드로 끌어들이는 것은 이 세 부분으로 구성된 접근 방식의 첫 번째 부분에 불과합니다. 이 접근 방식이 제대로 작동하려면 권한이 부여되지 않은 노드에 파드를 스케줄링하지 않도록 해야 합니다. 쿠버네티스는 원치 않거나 승인되지 않은 파드를 차단하기 위해 노트 [테인트](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)를 사용합니다. 테인트는 파드가 스케줄링되지 않도록 노드에 조건을 설정하는 데 사용됩니다. 아래 테인트는 `tenant: tenants-x`의 키-값 쌍을 사용합니다. - -``` yaml -... - taints: - - key: tenant - value: tenants-x - effect: NoSchedule -... -``` - -위와 같이 노드 `테인트`가 주어지면, 테인트를 _허용하는_ 파드만 노드에 스케줄링할 수 있다. 승인된 파드를 노드에 스케줄링할 수 있으려면 아래와 같이 각 파드 사양에 테인트에 대한 `톨러레이션`이 포함되어야 합니다. - -``` yaml -... - tolerations: - - effect: NoSchedule - key: tenant - operator: Equal - value: tenants-x -... -``` - -위의 `톨러레이션`을 가진 파드는 적어도 그 특정 테인트로 인하여 해당 노드로 스케줄링이 중단되지는 않을 것이다. 쿠버네티스는 노드 리소스 압박과 같은 특정 상황에서 파드 스케줄링을 일시적으로 중단하기 위해 테인트를 사용하기도 합니다. 노드 어피니티, 테인트 및 톨러레이션을 사용하면 원하는 파드를 특정 노드로 효과적으로 배포하고 원치 않는 파드를 제거할 수 있습니다. - -!!! attention -특정 쿠버네티스 파드는 모든 노드에서 실행되어야 합니다. 이런 파드는 예로 [컨테이너 네트워크 인터페이스 (CNI)](https://github.com/containernetworking/cni) 및 [kube-proxy](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/) [데몬셋](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)등이 있습니다. 이를 위해 이런 파드의 사양에는 다양한 테인트을 견딜 수 있는 매우 관대한 톨러레이션이 포함되어야 합니다. 이런 톨러레이션을 변경하지 않도록 주의해야 합니다. 이런 허용치를 변경하면 클러스터 작동이 잘못될 수 있습니다. 또한 [OPA/Gatekeeper](https://github.com/open-policy-agent/gatekeeper) 및 [Kyverno](https://kyverno.io/)와 같은 정책 관리 도구를 사용하여 승인되지 않은 파드가 이런 관대한 톨러레이션을 사용하지 못하도록 하는 검증 정책도 작성할 수 있습니다. - -#### 파트 3 - 노드 선택을 위한 정책 기반 관리 - -CICD 파이프라인의 규칙 적용을 포함하여 파드 사양의 노드 어피니티 및 톨러레이션을 관리하는 데 사용할 수 있는 여러 도구가 있습니다. 하지만 쿠버네티스 클러스터 수준에서도 격리를 적용해야 합니다. 이를 위해 정책 관리 도구를 사용하여 요청 페이로드를 기반으로 인바운드 쿠버네티스 API 서버 요청을 _변경_ 하여 위에서 언급한 각 노드 어피니티 규칙 및 톨러레이션을 적용할 수 있습니다. - -예를 들어, _tenants-x_ 네임스페이스로 향하는 파드에 올바른 노드 어피니티 및 톨러레이션을 _스탬핑_하여 _tenants-x_ 노드에 대한 스케줄링을 허용할 수 있다. 쿠버네티스 [뮤테이팅(Mutating) 어드미션 웹훅](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)을 사용하여 구성된 정책 관리 도구를 활용하면 정책을 사용하여 인바운드 파드 사양을 변경할 수 있습니다. 뮤테이션은 원하는 스케줄링이 가능하도록 필요한 요소를 추가합니다. 노드 어피니티를 추가하는 OPA/게이트키퍼 정책의 예는 다음과 같습니다. - -``` yaml -apiVersion: mutations.gatekeeper.sh/v1alpha1 -kind: Assign -metadata: - name: mutator-add-nodeaffinity-pod - annotations: - aws-eks-best-practices/description: >- - Adds Node affinity - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity -spec: - applyTo: - - groups: [""] - kinds: ["Pod"] - versions: ["v1"] - match: - namespaces: ["tenants-x"] - location: "spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms" - parameters: - assign: - value: - - matchExpressions: - - key: "tenant" - operator: In - values: - - "tenants-x" -``` - -위의 정책은 _tenants-x_ 네임스페이스에 파드를 적용하기 위한 쿠버네티스 API 서버 요청에 적용됩니다. 이 정책은 `requiredDuringSchedulingIgnoredDuringExecution` 노드 어피니티 규칙을 추가하여, 파드가 `tenant: tenants-x` 레이블이 붙은 노드에 집중되도록 합니다. - -아래에 나와 있는 두 번째 정책은 대상 네임스페이스와 그룹, 종류, 버전의 동일한 일치 기준을 사용하여 동일한 파드 사양에 톨러레이션을 추가합니다. - -``` yaml -apiVersion: mutations.gatekeeper.sh/v1alpha1 -kind: Assign -metadata: - name: mutator-add-toleration-pod - annotations: - aws-eks-best-practices/description: >- - Adds toleration - https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ -spec: - applyTo: - - groups: [""] - kinds: ["Pod"] - versions: ["v1"] - match: - namespaces: ["tenants-x"] - location: "spec.tolerations" - parameters: - assign: - value: - - key: "tenant" - operator: "Equal" - value: "tenants-x" - effect: "NoSchedule" -``` - -위의 정책은 파드에만 해당된다. 이는 정책의 `location` 요소에 있는 변경되는 요소에 대한 경로 때문입니다. 디플로이먼트 및 잡 리소스와 같이 파드를 생성하는 리소스를 처리하기 위한 추가 정책을 작성할 수 있다. 나열된 정책 및 기타 예는 이 가이드의 동반 [GitHub 프로젝트](https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa/gatekeeper/node-selector)에서 확인할 수 있습니다. - -이 두 뮤테이션의 결과는 파드가 원하는 노드에 끌리는 동시에 특정 노드 테인트에 의해 반발되지 않는다는 것입니다. 이를 확인하기 위해 `tenant=tenants-x` 로 레이블이 지정된 노드를 가져 오고 `tenants-x` 네임스페이스 에서 파드를 가져 오기 위해 두 개의 `kubectl` 호출에서 출력 스니펫을 볼 수 있습니다. - -``` bash -kubectl get nodes -l tenant=tenants-x -NAME -ip-10-0-11-255... -ip-10-0-28-81... -ip-10-0-43-107... - -kubectl -n tenants-x get pods -owide -NAME READY STATUS RESTARTS AGE IP NODE -tenant-test-deploy-58b895ff87-2q7xw 1/1 Running 0 13s 10.0.42.143 ip-10-0-43-107... -tenant-test-deploy-58b895ff87-9b6hg 1/1 Running 0 13s 10.0.18.145 ip-10-0-28-81... -tenant-test-deploy-58b895ff87-nxvw5 1/1 Running 0 13s 10.0.30.117 ip-10-0-28-81... -tenant-test-deploy-58b895ff87-vw796 1/1 Running 0 13s 10.0.3.113 ip-10-0-11-255... -tenant-test-pod 1/1 Running 0 13s 10.0.35.83 ip-10-0-43-107... -``` - -위의 출력에서 볼 수 있듯이 모든 파드는 `tenant=tenants-x`로 표시된 노드에 스케줄링됩니다. 간단히 말해, 파드는 원하는 노드에서만 실행되고 다른 파드(필수 어피니티 및 톨러레이션 제외)는 실행되지 않습니다. 테넌트 워크로드는 효과적으로 격리됩니다. - -뮤테이션된 파드 스펙의 예는 아래에 나와 있습니다. - -``` yaml -apiVersion: v1 -kind: Pod -metadata: - name: tenant-test-pod - namespace: tenants-x -spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: tenant - operator: In - values: - - tenants-x -... - tolerations: - - effect: NoSchedule - key: tenant - operator: Equal - value: tenants-x -... -``` - -!!! attention - 뮤테이팅(mutating) 및 검증(validating) 어드미션 웹훅을 사용하여 쿠버네티스 API 서버 요청 흐름에 통합된 정책 관리 도구는 지정된 기간 내에 API 서버의 요청에 응답하도록 설계되었습니다. 이 시간은 보통 3초 이내입니다. 웹훅 호출이 구성된 시간 내에 응답을 반환하지 못하면 인바운드 API 서버 요청의 변경 및/또는 검증이 발생할 수도 있고 그렇지 않을 수도 있습니다. 이 동작은 승인 웹훅 구성이 [Fail-Open 또는 Fail-Closed](https://open-policy-agent.github.io/gatekeeper/website/docs/#admission-webhook-fail-open-by-default)로 설정되어 있는지 여부에 따라 달라집니다. - -위 예시에서는 OPA/게이트키퍼용으로 작성된 정책을 사용했습니다. 하지만 노드 선택 사용 사례를 처리하는 다른 정책 관리 도구도 있습니다. 예를 들어, 이 [Kyverno 정책](https://kyverno.io/policies/other/add_node_affinity/add_node_affinity/)을 사용하여 노드 어피니티 뮤테이션을 처리할 수 있습니다. - -!!! tip - 제대로 작동하는 경우 정책을 변경하면 인바운드 API 서버 요청 페이로드에 대한 원하는 변경 사항이 적용됩니다. 하지만 변경 사항이 계속 적용되기 전에 원하는 변경 사항이 적용되는지 확인하는 검증 정책도 포함해야 합니다. 이는 테넌트-노드 격리에 이런 정책을 사용할 때 특히 중요합니다. 또한 클러스터에 원치 않는 구성이 있는지 정기적으로 점검할 수 있도록 _감사_ 정책을 포함하는 것도 좋습니다. - -### 참조 - -- [k-rail](https://github.com/cruise-automation/k-rail)는 특정 정책의 적용을 통해 멀티테넌트 환경을 보호할 수 있도록 설계되었습니다. - -- [Amazon EKS를 사용하는 멀티 테넌트 SaaS 애플리케이션에 대한 보안 사례](https://d1.awsstatic.com/whitepapers/security-practices-for-multi-tenant-saas-apps-using-eks.pdf) - -## 하드 멀티테넌시 - -각 테넌트에 대해 별도의 클러스터를 프로비저닝하여 하드 멀티테넌시를 구현할 수 있습니다. 이렇게 하면 테넌트 간에 매우 강력한 격리가 가능하지만 몇 가지 단점이 있습니다. - -첫째, 테넌트가 많은 경우 이 접근 방식은 비용이 많이 들 수 있습니다. 각 클러스터의 컨트롤 플레인 비용을 지불해야 할 뿐만 아니라 클러스터 간에 컴퓨팅 리소스를 공유할 수 없게 됩니다. 이로 인해 결국 클러스터의 일부는 활용도가 낮고 다른 클러스터는 과도하게 사용되는 단편화가 발생합니다. - -둘째, 이런 클러스터를 모두 관리하려면 특수 도구를 구입하거나 구축해야 할 수 있습니다.시간이 지나면 수백 또는 수천 개의 클러스터를 관리하는 것이 너무 복잡해질 수 있습니다. - -마지막으로 테넌트별로 클러스터를 생성하는 것은 네임스페이스를 생성하는 것보다 느립니다. 하지만 규제가 엄격한 산업이나 강력한 격리가 필요한 SaaS 환경에서는 하드 테넌시 접근 방식이 필요할 수 있습니다. - -## 향후 방향 - -Kubernetes 커뮤니티는 소프트 멀티테넌시의 현재 단점과 하드 멀티테넌시의 문제점을 인식하고 있습니다.[멀티테넌시 SIG 그룹](https://github.com/kubernetes-sigs/multi-tenancy)은 계층적 네임스페이스 컨트롤러(HNC) 및 가상 클러스터를 비롯한 여러 인큐베이션 프로젝트를 통해 이런 단점을 해결하려고 노력하고 있습니다. - -HNC 제안(KEP)은 테넌트 관리자가 하위 네임스페이스를 생성할 수 있는 기능과 함께 \[policy\] 개체 상속을 통해 네임스페이스 간의 상위-하위 관계를 생성하는 방법을 설명합니다. - -가상 클러스터 제안서는 클러스터 내의 각 테넌트("Kubernetes on Kubernetes"라고도 표현)에 대해 API 서버, 컨트롤러 관리자 및 스케줄러를 포함한 컨트롤 플레인 서비스의 개별 인스턴스를 생성하는 메커니즘을 설명합니다. - -[멀티테넌시 벤치마크](https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/README.md) 제안서는 격리 및 분할을 위한 네임스페이스를 사용하여 클러스터를 공유하는 지침과 지침 준수 여부를 검증하기 위한 명령줄 도구 [kubectl-mtb](https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/kubectl-mtb/README.md)를 제공합니다. - -## 멀티 클러스터 관리 리소스 - -- [Banzai Cloud](https://banzaicloud.com/) -- [Kommander](https://d2iq.com/solutions/ksphere/kommander) -- [Lens](https://github.com/lensapp/lens) -- [Nirmata](https://nirmata.com) -- [Rafay](https://rafay.co/) -- [Rancher](https://rancher.com/products/rancher/) -- [Weave Flux](https://www.weave.works/oss/flux/) diff --git a/content/security/docs/network.ko.md b/content/security/docs/network.ko.md deleted file mode 100644 index 74adb5a36..000000000 --- a/content/security/docs/network.ko.md +++ /dev/null @@ -1,548 +0,0 @@ -# 네트워크 보안 - -네트워크 보안에는 여러 측면이 있습니다. 첫 번째는 서비스 간의 네트워크 트래픽 흐름을 제한하는 규칙 적용과 관련됩니다. 두 번째는 전송 중인 트래픽의 암호화와 관련이 있습니다. EKS에서 이런 보안 조치를 구현하는 메커니즘은 다양하지만 종종 다음 항목을 포함합니다. - -## 트래픽 관리 - -- 네트워크 정책 -- 보안 그룹 - -## 네트워크 암호화 - -- 서비스 메시 -- 컨테이너 네트워크 인터페이스(CNI) -- 인그레스 컨트롤러와 로드밸런서 -- Nitro 인스턴스 -- cert-manager와 ACM Private CA - -## 네트워크 정책 - -쿠버네티스 클러스터 내에서는 기본적으로 모든 파드와 파드 간의 통신이 허용된다. 이러한 유연성은 실험을 촉진하는 데 도움이 될 수 있지만 안전한 것으로 간주되지는 않습니다. 쿠버네티스 네트워크 정책은 파드 간 통신(East/West 트래픽이라고도 함)과 파드와 외부 서비스 간의 네트워크 트래픽을 제한하는 메커니즘을 제공합니다. 쿠버네티스 네트워크 정책은 OSI 모델의 계층 3과 4에서 작동합니다. 네트워크 정책은 파드, 네임스페이스 셀렉터 및 레이블을 사용하여 소스 및 대상 파드를 식별하지만 IP 주소, 포트 번호, 프로토콜 또는 이들의 조합을 포함할 수도 있습니다. 네트워크 정책은 파드에 대한 인바운드 또는 아웃바운드 연결 모두에 적용할 수 있으며, 이를 인그레스(ingress) 및 이그레스(egress) 규칙이라고도 합니다. - -Amazon VPC CNI 플러그인의 기본 네트워크 정책 지원을 통해 네트워크 정책을 구현하여 쿠버네티스 클러스터의 네트워크 트래픽을 보호할 수 있습니다. 이는 업스트림 쿠버네티스 네트워크 정책 API와 통합되어 호환성과 쿠버네티스 표준 준수를 보장합니다. 업스트림 API에서 지원하는 다양한 [식별자](https://kubernetes.io/docs/concepts/services-networking/network-policies/)를 사용하여 정책을 정의할 수 있습니다. 기본적으로 모든 수신 및 송신 트래픽은 파드에 허용됩니다. PolicyType Ingress가 포함된 네트워크 정책을 지정하는 경우 파드 노드의 연결과 인그레스 규칙에서 허용하는 연결만 파드에 대한 연결만 허용됩니다. 이그레스 규칙에도 동일하게 적용됩니다. 여러 규칙이 정의된 경우 결정을 내릴 때 모든 규칙의 통합을 고려합니다. 따라서 평가 순서는 정책 결과에 영향을 미치지 않습니다. - -!!! attention - EKS 클러스터를 처음 프로비저닝할 때 VPC CNI 네트워크 정책 기능은 기본적으로 활성화되지 않습니다. 지원되는 VPC CNI 애드온 버전을 배포했는지 확인하고 vpc-cni 애드온에서 `ENABLE_NETWORK_POLICY` 플래그를 `true`로 설정하여 이를 활성화하세요. 자세한 지침은 [Amazon EKS 사용자 가이드](https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html)를 참조하십시오. - -## 권장사항 - -### 네트워크 정책 시작하기 - 최소 권한 원칙 적용 - -### 디폴트 거부(deny) 정책 만들기 - -RBAC 정책과 마찬가지로 네트워크 정책에서도 최소 권한 액세스 원칙을 따르는 것이 좋습니다. 먼저 네임스페이스 내에서 모든 인바운드 및 아웃바운드 트래픽을 제한하는 '모두 거부' 정책을 만드세요. - -```yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: default-deny - namespace: default -spec: - podSelector: {} - policyTypes: - - Ingress - - Egress -``` - -![default-deny]( ./images/default-deny.jpg ) - -!!! tip - 위 이미지는 [Tufin](https://orca.tufin.io/netpol/)의 네트워크 정책 뷰어로 생성되었습니다. - -### DNS 쿼리를 허용하는 규칙 만들기 - -기본 거부 모든 규칙을 적용한 후에는 파드가 이름 확인을 위해 CoreDNS를 쿼리하도록 허용하는 전역 규칙과 같은 추가 규칙에 계층화를 시작할 수 있습니다. 네임스페이스에 레이블을 지정하여 시작합니다. - -```yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-dns-access - namespace: default -spec: - podSelector: - matchLabels: {} - policyTypes: - - Egress - egress: - - to: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: kube-system - podSelector: - matchLabels: - k8s-app: kube-dns - ports: - - protocol: UDP - port: 53 -``` - -![allow-dns-access](./images/allow-dns-access.jpg) - -#### 네임스페이스/파드 간 트래픽 흐름을 선택적으로 허용하는 규칙을 점진적으로 추가 - -애플리케이션 요구 사항을 이해하고 필요에 따라 세분화된 수신 및 송신 규칙을 생성하십시오. 아래 예는 포트 80의 인그레스 트래픽을 `client-one`에서 `app-one`으로 제한하는 방법을 보여줍니다. 이렇게 하면 공격 표면을 최소화하고 인증되지 않은 접근에 대한 위험을 줄일 수 있습니다. - -```yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: allow-ingress-app-one - namespace: default -spec: - podSelector: - matchLabels: - k8s-app: app-one - policyTypes: - - Ingress - ingress: - - from: - - podSelector: - matchLabels: - k8s-app: client-one - ports: - - protocol: TCP - port: 80 -``` - -![allow-ingress-app-one](./images/allow-ingress-app-one.png) - -### 네트워크 정책 적용 모니터링 - -- **네트워크 정책 편집기 사용** - - [네트워크 정책 편집기](https://networkpolicy.io/)는 네트워크 흐름 로그의 시각화, 보안 점수, 자동 생성을 지원합니다. - - 상호활동적으로 네트워크 정책 구성하세요. -- **로그 감사** - - EKS 클러스터의 감사 로그를 정기적으로 검토하세요. - - 감사 로그는 네트워크 정책 변경을 포함하여 클러스터에서 수행된 작업에 대한 풍부한 정보를 제공합니다. - - 이 정보를 사용하여 시간 경과에 따른 네트워크 정책 변경 사항을 추적하고 승인되지 않았거나 예상치 못한 변경을 감지할 수 있습니다. -- **테스트 자동화** - - 운영 환경을 미러링하는 테스트 환경을 만들고 네트워크 정책을 위반하려는 워크로드를 정기적으로 배포하여 자동화된 테스트를 구현하십시오. -- **메트릭 지표 모니터링** - - VPC CNI 노드 에이전트에서 프로메테우스 메트릭을 수집하도록 옵저버빌리티 에이전트를 구성하여 에이전트 상태 및 SDK 오류를 모니터링할 수 있습니다. -- **정기적으로 네트워크 정책을 감사** - - 네트워크 정책을 정기적으로 감사하여 현재 애플리케이션 요구 사항을 충족하는지 확인하십시오.애플리케이션이 발전함에 따라 감사를 통해 중복된 인그레스, 이그레스 규칙을 제거하고 애플리케이션에 과도한 권한이 부여되지 않도록 할 수 있습니다. -- **Open Policy Agent(OPA)를 사용하여 네트워크 정책이 존재하는지 확인** - - 아래와 같은 OPA 정책을 사용하여 애플리케이션 파드를 온보딩하기 전에 네트워크 정책이 항상 존재하는지 확인하십시오. 이 정책은 해당 네트워크 정책이 없는 경우 `k8s-app: sample-app`이라는 레이블이 붙은 k8s 파드의 온보딩을 거부합니다. - -```javascript -package kubernetes.admission -import data.kubernetes.networkpolicies - -deny[msg] { - input.request.kind.kind == "Pod" - pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels} - contains_label(pod_label_value, "sample-app") - np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels} - not contains_label(np_label_value, "sample-app") - msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name]) -} -contains_label(arr, val) { - arr[_] == val -} -``` - -### 문제 해결 (트러블슈팅) - -#### vpc-network-policy-controller 및 node-agent 로그 모니터링 - -EKS 컨트롤 플레인의 컨트롤러 매니저 로그를 활성화하여 네트워크 정책 기능을 진단합니다. 컨트롤 플레인 로그를 CloudWatch 로그 그룹으로 스트리밍하고 [CloudWatch Log Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html)를 사용하여 고급 쿼리를 수행할 수 있습니다. 로그에서 네트워크 정책으로 확인된 파드 엔드포인트 객체, 정책의 조정 상태를 확인하고 정책이 예상대로 작동하는지 디버깅할 수 있습니다. - -또한 Amazon VPC CNI를 사용하면 EKS 워커 노드에서 정책 적용 로그를 수집하고 [Amazon Cloudwatch](https://aws.amazon.com/cloudwatch/) 로 내보낼 수 있습니다. 활성화되면 [CloudWatch Container Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html)를 활용하여 네트워크 정책과 관련된 사용에 대한 통찰력을 제공할 수 있습니다. - -또한 Amazon VPC CNI는 노드 내 eBPF 프로그램과 상호 작용할 수 있는 인터페이스를 제공하는 SDK를 제공합니다. SDK는 `aws-node`가 노드에 배포될 때 설치됩니다. 노드의 `/opt/cni/bin` 디렉터리에서 설치된 SDK 바이너리를 찾을 수 있습니다. 출시 시 SDK는 eBPF 프로그램 및 맵 검사와 같은 기본 기능을 지원합니다. - -```shell -sudo /opt/cni/bin/aws-eks-na-cli ebpf progs -``` - -#### 네트워크 트래픽 메타데이터 로깅 - -[AWS VPC Flow Logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)는 VPC를 통과하는 트래픽에 대한 메타데이터(예: 소스 및 대상 IP 주소, 포트)를 허용/드랍된 패킷과 함께 캡처합니다. 이 정보를 분석하여 VPC 내 리소스(파드 포함) 간에 의심스럽거나 특이한 활동이 있는지 확인할 수 있습니다. 하지만 파드의 IP 주소는 교체될 때 자주 변경되므로 플로우 로그만으로는 충분하지 않을 수 있다. Calico Enterprise는 파드 레이블 및 기타 메타데이터를 사용하여 플로우 로그를 확장하여 파드 간 트래픽 흐름을 더 쉽게 해독할 수 있도록 합니다. - -## 보안 그룹 - -EKS는 [AWS VPC 보안 그룹](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)(SG)을 사용하여 쿠버네티스 컨트롤 플레인과 클러스터의 워커 노드 사이의 트래픽을 제어합니다. 보안 그룹은 워커 노드, 기타 VPC 리소스 및 외부 IP 주소 간의 트래픽을 제어하는 데에도 사용됩니다. EKS 클러스터 (쿠버네티스 버전 1.14-eks.3 이상)를 프로비저닝하면 클러스터 보안 그룹이 자동으로 생성됩니다. 이 보안 그룹은 EKS 컨트롤 플레인과 관리형 노드 그룹의 노드 간의 자유로운 통신을 허용합니다. 단순화를 위해 비관리형 노드 그룹을 포함한 모든 노드 그룹에 클러스터 SG를 추가하는 것이 좋습니다. - -쿠버네티스 버전 1.14 및 EKS 버전 eks.3 이전에는 EKS 컨트롤 플레인 및 노드 그룹에 대해 별도의 보안 그룹이 구성되었습니다. 컨트롤 플레인 및 노드 그룹 보안 그룹에 대한 최소 및 권장 규칙은 [AWS 문서](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html)에서 확인할 수 있습니다. _컨트롤 플레인 보안 그룹_ 의 최소 규칙에 따라 워커 노드 보안그룹에서 포트 443을 인바운드할 수 있습니다. 이 규칙은 kubelets가 쿠버네티스 API 서버와 통신할 수 있도록 하는 규칙입니다. 또한 워커 노드 보안그룹로의 아웃바운드 트래픽을 위한 포트 10250도 포함되어 있습니다. 10250은 kubelet이 수신하는 포트입니다. 마찬가지로 최소 _노드 그룹_ 규칙은 컨트롤 플레인 보안그룹에서 포트 10250을 인바운드하고 컨트롤 플레인 보안그룹로 아웃바운드하는 443을 허용합니다. 마지막으로 노드 그룹 내 노드 간의 자유로운 통신을 허용하는 규칙이 있습니다. - -클러스터 내에서 실행되는 서비스와 RDS 데이터베이스와 같이 클러스터 외부에서 실행되는 서비스 간의 통신을 제어해야 하는 경우 [파드용 보안 그룹](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html)을 고려해 보세요. 파드용 보안 그룹을 사용하면 파드 컬렉션에 **기존** 보안 그룹을 할당할 수 있다. - -!!! warning - 파드를 생성하기 전에 존재하지 않는 보안 그룹을 참조하는 경우, 파드는 스케줄링되지 않는다. - -`SecurityGroupPolicy` 객체를 생성하고 `PodSelector` 또는 `ServiceAccountSelector`를 지정하여 어떤 파드를 보안 그룹에 할당할지 제어할 수 있습니다. 셀렉터를 `{}`로 설정하면 `SecurityGroupPolicy`에서 참조하는 보안그룹이 네임스페이스의 모든 파드 또는 네임스페이스의 모든 서비스 어카운트에 할당됩니다. 파드용 보안 그룹을 구현하기 전에 [고려 사항](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations)을 모두 숙지해야 합니다. - -!!! 중요 - 파드에 보안그룹을 사용하는 경우 클러스터 보안 그룹에 포트 53이 아웃바운드되도록 허용하는 보안그룹을 생성해야 합니다. 마찬가지로, 파드 보안 그룹의 포트 53 인바운드 트래픽을 허용하도록 클러스터 보안 그룹을 업데이트해야 합니다. - -!!! 중요 - 파드용 보안 그룹을 사용할 때에도 [보안 그룹 제한사항](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)이 여전히 적용되므로 신중하게 사용해야 합니다. - -!!! 중요 - 파드에 구성된 모든 프로브에 대해 클러스터 보안 그룹 (kubelet)의 인바운드 트래픽에 대한 규칙을 **필수** 생성해야 합니다. - -!!! 중요 - 파드의 보안 그룹은 EC2 인스턴스의 여러 개의 ENI를 할당 하기 위해 [ENI 트렁킹](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html) 기능을 사용합니다. 파드가 보안그룹에 할당되면 VPC 컨트롤러는 노드 그룹의 브랜치 ENI를 파드와 연결합니다. 파드가 예약될 때 노드그룹에서 사용할 수 있는 브랜치 ENI가 충분하지 않은 경우 파드는 보류 상태로 유지됩니다. 인스턴스가 지원할 수 있는 브랜치 ENI의 수는 인스턴스 유형/패밀리에 따라 다릅니다. 자세한 내용은 [AWS 문서](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types)를 참조하십시오. - -파드용 보안 그룹은 정책 데몬의 오버헤드 없이 클러스터 내부 및 외부의 네트워크 트래픽을 제어할 수 있는 AWS 네이티브 방법을 제공하지만 다른 옵션도 사용할 수 있습니다. 예를 들어 Cilium 정책 엔진을 사용하면 네트워크 정책에서 DNS 이름을 참조할 수 있습니다. Calico Enterprise에는 네트워크 정책을 AWS 보안 그룹에 매핑하는 옵션이 포함되어 있습니다. Istio와 같은 서비스 메시를 구현한 경우, 이그레스 게이트웨이를 사용하여 네트워크 송신을 검증된 특정 도메인 또는 IP 주소로 제한할 수 있습니다. 이 옵션에 대한 자세한 내용은 [Istio의 이그레스 트래픽 제어](https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/)에 대한 3부작 시리즈를 참조하십시오. - -## 언제 네트워크 정책과 파드용 보안 그룹을 사용해야 할까요? - -### 쿠버네티스 네트워크 정책을 사용하는 경우 - -- **파드-파드 간 트래픽 제어** - - 클러스터 내 파드 간 네트워크 트래픽(이스트-웨스트 트래픽) 제어에 적합 -- **IP 주소 또는 포트 수준에서 트래픽 제어 (OSI 계층 3 또는 4)** - -### 파드용 AWS 보안 그룹(SGP) 을 사용해야 하는 경우 - -- **기존 AWS 구성 활용** - - AWS 서비스에 대한 액세스를 관리하는 복잡한 EC2 보안 그룹이 이미 있고 애플리케이션을 EC2 인스턴스에서 EKS로 마이그레이션하는 경우 SGP는 보안 그룹 리소스를 재사용하고 이를 파드에 적용할 수 있는 매우 좋은 선택이 될 수 있습니다. -- **AWS 서비스에 대한 접근 제어** - - EKS 클러스터 내에서 실행되는 애플리케이션이 다른 AWS 서비스(RDS 데이터베이스)와 통신하려는 경우 SGP를 효율적인 메커니즘으로 사용하여 파드에서 AWS 서비스로의 트래픽을 제어합니다. -- **파드 및 노드 트래픽 격리** - - 파드 트래픽을 나머지 노드 트래픽과 완전히 분리하려면 `POD_SECURITY_GROUP_ENFORCING_MODE=strict` 모드에서 SGP를 사용하십시오. - -### `파드용 보안 그룹` 및 `네트워크 정책` 모범 사례 - -- **레이어별 보안** - - 계층화된 보안 접근 방식을 위해 SGP와 쿠버네티스 네트워크 정책을 함께 사용하십시오. - - SGP를 사용하여 클러스터에 속하지 않은 AWS 서비스에 대한 네트워크 수준 액세스를 제한하는 반면, 쿠버네티스 네트워크 정책은 클러스터 내 파드 간 네트워크 트래픽을 제한할 수 있습니다. -- **최소 권한 원칙** - - 파드 또는 네임스페이스 간에 필요한 트래픽만 허용 -- **애플리케이션 격리** - - 가능한 경우 네트워크 정책에 따라 애플리케이션을 구분하여 애플리케이션이 손상된 경우 침해 범위를 줄이십시오. -- **정책을 단순하고 명확하게 유지** - - 쿠버네티스 네트워크 정책은 매우 세밀하고 복잡할 수 있으므로 잘못된 구성의 위험을 줄이고 관리 오버헤드를 줄이려면 가능한 한 단순하게 유지하는 것이 가장 좋습니다. -- **공격 범위 축소** - - 애플리케이션 노출을 제한하여 공격 표면을 최소화합니다. - -!!! caution - 파드용 보안 그룹은 `strict`과 `standard`이라는 두 가지 적용 모드를 제공합니다. EKS 클러스터의 파드 기능에 네트워크 정책과 보안 그룹을 모두 사용할 때는 `standard` 모드를 사용해야 합니다. - -네트워크 보안과 관련해서는 계층화된 접근 방식이 가장 효과적인 솔루션인 경우가 많습니다. 쿠버네티스 네트워크 정책과 SGP를 함께 사용하면 EKS에서 실행되는 애플리케이션을 위한 강력한 심층 방어 전략을 제공할 수 있습니다. - -## 서비스 메시 정책 적용 또는 쿠버네티스 네트워크 정책 - -'서비스 메시'는 애플리케이션에 추가할 수 있는 전용 인프라 계층입니다. 이를 통해 가시성, 트래픽 관리, 보안 등의 기능을 자체 코드에 추가하지 않고도 투명하게 추가할 수 있습니다. - -서비스 메시는 OSI 모델의 계층 7 (애플리케이션) 에서 정책을 적용하는 반면, 쿠버네티스 네트워크 정책은 계층 3 (네트워크) 및 계층 4 (전송) 에서 작동합니다.이 분야에는 AWS AppMesh, Istio, Linkerd 등과 같은 다양한 제품이 있습니다. - -### 정책 시행에 서비스 메시를 사용하는 경우 - -- 서비스 메쉬가 구성되어 있는 경우 -- 트래픽 관리, 옵저버빌리티 및 보안과 같은 고급 기능이 필요한 경우 - - 트래픽 제어, 로드 밸런싱, 서킷 브레이킹, 속도 제한, 타임아웃 등 - - 서비스가 잘 동작하는지에 대한 자세한 인사이트 (레이턴시, 오류율, 초당 요청 수, 요청량 등) - - mTLS과 같은 보안 기능을 위해 서비스 메시를 구현하고 활용하고자 합니다. - -### 더 간단한 사용 사례를 위해 쿠버네티스 네트워크 정책을 선택하세요 - -- 서로 통신할 수 있는 파드를 제한하세요. -- 네트워크 정책은 서비스 메시보다 필요한 리소스가 적기 때문에 단순한 사용 사례나 서비스 메시의 실행 및 관리 오버헤드가 정당하지 않을 수 있는 소규모 클러스터에 적합합니다. - -!!! tip - 네트워크 정책과 서비스 메시를 함께 사용할 수도 있습니다. 네트워크 정책을 사용하여 파드 간에 기본 수준의 보안 및 격리를 제공한 다음 서비스 메시를 사용하여 트래픽 관리, 관찰 가능성 및 보안과 같은 추가 기능을 추가합니다. - -## 서드파티 네트워크 정책 엔진 - -글로벌 네트워크 정책, DNS 호스트 이름 기반 규칙 지원, 계층 7 규칙, 서비스 어카운트 기반 규칙, 명시적 거부/로그 작업 등과 같은 고급 정책 요구 사항이 있는 경우 타사 네트워크 정책 엔진을 고려해 보십시오. [Calico](https://docs.projectcalico.org/introduction/)는 EKS와 잘 작동하는 [Tigera](https://tigera.io)의 오픈 소스 정책 엔진입니다. Calico는 Kubernetes 네트워크 정책 기능 전체를 구현하는 것 외에도 Istio와 통합될 경우 계층 7 규칙 (예: HTTP)에 대한 지원을 포함하여 더 다양한 기능을 갖춘 확장 네트워크 정책을 지원합니다. Calico 정책의 범위는 네임스페이스, 파드, 서비스 어카운트 또는 전 세계로 지정할 수 있습니다. 정책 범위를 서비스 어카운트으로 지정하면 수신/송신 규칙 집합이 해당 서비스 어카운트과 연결됩니다. 적절한 RBAC 규칙을 적용하면 팀에서 이런 규칙을 재정의하는 것을 방지하여 IT 보안 전문가가 네임스페이스 관리를 안전하게 위임할 수 있습니다. 마찬가지로 [Cilium](https://cilium.readthedocs.io/en/stable/intro/)의 관리자들도 HTTP와 같은 계층 7 규칙에 대한 부분적 지원을 포함하도록 네트워크 정책을 확장했습니다. 또한 Cilium은 DNS 호스트 이름을 지원하는데, 이는 쿠버네티스 서비스/파드와 VPC 내부 또는 외부에서 실행되는 리소스 간의 트래픽을 제한하는 데 유용할 수 있다. 반대로 Calico Enterprise에는 쿠버네티스 네트워크 정책을 AWS 보안 그룹과 DNS 호스트 이름에 매핑할 수 있는 기능이 포함되어 있습니다. - -[이 Github 프로젝트](https://github.com/ahmetb/kubernetes-network-policy-recipes)에서 일반적인 쿠버네티스 네트워크 정책 목록을 찾을 수 있습니다. Calico에 대한 유사한 규칙 세트는 [Calico 문서](https://docs.projectcalico.org/security/calico-network-policy)에서 확인할 수 있습니다. - -### Amazon VPC CNI 네트워크 정책 엔진으로 마이그레이션 - -일관성을 유지하고 예상치 못한 파드 통신 동작을 방지하려면 클러스터에 네트워크 정책 엔진을 하나만 배포하는 것이 좋습니다. 3P에서 VPC CNI 네트워크 정책 엔진으로 마이그레이션하려는 경우 VPC CNI 네트워크 정책 지원을 활성화하기 전에 기존 3P 네트워크 정책 CRD를 쿠버네티스 네트워크 정책 리소스로 변환하는 것이 좋습니다. 또한 마이그레이션된 정책을 프로덕션 환경에 적용하기 전에 별도의 테스트 클러스터에서 테스트하세요. 이를 통해 파드 통신 동작의 잠재적 문제나 불일치를 식별하고 해결할 수 있습니다. - -#### 마이그레이션 도구 - -마이그레이션 프로세스를 지원하기 위해 기존 Calico/Cilium 네트워크 정책 CRD를 쿠버네티스 네이티브 네트워크 정책으로 변환하는 [K8s Network Policy Migrator](https://github.com/awslabs/k8s-network-policy-migrator) 도구를 개발했습니다. 변환 후에는 VPC CNI 네트워크 정책 컨트롤러를 실행하는 새 클러스터에서 변환된 네트워크 정책을 직접 테스트할 수 있습니다. 이 도구는 마이그레이션 프로세스를 간소화하고 원활한 전환을 보장하도록 설계되었습니다. - -!!! 중요 - 마이그레이션 도구는 네이티브 쿠버네티스 네트워크 정책 API와 호환되는 서드파티 정책만 변환합니다. 서드파티 플러그인이 제공하는 고급 네트워크 정책 기능을 사용하는 경우 마이그레이션 도구는 해당 기능을 건너뛰고 보고합니다. - -참고로, 마이그레이션 도구는 현재 AWS VPC CNI 네트워크 정책 엔지니어링 팀에서 지원하지 않으며, 고객이 최선의 노력을 기울여 사용할 수 있도록 만들어졌습니다. 마이그레이션 프로세스를 원활하게 진행하려면 이 도구를 활용하는 것이 좋습니다. 도구에서 문제나 버그가 발생하는 경우 [Github 이슈](https://github.com/awslabs/k8s-network-policy-migrator/issues)를 생성해 주시기 바랍니다. 여러분의 피드백은 우리에게 매우 소중하며 서비스를 지속적으로 개선하는 데 도움이 됩니다. - -### 추가 리소스 - -- [Kubernetes & Tigera: 네트워크 정책, 보안 및 감사](https://youtu.be/lEY2WnRHYpg) -- [Calico Enterprise](https://www.tigera.io/tigera-products/calico-enterprise/) -- [Cilium](https://cilium.readthedocs.io/en/stable/intro/) -- [NetworkPolicy Editor](https://cilium.io/blog/2021/02/10/network-policy-editor) Cilium의 대화형 정책 편집자 -- [Inspektor Gadget advise network-policy gadget](https://www.inspektor-gadget.io/docs/latest/gadgets/advise/network-policy/)는 네트워크 트래픽 분석을 기반으로 네트워크 정책을 제안합니다. - -## 전송 암호화 - -PCI, HIPAA 또는 기타 규정을 준수해야 하는 애플리케이션은 전송 중에 데이터를 암호화해야 합니다. 오늘날 TLS는 유선 트래픽을 암호화하기 위한 사실상 표준 방식입니다. TLS는 이전 SSL과 마찬가지로 암호화 프로토콜을 사용하여 네트워크를 통해 보안 통신을 제공합니다. TLS는 세션 시작 시 협상되는 공유 암호를 기반으로 데이터를 암호화하는 키를 생성하는 대칭 암호화를 사용합니다. 다음은 쿠버네티스 환경에서 데이터를 암호화할 수 있는 몇 가지 방법입니다. - -### Nitro 인스턴스 - -다음 Nitro 인스턴스 유형 (예: C5n, G4, I3en, M5dn, M5n, P3dn, R5dn, R5n)간에 교환되는 트래픽은 기본적으로 자동 암호화됩니다. Transit Gateway 또는 로드밸런서와 같이 중간 홉이 있는 경우 트래픽은 암호화되지 않습니다. 전송 중 암호화에 대한 자세한 내용과 기본적으로 네트워크 암호화를 지원하는 인스턴스 유형의 전체 목록은 [전송 암호화 문서](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/data-protection.html#encryption-transit)를 참조하십시오. - -### 컨테이너 네트워크 인터페이스(CNI) - -[WeAvenet](https://www.weave.works/oss/net/)은 슬리브 트래픽(더 느린 패킷 포워딩 접근 방식)에는 NaCL 암호화를 사용하고 빠른 데이터 경로 트래픽에는 IPsec ESP를 사용하여 모든 트래픽을 자동으로 암호화하도록 구성할 수 있습니다. - -### 서비스 메시 - -전송 중 암호화는 AppMesh, Linkerd v2 및 Istio와 같은 서비스 메시를 사용하여 구현할 수도 있습니다. AppMesh는 X.509 인증서 또는 Envoy의 비밀 검색 서비스(SDS)를 사용하는 [mTLS](https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html)를 지원합니다. Linkerd와 Istio 모두 mTLS를 지원합니다. - -[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) GitHub 리포지토리는 X.509 인증서 및 SPIRE를 Envoy 컨테이너와 함께 SDS 공급자로 사용하여 MTL을 구성하는 방법을 제공합니다: - -- [X.509 인증서를 사용하여 mTLS 구성](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-file-based) -- [SPIRE (SDS) 를 사용하여 TLS 구성](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-sds-based) - -또한 App Mesh는 [AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html)(ACM)에서 발급한 사설 인증서 또는 가상 노드의 로컬 파일 시스템에 저장된 인증서를 사용하여 [TLS 암호화](https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html)를 지원합니다. - -- [aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) GitHub 리포지토리는 ACM에서 발급한 인증서 및 Envoy 컨테이너와 함께 패키징된 인증서를 사용하여 TLS를 구성하는 방법을 안내합니다: -- [파일 제공 TLS 인증서를 사용하여 TLS 구성](https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/howto-tls-file-provided) -- [AWS Certificate Manager를 사용하여 TLS 구성](https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm) - -### 인그레스 컨트롤러 및 로드밸런서 - -인그레스 컨트롤러는 클러스터 외부에서 발생하는 HTTP/S 트래픽을 클러스터 내에서 실행되는 서비스로 지능적으로 라우팅하는 방법입니다. 이런 인그레스 앞에 CLB(Classic Load Balancer) 또는 NLB(Network Load Balancer)와 같은 레이어 4 로드밸런서가 있는 경우가 많습니다. 암호화된 트래픽은 네트워크 내 여러 위치 (예: 로드밸런서, 인그레스 리소스, 파드) 에서 종료될 수 있다. SSL 연결을 종료하는 방법과 위치는 궁극적으로 조직의 네트워크 보안 정책에 따라 결정됩니다. 예를 들어 엔드 투 엔드 암호화를 요구하는 정책이 있는 경우 Pod에서 트래픽을 해독해야 합니다. 이렇게 되면 파드가 초기 핸드셰이크를 설정하는 데 많은 시간을 소비해야 하므로 파드에 추가적인 부담이 가중됩니다. 전체 SSL/TLS 처리는 CPU 집약도가 매우 높습니다. 따라서 유연성이 있다면 인그레스 또는 로드밸런서에서 SSL 오프로드를 수행해 보세요. - -#### AWS Elastic 로드밸런서를 통한 암호화 사용 - -[AWS Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html)(ALB) 및 [Network Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html)(NLB) 모두 전송 암호화(SSL 및 TLS)를 지원합니다. ALB에 대한 `alb.ingress.kubernetes.io/certificate-arn` 어노테이션을 사용하면 ALB에 추가할 인증서를 지정할 수 있습니다. 어노테이션을 생략하면 컨트롤러는 호스트 필드를 사용하여 사용 가능한 [AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html)인증서를 일치시켜 인증서를 필요로 하는 리스너에 인증서를 추가하려고 시도합니다. EKS v1.15부터 아래 예와 같이 NLB와 함께 `service.beta.kubernetes.io/aws-load-balancer-ssl-cert` 어노테이션을 사용할 수 있습니다. - -```yaml -apiVersion: v1 -kind: Service -metadata: - name: demo-app - namespace: default - labels: - app: demo-app - annotations: - service.beta.kubernetes.io/aws-load-balancer-type: "nlb" - service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "" - service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" - service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" -spec: - type: LoadBalancer - ports: - - port: 443 - targetPort: 80 - protocol: TCP - selector: - app: demo-app ---- -kind: Deployment -apiVersion: apps/v1 -metadata: - name: nginx - namespace: default - labels: - app: demo-app -spec: - replicas: 1 - selector: - matchLabels: - app: demo-app - template: - metadata: - labels: - app: demo-app - spec: - containers: - - name: nginx - image: nginx - ports: - - containerPort: 443 - protocol: TCP - - containerPort: 80 - protocol: TCP -``` - -다음은 SSL/TLS 종료에 대한 추가 예입니다. - -- [Securing EKS Ingress With Contour And Let’s Encrypt The GitOps Way](https://aws.amazon.com/blogs/containers/securing-eks-ingress-contour-lets-encrypt-gitops/) -- [How do I terminate HTTPS traffic on Amazon EKS workloads with ACM?](https://aws.amazon.com/premiumsupport/knowledge-center/terminate-https-traffic-eks-acm/) - -!!! caution - AWS LB 컨트롤러와 같은 일부 인그레스는 인그레스 사양의 일부가 아닌 어노테이션을 사용하여 SSL/TLS를 구현합니다. - -### ACM Private CA 연동 (cert-manager) - -인증서를 배포, 갱신 및 취소하는 인기 있는 쿠버네티스 애드온인 ACM Private Certificate Authority(CA) 및 [cert-manager](https://cert-manager.io/)를 사용하여 수신, 파드, 파드 간에 EKS 애플리케이션 워크로드를 보호하도록 TLS와 mTLS를 활성화할 수 있습니다. ACM Private CA는 자체 CA를 관리하는 데 드는 선결제 및 유지 관리 비용이 없는 가용성이 높고 안전한 관리형 CA입니다. 기본 쿠버네티스 인증 기관을 사용하는 경우 ACM Private CA를 통해 보안을 개선하고 규정 준수 요구 사항을 충족할 수 있습니다. ACM Private CA는 FIPS 140-2 레벨 3 하드웨어 보안 모듈에서 프라이빗 키를 보호합니다(매우 안전함). 이는 메모리에 인코딩된 키를 저장하는 기본 CA (보안 수준이 낮음)와 비교하면 매우 안전합니다. 또한 중앙 집중식 CA를 사용하면 쿠버네티스 환경 내부 및 외부에서 사설 인증서를 더 잘 제어하고 감사 기능을 개선할 수 있습니다. - -#### 워크로드 간 상호 TLS를 위한 짧은 수명의 CA 모드 - -EKS 환경에서에서 mTLS용 ACM Private CA를 사용할 때는 _수명이 짧은 CA 모드_와 함께 수명이 짧은 인증서를 사용하는 것이 좋습니다. 범용 CA 모드에서 수명이 짧은 인증서를 발급할 수 있지만 새 인증서를 자주 발급해야 하는 사용 사례에서는 수명이 짧은 CA 모드를 사용하는 것이 더 비용 효율적입니다 (일반 모드보다 최대 75% 저렴). 이 외에도 사설 인증서의 유효 기간을 EKS 클러스터의 파드 수명에 맞춰 조정해야 합니다 [여기에서 ACM Private CA와 그 이점에 대해 자세히 알아보십시오](https://aws.amazon.com/certificate-manager/private-certificate-authority/). - -#### ACM 구성 가이드 - -먼저 [ACM Private CA 문서](https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html)에 제공된 절차에 따라 Private CA를 생성하십시오. Private CA를 만든 후에는 [cert-manager 설치 가이드](https://cert-manager.io/docs/installation/) 절차에 따라 cert-manager를 설치하십시오. cert-manager를 설치한 후 [GitHub의 설정 가이드](https://github.com/cert-manager/aws-privateca-issuer#setup)에 따라 Private CA 쿠버네티스 인증서 관리자 플러그인을 설치합니다. 플러그인을 사용하면 인증서 관리자가 ACM Private CA에 사설 인증서를 요청할 수 있습니다. - -이제 cert-manager와 플러그인이 설치된 사설 CA와 EKS 클러스터를 만들었으니, 권한을 설정하고 발급자를 생성할 차례입니다. ACM 사설 CA에 대한 액세스를 허용하도록 EKS 노드 역할의 IAM 권한을 업데이트하십시오. ``를 사설 CA의 값으로 바꾸십시오. - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "awspcaissuer", - "Action": [ - "acm-pca:DescribeCertificateAuthority", - "acm-pca:GetCertificate", - "acm-pca:IssueCertificate" - ], - "Effect": "Allow", - "Resource": "" - } - ] -} -``` - -[서비스 어카운트용 IAM 역할(IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)도 사용할 수 있습니다. 전체 예는 아래의 추가 리소스 섹션을 참조하십시오. - -아래 예제의 내용을 포함한 `cluster-issuer.yaml` CRD 파일을 생성하고 `` 및 `` 영역을 Private CA 정보로 대체하여 Amazon EKS에서 발급자를 생성합니다. - -```yaml -apiVersion: awspca.cert-manager.io/v1beta1 -kind: AWSPCAClusterIssuer -metadata: - name: demo-test-root-ca -spec: - arn: - region: -``` - -Deploy the Issuer you created. - -```bash -kubectl apply -f cluster-issuer.yaml -``` - -EKS 클러스터는 사설 CA에서 인증서를 요청하도록 구성되어 있습니다. 이제 cert-manager의 `Certificate` 리소스를 사용하여 `IssuerRef` 필드 값을 위에서 만든 사설 CA 발급자로 변경하여 인증서를 발급할 수 있습니다. 인증서 리소스를 지정하고 요청하는 방법에 대한 자세한 내용은 cert-manager의 [인증서 리소스 가이드](https://cert-manager.io/docs/usage/certificate/)를 참조하십시오. [다음 예제를 참조하세요.](https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/). - -### ACM Private CA 연동 (Istio 및 cert-manager) - -EKS 클러스터에서 Istio를 실행하는 경우 Istio 컨트롤 플레인 (특히 'istiod') 이 루트 인증 기관 (CA) 으로 작동하지 않도록 설정하고 ACM Private CA를 워크로드 간 MTL의 루트 CA로 구성할 수 있습니다. 이 방법을 사용하려는 경우 ACM Private CA에서 _단기 CA 모드_를 사용하는 것이 좋습니다. 자세한 내용은 [이전 섹션](#워크로드-간-상호-tls를-위한-짧은-수명의-ca-모드) 및 이 [블로그](https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode)를 참조하십시오. - -#### Istio에서 인증서 서명 작동 방식 (기본방식) - -쿠버네티스의 워크로드는 서비스 어카운트를 사용하여 식별됩니다. 서비스 어카운트를 지정하지 않으면 쿠버네티스는 워크로드에 서비스 어카운트를 자동으로 할당합니다. 또한 서비스 어카운트는 관련 토큰을 자동으로 마운트합니다. 이 토큰은 서비스 어카운트에서 쿠버네티스 API에 대한 인증을 위한 워크로드에 사용됩니다. 서비스 어카운트는 쿠버네티스의 ID로 충분할 수 있지만 Istio에는 자체 ID 관리 시스템과 CA가 있습니다. Envoy 사이드카 프록시로 워크로드를 시작하는 경우 Istio에서 할당한 ID가 있어야 해당 워크로드가 신뢰할 수 있는 것으로 간주되고 메시의 다른 서비스와 통신할 수 있습니다. - -Istio에서 이 ID를 가져오기 위해 'istio-agent'는 인증서 서명 요청(또는 CSR) 이라는 요청을 Istio 컨트롤 플레인에 보냅니다. 이 CSR에는 처리 전에 워크로드의 ID를 확인할 수 있도록 서비스 어카운트 토큰이 포함되어 있습니다. 이 확인 프로세스는 등록 기관(또는 RA)과 CA 역할을 모두 하는 'istiod'에 의해 처리됩니다. RA는 검증된 CSR만 CA에 전달되도록 하는 게이트키퍼 역할을 합니다. CSR이 확인되면 CA로 전달되며 CA는 서비스 어카운트과 함께 [SPIFFE](https://spiffe.io/) ID가 포함된 인증서를 발급합니다. 이 인증서를 SPIFE 검증 가능한 ID 문서(또는 SVID) 라고 합니다. SVID는 요청 서비스에 할당되어 식별을 목적으로 하고 통신 서비스 간에 전송되는 트래픽을 암호화합니다. - -![Istio 인증서 서명 요청의 기본 흐름](./images/default-istio-csr-flow.png) - -#### ACM Private CA를 사용하여 Istio에서 인증서 서명이 작동하는 방식 - -Istio 인증서 서명 요청 에이전트 ([istio-csr](https://cert-manager.io/docs/projects/istio-csr/))라는 인증서 관리 애드온을 사용하여 Istio를 ACM 사설 CA와 통합할 수 있습니다. 이 에이전트를 사용하면 인증서 관리자 발급자(이 경우 ACM Private CA)를 통해 Istio 워크로드와 컨트롤 플레인 구성 요소를 보호할 수 있습니다. _istio-csr_ 에이전트는 수신 CSR을 검증하는 기본 구성에서 _istiod_가 제공하는 것과 동일한 서비스를 제공합니다. 단, 확인 후에는 요청을 인증서 관리자가 지원하는 리소스(예: 외부 CA 발급자와의 통합)로 변환합니다. - -워크로드에서 CSR이 수신될 때마다 해당 CSR은 _istio-csr_로 전달되며, 이 CSR은 ACM 사설 CA로부터 인증서를 요청합니다. _istio-csr_와 ACM Private CA 간의 이런 통신은 [AWS Private CA 발급자 플러그인](https://github.com/cert-manager/aws-privateca-issuer)을 통해 활성화됩니다. 인증서 관리자는 이 플러그인을 사용하여 ACM 사설 CA에 TLS 인증서를 요청합니다. 발급자 플러그인은 ACM 사설 CA 서비스와 통신하여 워크로드에 대한 서명된 인증서를 요청합니다. 인증서가 서명되면 이 인증서는 _istio-csr_로 반환되며, 그러면 서명된 요청을 읽고 CSR을 시작한 워크로드에 해당 요청을 반환합니다. - -![istio-csr를 사용한 Istio 인증서 서명 요청 흐름](./images/istio-csr-with-acm-private-ca.png) - -#### 사설 CA가 포함된 Istio 구성 가이드 - -1. 먼저 [이 섹션의 설정 지침](#acm-private-ca-연동-istio-및-cert-manager) 에 따라 다음을 완료하십시오.: -2. 사설 CA 생성 -3. cert-manager 설치 -4. 발급자 플러그인 설치 -5. 권한을 설정하고 발급자를 생성합니다. 발급자는 CA를 나타내며 'istiod' 및 메시 워크로드 인증서에 서명하는 데 사용됩니다. ACM 사설 CA와 통신합니다. -6. 'Istio-system' 네임스페이스를 생성합니다. 여기에 'istiod 인증서'와 기타 Istio 리소스가 배포됩니다. -7. AWS 사설 CA 발급자 플러그인으로 구성된 Istio CSR을 설치합니다.워크로드에 대한 인증서 서명 요청을 보존하여 승인 및 서명 여부를 확인할 수 있습니다 (`PerveCertificateRequests=true`). - - ```bash - helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \ - --set "app.certmanager.issuer.group=awspca.cert-manager.io" \ - --set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \ - --set "app.certmanager.issuer.name=" \ - --set "app.certmanager.preserveCertificateRequests=true" \ - --set "app.server.maxCertificateDuration=48h" \ - --set "app.tls.certificateDuration=24h" \ - --set "app.tls.istiodCertificateDuration=24h" \ - --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \ - --set "volumeMounts[0].name=root-ca" \ - --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ - --set "volumes[0].name=root-ca" \ - --set "volumes[0].secret.secretName=istio-root-ca" - ``` - -8. 'istiod'를 'cert-manager istio-csr'로 바꾼 사용자 지정 설정으로 메시의 인증서 공급자로 Istio를 설치하세요. 이 프로세스는 [Istio 오퍼레이터](https://tetrate.io/blog/what-is-istio-operator/)를 사용하여 수행할 수 있습니다. - - ```yaml - apiVersion: install.istio.io/v1alpha1 - kind: IstioOperator - metadata: - name: istio - namespace: istio-system - spec: - profile: "demo" - hub: gcr.io/istio-release - values: - global: - # Change certificate provider to cert-manager istio agent for istio agent - caAddress: cert-manager-istio-csr.cert-manager.svc:443 - components: - pilot: - k8s: - env: - # Disable istiod CA Sever functionality - - name: ENABLE_CA_SERVER - value: "false" - overlays: - - apiVersion: apps/v1 - kind: Deployment - name: istiod - patches: - - # Mount istiod serving and webhook certificate from Secret mount - - path: spec.template.spec.containers.[name:discovery].args[7] - value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt" - - path: spec.template.spec.containers.[name:discovery].args[8] - value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key" - - path: spec.template.spec.containers.[name:discovery].args[9] - value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem" - - - path: spec.template.spec.containers.[name:discovery].volumeMounts[6] - value: - name: cert-manager - mountPath: "/etc/cert-manager/tls" - readOnly: true - - path: spec.template.spec.containers.[name:discovery].volumeMounts[7] - value: - name: ca-root-cert - mountPath: "/etc/cert-manager/ca" - readOnly: true - - - path: spec.template.spec.volumes[6] - value: - name: cert-manager - secret: - secretName: istiod-tls - - path: spec.template.spec.volumes[7] - value: - name: ca-root-cert - configMap: - defaultMode: 420 - name: istio-ca-root-cert - ``` - -9. 생성한 위의 사용자 지정 리소스(CRD)를 배포합니다. - - ```bash - istioctl operator init - kubectl apply -f istio-custom-config.yaml - ``` - -10. 이제 EKS 클러스터의 메시에 워크로드를 배포하고 [mTLS를 적용](https://istio.io/latest/docs/reference/config/security/peer_authentication/)할 수 있습니다. - -![Istio 인증서 서명 요청](./images/istio-csr-requests.png) - -## 도구 및 리소스 - -- [cert-manager 및 ACM Private CA 플러그인을 구현하여 EKS에서 TLS를 활성화하는 방법](https://aws.amazon.com/blogs/security/tls-enabled-kubernetes-clusters-with-acm-private-ca-and-amazon-eks-2/). -- [새로운 AWS Load Balancer Controller 및 ACM Private CA를 사용하여 Amazon EKS에서 엔드-투-엔드 TLS 암호화 설정](https://aws.amazon.com/blogs/containers/setting-up-end-to-end-tls-encryption-on-amazon-eks-with-the-new-aws-load-balancer-controller/). -- [Private CA 쿠버네티스 cert-manager 플러그인 (Github)](https://github.com/cert-manager/aws-privateca-issuer). -- [Private CA 쿠버네티스 cert-manager 플러그인 사용자 가이드](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaKubernetes.html). -- [AWS Private Certificate Authority 단기 인증서 모드 사용 방법](https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode) -- [kniff 및 Wireshark를 사용한 쿠버네티스의 서비스 메시 TLS 검증](https://itnext.io/verifying-service-mesh-tls-in-kubernetes-using-ksniff-and-wireshark-2e993b26bf95) -- [ksniff](https://github.com/eldadru/ksniff) -- [egress-operator](https://github.com/monzo/egress-operator) 프로토콜 검사 없이 클러스터의 송신 트래픽을 제어하는 오퍼레이터 및 DNS 플러그인 diff --git a/content/security/docs/pods.ko.md b/content/security/docs/pods.ko.md deleted file mode 100644 index d690b9a53..000000000 --- a/content/security/docs/pods.ko.md +++ /dev/null @@ -1,466 +0,0 @@ -# 파드 보안 - -파드 사양에는 전반적인 보안 태세를 강화하거나 약화시킬 수 있는 다양한 속성이 포함되어 있습니다. 쿠버네티스 실무자로서 주요 관심사는 컨테이너에서 실행 중인 프로세스가 컨테이너 런타임의 격리 경계를 벗어나 기본 호스트에 대한 액세스 권한을 얻지 못하도록 하는 것입니다. - -## 리눅스 기능 - -컨테이너 내에서 실행되는 프로세스는 기본적으로 \[Linux\] 루트 사용자의 컨텍스트에서 실행됩니다. 컨테이너 내의 루트 작업은 컨테이너 런타임이 컨테이너에 할당하는 리눅스 기능 세트에 의해 부분적으로 제한되지만 이런 기본 권한을 통해 공격자는 권한을 에스컬레이션하거나 호스트에 바인딩된 민감한 정보에 액세스할 수 있습니다. 비밀 및 컨피그맵을 포함합니다. 다음은 컨테이너에 할당된 기본 기능 목록입니다. 각 기능에 대한 추가 정보는 [해당 문서](http://man7.org/linux/man-pages/man7/capabilities.7.html)를 참조하십시오. - -`CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT` - -!!! info - - EC2 및 Fargate 파드에는 기본적으로 앞서 언급한 기능이 할당됩니다. 또한 Linux 기능은 Fargate 파드에서만 삭제할 수 있습니다. - -Privileged 권한으로 실행되는 파드는 호스트의 루트와 연결된 Linux 기능의 _모든 권한_ 을 상속합니다. 가능한 해당 권한으로 실행은 지양하여야 합니다. - -### 노드 승인 - -모든 쿠버네티스 워커 노드는 [노드 인증](https://kubernetes.io/docs/reference/access-authn-authz/node/)이라는 권한 부여 모드를 사용합니다.노드 인증은 kubelet에서 시작되는 모든 API 요청을 승인하고 노드가 다음 작업을 수행할 수 있도록 합니다. - -읽기 작업: - -- 서비스 -- 엔드포인트 -- 노드 -- 파드 -- kubelet의 노드에 바인딩된 파드와 관련된 시크릿, 컨피그맵, 퍼시스턴트 볼륨 클레임 및 퍼시스턴트 볼륨 - -쓰기 작업: - -- 노드 및 노드 상태( `NodeRestriction` 어드미션 플러그인을 활성화하여 kubelet이 자신의 노드를 수정하도록 제한) -- 파드 및 파드 상태( `NodeRestriction` 어드미션 플러그인을 활성화하여 kubelet이 자신에게 바인딩된 pod를 수정하도록 제한) -- 이벤트 - -인증 관련 작업: - -- TLS 부트스트래핑을 위한 인증서 서명 요청(CSR) API에 대한 읽기/쓰기 권한 -- 위임 인증/권한 확인을 위한 TokenReview 및 SubjectAccessReview 생성 권한 - -EKS는 [노드 제한 어드미션 컨트롤러](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction)를 사용하여 노드가 제한된 노드 속성 및 파드 세트만 수정하도록 허용합니다. 노드에 바인딩된 개체입니다. 그럼에도 불구하고 호스트에 대한 액세스를 관리하는 공격자는 클러스터 내에서 측면 이동을 허용할 수 있는 쿠버네티스 API에서 환경에 대한 민감한 정보를 수집할 수 있습니다. - -## 파드 보안 솔루션 - -### 파드 시큐리티 폴리시(PSP) - -과거에는 [파드 시큐리티 폴리시(PSP)](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) 리소스를 사용하여 파드가 충족해야 하는 일련의 요구 사항을 지정했습니다. Kubernetes 버전 1.21부터 PSP는 더 이상 사용되지 않습니다. Kubernetes 버전 1.25에서 제거될 예정입니다. - -!!! attention - - Kubernetes 버전 1.21부터 [PSP는 더 이상 사용되지 않습니다](https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/). P2P가 더이상 지원되지 않을 버전 1.25까지 대안 솔루션으로 전환하는데 대략 2년의 시간이 남았습니다. 이 [문서](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation)는 이런 지원 중단의 동기에 대하여 설명합니다. - -### 새로운 파드 보안 솔루션으로 마이그레이션 - -PSP는 제거될 예정이며 더 이상 활성 개발 중이 아니므로 클러스터 관리자와 운영자는 이런 보안 제어를 교체해야 합니다. 두 가지 솔루션으로 이런 요구를 충족할 수 있습니다. - -- 쿠버네티스 에코시스템 내 PAC(Policy-as-code) 솔루션 -- 쿠버네티스 [파드 시큐리티 스탠다드(PSS)](https://kubernetes.io/docs/concepts/security/pod-security-standards/) - -PAC 및 PSS 솔루션은 모두 PSP와 공존할 수 있습니다. PSP가 제거되기 전에 클러스터에서 사용할 수 있습니다. 따라서 PSP에서 마이그레이션할 때 쉽게 채택할 수 있습니다. PSP에서 PSS로 마이그레이션을 고려하는 경우 이 [문서](https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/)를 참조하세요. - -아래에 설명된 PAC 솔루션 중 하나인 Kyverno는 PSP에서 해당 솔루션으로 마이그레이션할 때 유사한 정책, 기능 비교 및 마이그레이션 절차를 포함하여 [해당 블로그](https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/)에 구체적인 지침을 제공합니다. 파드 시큐리티 어드미션 (PSA)과 관련된 Kyverno로의 마이그레이션에 대한 추가 정보 및 지침은 [AWS 블로그](https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/)에 게시되었습니다. - -### 코드로서의 정책(PAC) - -PAC(Policy-as-code) 솔루션은 규정된 자동 제어를 통해 클러스터 사용자를 안내하고 원치 않는 동작을 방지하는 가드레일을 제공합니다. PAC는 [쿠버네티스 동적 어드미션 컨트롤러](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)를 사용하여 웹훅 호출을 통해 쿠버네티스 API 서버 요청 흐름을 가로채고 변형 및 검증합니다. 코드로 작성되고 저장된 정책을 기반으로 페이로드를 요청합니다. 변형 및 유효성 검사는 API 서버 요청으로 인해 클러스터가 변경되기 전에 발생합니다. PAC 솔루션은 정책을 사용하여 분류 및 값을 기반으로 API 서버 요청 페이로드를 일치시키고 작동합니다. - -Kubernetes에 사용할 수 있는 몇 가지 오픈 소스 PAC 솔루션이 있습니다. 이런 솔루션은 Kubernetes 프로젝트의 일부가 아닙니다. Kubernetes 생태계에서 제공됩니다. 일부 PAC 솔루션은 다음과 같습니다. - -- [OPA/게이트키퍼](https://open-policy-agent.github.io/gatekeeper/website/docs/) -- [오픈 정책 에이전트(OPA)](https://www.openpolicyagent.org/) -- [카이베르노](https://kyverno.io/) -- [Kubewarden](https://www.kubewarden.io/) -- [jsPolicy](https://www.jspolicy.com/) - -PAC 솔루션에 대한 자세한 내용과 필요에 맞는 적절한 솔루션을 선택하는 데 도움이 되는 방법은 아래 링크를 참조하십시오. - -- [쿠버네티스에 대한 정책 기반 대책 - 1부](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/) -- [쿠버네티스를 위한 정책 기반 대책 – 2부](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/) - -### 파드 시큐리티 스탠다드(PSS) 및 파드 시큐리티 어드미션(PSA) - -PSP 지원 중단 및 즉시 사용 가능한 파드 보안을 제어해야 하는 지속적인 필요성에 대응하여 빌트인 쿠버네티스 솔루션으로 쿠버네티스 [Auth Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-auth)는 [파드 시큐리티 스탠다드(PSS)](https://kubernetes.io/docs/concepts/security/pod-security-standards/) 및 [파드 시큐리티 어드미션(PSA)](https://kubernetes.io/docs/concepts/security/pod-security-admission/)을 만들었습니다. PSA 에는 PSS에 정의된 제어를 구현하는 [어드미션 컨트롤러 웹훅 프로젝트](https://github.com/kubernetes/pod-security-admission#pod-security-admission)가 포함됩니다. 이 허용 컨트롤러 접근 방식은 PAC 솔루션에서 사용되는 방식과 유사합니다. - -쿠버네티스 문서에 따르면 PSS는 _"보안 스펙트럼을 광범위하게 포괄하는 세 가지 다른 정책을 정의합니다. 이런 정책은 누적되며 매우 허용적인 것부터 매우 제한적인 것까지 다양합니다."_ - -이런 정책은 다음과 같이 정의됩니다: - -- **Privileged:** 제한되지 않은(안전하지 않은) 정책으로 가능한 가장 광범위한 수준의 권한을 제공합니다. 이 정책은 알려진 권한 에스컬레이션을 허용합니다. 정책이 없다는 것입니다. 이는 로깅 에이전트, CNI, 스토리지 드라이버 및 권한 액세스가 필요한 기타 시스템 전체 애플리케이션과 같은 애플리케이션에 적합합니다. - -- **Baseline:** 알려진 권한 에스컬레이션을 방지하는 최소 제한 정책입니다. 기본(최소 지정) 파드 구성을 허용합니다. 베이스라인 정책은 hostNetwork, hostPID, hostIPC, hostPath, hostPort의 사용, Linux 기능을 추가 제한 등과 같은 기타 몇 가지 제한 사항을 포함합니다. - -- **Restricted:** 현재 파드 강화 모범 사례에 따라 엄격하게 제한된 정책입니다. 이 정책은 기준선에서 상속되며 루트 또는 루트 그룹으로 실행할 수 없는 것과 같은 추가 제한 사항을 추가합니다. 제한된 정책은 애플리케이션의 기능에 영향을 미칠 수 있습니다. 이들은 주로 보안에 중요한 응용 프로그램을 실행하는 것을 목표로 합니다. - -이런 정책은 [파드 실행을 위한 프로파일](https://kubernetes.io/docs/concepts/security/pod-security-standards/#profile-details)을 정의하며, 세 가지 수준의 특권(Priviledged) 액세스에서부터 제한된(Restricted) 액세스로 정렬됩니다. - -PSS에서 정의한 컨트롤을 구현하기 위해 PSA는 세 가지 모드로 작동합니다. - -- **enforce:** 정책을 위반하면 파드가 거부됩니다. - -- **audit:** 정책 위반은 감사 로그에 기록된 이벤트에 대한 감사 어노테이션 추가를 트리거하지만 그렇지 않으면 허용됩니다. - -- **warn:** 정책을 위반하면 사용자에게 경고가 표시되지만 그렇지 않으면 허용됩니다. - -이런 모드와 프로파일 (제한) 수준은 아래 예와 같이 레이블을 사용하여 쿠버네티스 네임스페이스 수준에서 구성됩니다. - -```yaml -apiVersion: v1 -kind: Namespace -metadata: - name: policy-test - labels: - pod-security.kubernetes.io/enforce: restricted -``` - -독립적으로 사용하는 경우 이런 작동 모드는 다른 사용자 경험을 제공하는 다른 응답을 갖습니다. _enforce_ 모드는 각 podSpec이 구성된 제한 수준을 위반하는 경우 파드가 생성되지 않도록 합니다. 그러나 이 모드에서는 PodSpec이 적용된 PSS를 위반하더라도 배포와 같이 파드를 생성하는 파드가 아닌 쿠버네티스 개체가 클러스터에 적용되는 것을 방지하지 않습니다. 이 경우 배포가 적용되지만 파드는 적용되지 않습니다. - -성공적으로 적용된 디플로이머트 객체는 객체 내 파드 생성 실패에 속한다는 즉각적인 표시가 없기 때문에 이를 인지하지 쉽지 않습니다. 위반 podSpec은 파드를 생성하지 않습니다. `kubectl get deploy -oyaml`로 디플로이먼트 리소스를 검사하면 아래와 같이 실패한 파드 `.status.conditions` 엘리먼트의 메시지가 표시된다. - -```yaml -... -status: - conditions: - - lastTransitionTime: "2022-01-20T01:02:08Z" - lastUpdateTime: "2022-01-20T01:02:08Z" - message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest": - allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), - unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), - runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), - seccompProfile (pod or container "test" must set securityContext.seccompProfile.type - to "RuntimeDefault" or "Localhost")' - reason: FailedCreate - status: "True" - type: ReplicaFailure -... -``` - -_audit_ 및 _warn_ 모드에서 파드 제한은 위반 파드가 생성되고 시작되는 것을 막지 않습니다 . 그러나 이런 모드에서는 API 서버 감사 로그 이벤트에 대한 감사 주석 및 API 서버 클라이언트에 대한 경고(예: _kubectl_ )는 파드와 파드를 생성하는 개체에 위반이 있는 podSpec이 포함되어 있을 때 각각 트리거됩니다. `kubectl` _경고_ 메시지는 아래와 같습니다. - -```bash -Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") -deployment.apps/test created -``` - -PSA _audit_ 및 _warn_ 모드는 클러스터 작업에 부정적인 영향을 주지 않고 PSS를 도입할 때 유용합니다. - -PSA 작동 모드는 상호 배타적이지 않으며 누적 방식으로 사용할 수 있습니다. 아래에서 볼 수 있듯이 단일 네임스페이스에서 여러 모드를 구성할 수 있습니다. - -```yaml -apiVersion: v1 -kind: Namespace -metadata: - name: policy-test - labels: - pod-security.kubernetes.io/audit: restricted - pod-security.kubernetes.io/enforce: restricted - pod-security.kubernetes.io/warn: restricted -``` - -위의 예에서 배포를 적용할 때 사용자에게 친숙한 경고 및 감사 주석이 제공되는 반면 위반 적용도 파드 수준에서 제공됩니다. 실제로 여러 PSA 레이블은 아래와 같이 서로 다른 프로파일 수준을 사용할 수 있습니다. - -```yaml -apiVersion: v1 -kind: Namespace -metadata: - name: policy-test - labels: - pod-security.kubernetes.io/enforce: baseline - pod-security.kubernetes.io/warn: restricted -``` - -위의 예에서 PSA는 _baseline_ 프로파일 수준을 충족하는 모든 파드의 생성을 허용한 다음 _restricted_ 프로파일 수준 을 위반하는 파드(및 파드를 생성하는 개체)는 _경고_ 하도록 구성됩니다. 이는 _baseline_ 에서 _restricted_ 프로파일로 변경할 때 가능한 영향을 확인하는 데 유용한 접근 방식입니다. - -#### 기존 파드 - -기존 파드가 있는 네임스페이스가 더 제한적인 PSS 프로파일을 사용하도록 수정되면 _audit_ 및 _warn_ 모드가 적절한 메시지를 생성합니다. 그러나 _enforce_ 모드는 파드를 삭제하지 않습니다. 경고 메시지는 아래와 같습니다. - -```bash -Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest" -Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile -namespace/policy-test configured -``` - -#### 예외 처리 (Exemptions) - -PSA는 _Exemptions_ 를 사용하여 달리 적용되었을 파드에 대한 위반 집행을 제외합니다. 이런 면제는 아래에 나열되어 있습니다. - -- **Usernames:** 예외 처리된 인증(또는 사칭) 사용자 이름을 가진 사용자의 요청은 무시됩니다. - -- **RuntimeClassNames:** 예외 처리된 런타임 클래스 이름을 지정하는 파드 및 워크로드 리소스는 무시됩니다. - -- **네임스페이스:** 예외 처리된 네임스페이스의 파드 및 워크로드 리소스는 무시됩니다. - -이런 예외 처리는 [PSA 어드미션 컨트롤러 구성](https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller)에서 다음과 같이 API 서버 구성의 일부로 정적으로 적용됩니다. - -_Validating Webhook_ 구현에서 예외는 [pod-security-webhook]( https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/50-deployment.yaml ) 컨테이너 내 볼륨으로 마운트되는 쿠버네티스 [컨피그맵](https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/20-configmap.yaml) 리소스 내에서 구성할 수 있습니다. - -```yaml -apiVersion: v1 -kind: ConfigMap -metadata: - name: pod-security-webhook - namespace: pod-security-webhook -data: - podsecurityconfiguration.yaml: | - apiVersion: pod-security.admission.config.k8s.io/v1 - kind: PodSecurityConfiguration - defaults: - enforce: "restricted" - enforce-version: "latest" - audit: "restricted" - audit-version: "latest" - warn: "restricted" - warn-version: "latest" - exemptions: - # Array of authenticated usernames to exempt. - usernames: [] - # Array of runtime class names to exempt. - runtimeClasses: [] - # Array of namespaces to exempt. - namespaces: ["kube-system","policy-test1"] -``` - -위의 컨피그맵 YAML에서 볼 수 있듯이 _audit_ , _enforce_ 및 _warn_ 와 같은 모든 PSA 모드에 대한 클러스터 전체의 기본 PSS 수준은 _restricted_ 로 설정되었습니다. 이는 예외인 `namespaces: ["kube-system","policy-test1"]` 을 제외한 모든 네임스페이스에 영향을 미칩니다 . 또한 아래에 표시된 _ValidatingWebhookConfiguration_ 리소스에서 _pod-security-webhook_ 네임스페이스도 구성된 PSS에서 제외됩니다. - -```yaml -... -webhooks: - # Audit annotations will be prefixed with this name - - name: "pod-security-webhook.kubernetes.io" - # Fail-closed admission webhooks can present operational challenges. - # You may want to consider using a failure policy of Ignore, but should - # consider the security tradeoffs. - failurePolicy: Fail - namespaceSelector: - # Exempt the webhook itself to avoid a circular dependency. - matchExpressions: - - key: kubernetes.io/metadata.name - operator: NotIn - values: ["pod-security-webhook"] -... -``` - -!!! attention - - 파드 시큐리티 어드미션은 쿠버네티스 v1.25에서 안정 버전으로 전환되었습니다. 파드 시큐리티 어드미션 기능이 기본적으로 활성화되기 전에 사용하려면 동적 어드미션 컨트롤러 (뮤테이팅 웹훅) 를 설치해야 했습니다. 웹훅 설치 및 구성 지침은 [본 문서](https://github.com/kubernetes/pod-security-admission/tree/master/webhook)에서 확인할 수 있습니다. - -### PAC(Policy-as-Code)과 파드 시큐리티 스탠다드 중에서(PSS) 선택 - -파드 시큐리티 스탠다드(PSS)는 쿠버네티스에 내장되어 있고 쿠버네티스 에코시스템의 솔루션이 필요하지 않은 솔루션을 제공함으로써 파드 시큐리티 폴리시(PSP)을 대체하기 위해 개발되었습니다. PAC(Policy-as-Code) 솔루션은 훨씬 더 유연합니다. - -다음 장단점 목록은 파드 보안 솔루션에 대해 정보에 입각한 결정을 내리는 데 도움이 되도록 설계되었습니다. - -#### PAC (파드 시큐리티 스탠다드과 비교) - -장점: - -- 보다 유연하고 세분화됨(필요한 경우 리소스 속성까지) -- 파드에만 집중하는 것이 아니라 다양한 리소스 및 액션에 사용할 수 있음 -- 네임스페이스 수준에서만 적용되지 않음 -- 파드 시큐리티 스탠다드보다 더 성숙함 -- 의사결정은 기존 클러스터 리소스 및 외부 데이터(솔루션에 따라 다름)뿐만 아니라 API 서버 요청 페이로드의 모든 항목을 기반으로 할 수 있습니다. -- 유효성 검사 전에 API 서버 요청 변경 지원(솔루션에 따라 다름) -- 보완 정책 및 쿠버네티스 리소스 생성 가능 (솔루션에 따라 다름 - Kyverno는 파드 정책에서 디플로이먼트와 같은 상위 레벨 컨트롤러에 대한 정책을 [자동 생성](https://kyverno.io/docs/writing-policies/autogen/)할 수 있다. 또한 Kyverno는 [Generate Rules](https://kyverno.io/docs/writing-policies/generate/) 를 사용하여 _"새 리소스가 생성되거나 소스가 업데이트될 때"_ 쿠버네티스 리소스를 추가로 생성할 수 있습니다.) -- 쿠버네티스 API 서버를 호출하기 전에 CICD 파이프라인상에서 보다 빠르게 보안을 도입할 수 있습니다(솔루션에 따라 다름). -- 모범 사례, 조직 표준 등과 같이 반드시 보안과 관련되지 않은 동작을 구현하는 데 사용할 수 있습니다. -- 쿠버네티스 이외의 사용 사례에서 사용 가능(솔루션에 따라 다름) -- 유연성으로 인해 사용자 경험을 사용자의 요구에 맞게 조정할 수 있습니다. - -단점: - -- Kubernetes에 빌트인으로 제공되지 않음 -- 학습, 구성 및 지원이 더 복잡함 -- 정책 작성에는 새로운 기술/언어/기능이 필요할 수 있습니다. - -#### 파드 시큐리티 어드미션(PAC과 비교) - -장점: - -- 쿠버네티스에서 빌트인 제공 -- 더 간단한 구성 -- 사용할 새로운 언어나 작성할 정책이 없습니다. -- 클러스터 기본 승인 수준이 _privileged_ 로 구성된 경우 네임스페이스 레이블을 사용하여 파드 보안 프로파일에 네임스페이스를 옵트인할 수 있습니다. - -단점: - -- Policy-as-Code만큼 유연하거나 세분화되지 않음 -- 3개 단계의 제한 방식 제공 -- 주로 파드에 집중 - -#### 요약 - -현재 PSP 이외의 파드 보안 솔루션이 없고 필요한 파드 보안 태세가 파드 시큐리티 스탠다드(PSS) 에 정의된 모델에 맞는다면 PAC 솔루션 대신 PSS를 채택하는 것이 더 쉬울 수 있습니다. 그러나 파드 보안 태세가 PSS 모델에 맞지 않거나 PSS에서 정의한 것 외에 추가 제어를 추가할 계획이라면 PAC 솔루션이 더 적합해 보입니다. - -## 권장 사항 - -### 더 나은 사용자 경험을 위해 여러 파드 시큐리티 어드미션(PSA) 모드 사용 - -앞서 언급했듯이 PSA _enforce_ 모드는 PSS 위반이 있는 파드가 적용되는 것을 방지하지만 디플로이먼트와 같은 상위 수준 컨트롤러를 중지하지는 않습니다. 실제로 파드 적용에 실패했다는 표시 없이 디플로이먼트가 성공적으로 적용됩니다. _kubectl_ 을 사용 하여 디플로이먼트 객체를 검사하고 PSA에서 실패한 파드 메시지를 검색할 수 있지만 사용자 경험이 더 좋을 수 있습니다. 사용자 경험을 개선하려면 여러 PSA 모드(audit, enforce, warn)를 사용해야 합니다. - -```yaml -apiVersion: v1 -kind: Namespace -metadata: - name: policy-test - labels: - pod-security.kubernetes.io/audit: restricted - pod-security.kubernetes.io/enforce: restricted - pod-security.kubernetes.io/warn: restricted -``` - -위의 예에서 _enforce_ 모드가 정의된 경우 각 podSpec에서 PSS 위반이 있는 배포 매니페스트를 쿠버네티스 API 서버에 적용하려고 하면 배포가 성공적으로 적용되지만 파드는 적용되지 않습니다. 그리고 _audit_ 및 _warn_ 모드도 활성화되어 있으므로 API 서버 클라이언트는 경고 메시지를 수신하고 API 서버 감사 로그 이벤트에도 메시지가 표시됩니다. - -### Previleged 권한으로 실행할 수 있는 컨테이너 제한 - -언급한 바와 같이 Previleged 권한으로 실행되는 컨테이너는 호스트의 루트에 할당된 모든 Linux 기능을 상속합니다. 컨테이너가 제대로 작동하기 위해 이런 유형의 권한이 필요한 경우는 거의 없습니다. 컨테이너의 권한과 기능을 제한하는 데 사용할 수 있는 여러 가지 방법이 있습니다. - -!!! attention - - Fargate는 파드의 컨테이너가 AWS가 관리하는 인프라에서 실행되는 "서버리스"형태로 컨테이너를 실행할 수 있는 기능을 제공합니다. Fargate를 사용하면 Previleged 컨테이너를 실행하거나 hostNetwork 또는 hostPort를 사용하도록 파드를 구성할 수 없습니다. - -### 컨테이너에서 루트로 프로세스를 실행하지 마십시오 - -모든 컨테이너는 기본적으로 루트로 실행됩니다. 이는 공격자가 애플리케이션의 취약성을 악용하고 실행 중인 컨테이너에 대한 셸 액세스 권한을 얻을 수 있는 경우 문제가 될 수 있습니다. 다양한 방법으로 이 위험을 완화할 수 있습니다. 먼저 컨테이너 이미지에서 셸(Shell)을 제거합니다. 둘째, Dockerfile에 USER 지시문을 추가하거나 루트가 아닌 사용자로 파드의 컨테이너를 실행합니다. Kubernetes podSpec에는 `spec.securityContext` 아래에 애플리케이션을 실행할 사용자 및/또는 그룹을 지정할 수 있는 일련의 필드가 포함되어 있습니다. 이런 필드는 각각 `runAsUser` 및 `runAsGroup` 입니다. - -`spec.securityContext` 및 관련 요소 의 사용을 강제하기 위해 PAC 정책 또는 파드 시큐리티 스탠다드(PSS)를 클러스터에 추가할 수 있습니다. 이런 솔루션을 사용하면 etcd에 유지되기 전에 인바운드 Kubernetes API 서버 요청 페이로드를 검증할 수 있는 정책 또는 프로파일을 작성 및/또는 사용할 수 있습니다. 또한 PAC 솔루션은 인바운드 요청을 변경하고 경우에 따라 새 요청을 생성할 수 있습니다. - -### Docker에서 Docker를 실행하거나 컨테이너에 소켓을 마운트하지 마십시오 - -이렇게 하면 편리하게 Docker 컨테이너에서 이미지를 빌드/실행할 수 있지만 기본적으로 컨테이너에서 실행 중인 프로세스에 대한 노드의 완전한 제어를 양도하는 것입니다. 쿠버네티스에서 컨테이너 이미지를 빌드해야 하는 경우 [Kaniko](https://github.com/GoogleContainerTools/kaniko), [buildah](https://github.com/containers/buildah), [img](https://github.com/genuinetools/img) 또는 [CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) 같은 빌드 서비스 를 대신 사용할 수 있습니다. - -!!! tip - - 컨테이너 이미지 빌드와 같은 CICD 처리에 사용되는 쿠버네티스 클러스터는 보다 일반화된 워크로드를 실행하는 클러스터와 격리되어야 합니다. - -### hostPath 사용을 제한하거나 hostPath가 필요한 경우 사용할 수 있는 접두사를 제한하고 볼륨을 읽기 전용으로 구성합니다 - -`hostPath` 는 호스트에서 컨테이너로 직접 디렉토리를 마운트하는 볼륨입니다. 파드에 이런 유형의 액세스가 필요한 경우는 거의 없지만 필요한 경우 위험을 인식해야 합니다. 기본적으로 루트로 실행되는 파드는 hostPath에 의해 노출된 파일 시스템에 대한 쓰기 액세스 권한을 갖습니다. 이를 통해 공격자는 kubelet 설정을 수정하고, /etc/shadow와 같이 hostPath에 의해 직접 노출되지 않는 디렉토리 또는 파일에 대한 심볼릭 링크를 생성하고, ssh 키를 설치하고, 호스트에 마운트된 비밀을 읽고, 기타 악의적인 것들을 할 수 있습니다. hostPath의 위험을 완화하려면 `spec.containers.volumeMounts` 를 `readOnly` 로 구성하십시오. 예를 들면 다음과 같습니다. - -```yaml -volumeMounts: -- name: hostPath-volume - readOnly: true - mountPath: /host-path -``` - -또한 PAC 솔루션을 사용하여 `hostPath` 볼륨에서 사용할 수 있는 디렉토리를 제한하거나 `hostPath` 사용을 모두 방지해야 합니다. 파드 시큐리티 스탠다드 _Baseline_ 또는 _Restricted_ 정책을 사용하여 `hostPath` 사용을 방지할 수 있습니다. - -권한 상승의 위험성에 대한 자세한 내용은 Seth Art의 블로그 [Bad Pods: Kubernetes Pod Privilege Escalation](https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation)를 참조하십시오. - -### 리소스 경합 및 DoS 공격을 피하기 위해 각 컨테이너에 대한 요청 및 제한 설정 - -요청이나 제한이 없는 파드는 이론적으로 호스트에서 사용 가능한 모든 리소스를 소비할 수 있습니다. 추가 파드가 노드에 예약되면 노드에서 CPU 또는 메모리 압력이 발생하여 Kubelet이 종료되거나 노드에서 파드가 제거될 수 있습니다. 이런 일이 함께 발생하는 것을 방지할 수는 없지만 요청 및 제한을 설정하면 리소스 경합을 최소화하고 리소스를 과도하게 소비하는 잘못 작성된 애플리케이션으로 인한 위험을 완화하는 데 도움이 됩니다. - -`podSpec` 을 사용하면 CPU 및 메모리에 대한 요청 및 제한을 지정할 수 있습니다. CPU는 초과 신청될 수 있기 때문에 압축 가능한 리소스로 간주됩니다. 메모리는 압축할 수 없습니다. 즉, 여러 컨테이너 간에 공유할 수 없습니다. - -CPU 또는 메모리에 대해 _requests_ 를 지정할 때 본질적으로 컨테이너가 확보할 수 있는 _memory_ 의 양을 지정하는 것입니다. Kubernetes는 파드에 있는 모든 컨테이너의 요청을 집계하여 파드를 예약할 노드를 결정합니다. 컨테이너가 요청된 메모리 양을 초과하면 노드에 메모리 압력이 있으면 종료될 수 있습니다. - -_Limits_ 는 컨테이너가 사용할 수 있는 CPU 및 메모리 리소스의 최대량이며 컨테이너에 대해 생성된 cgroup 의 `memory.limit_in_bytes` 값에 직접 해당합니다. 메모리 제한을 초과하는 컨테이너는 OOM 종료됩니다. 컨테이너가 CPU 제한을 초과하면 제한됩니다. - -!!! tip - -컨테이너 `resources.limits`를 사용하는 경우 컨테이너 리소스 사용량(리소스 풋프린트라고도 함)은 부하 테스트를 기반으로 데이터 기반이고 정확해야 합니다. 정확하고 신뢰할 수 있는 리소스 공간이 없으면 컨테이너 'resources.limits'를 채울 수 있습니다. 예를 들어 'resources.limits.memory'는 잠재적인 메모리 리소스 제한 부정확성을 설명하기 위해 관찰 가능한 최대값보다 20-30% 높게 패딩될 수 있습니다. - -Kubernetes는 세 가지 서비스 품질(QoS) 클래스를 사용하여 노드에서 실행되는 워크로드의 우선 순위를 지정합니다. 여기에는 다음이 포함됩니다. - -- guaranteed -- burstable -- best-effort - -제한 및 요청이 설정되지 않은 경우 파드는 _best-effort_ (가장 낮은 우선 순위)로 구성됩니다. Best-effort 파드는 메모리가 부족할 때 가장 먼저 종료됩니다. 파드 내의 _all_ 컨테이너 에 제한이 설정 되거나 요청 및 제한이 동일한 값으로 설정되고 0이 아닌 경우 파드는 _guaranteed_ (가장 높은 우선 순위)로 구성됩니다. 보장된 파드는 구성된 메모리 제한을 초과하지 않는 한 종료되지 않습니다. 제한 및 요청이 0이 아닌 다른 값으로 구성되거나 파드 내의 한 컨테이너가 제한을 설정하고 다른 컨테이너는 다른 리소스에 대해 제한이 설정되지 않거나 설정된 경우 파드는 _burstable_ (중간 우선 순위)로 구성됩니다. 이런 파드에는 일부 리소스 보장이 있지만 요청된 메모리를 초과하면 종료될 수 있습니다. - -!!! attention - -요청은 컨테이너 cgroup의 `memory_limit_in_bytes` 값에 영향을 미치지 않습니다. cgroup 제한은 호스트에서 사용 가능한 메모리 양으로 설정됩니다. 그럼에도 불구하고 요청 값을 너무 낮게 설정하면 노드가 메모리 압력을 받는 경우 파드가 kubelet에 의해 종료 대상이 될 수 있습니다. - -| 클래스 | 우선순위 | 조건 | 죽이기 조건 | -| :-- | :-- | :-- | :-- | -| Guaranteed | 최고 | 제한 = 요청 != 0 | 메모리 제한만 초과 | -| Burstable | 중간 | 제한 != 요청 != 0 | 요청 메모리를 초과하면 종료됨 | -| Best-Effort| 최저 | 한도 및 요청이 설정되지 않음 | 메모리가 부족할 때 가장 먼저 강제 종료됨 | - -리소스 QoS에 대한 추가 정보는 [쿠버네티스 문서](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/resource-qos.md)를 참조하십시오. - -네임스페이스에 [리소스 할당량](https://kubernetes.io/docs/concepts/policy/resource-quotas/)을 설정하거나 [제한 범위](https://kubernetes.io/docs/concepts/policy/limit-range/)를 생성하여 리소스 요청(request) 및 리소스 제한(limit)을 강제로 사용할 수 있습니다. 리소스 할당량을 사용하면 네임스페이스에 할당된 총 리소스 양 (예: CPU 및 RAM)을 지정할 수 있습니다. 네임스페이스에 적용하면 해당 네임스페이스에 배포된 모든 컨테이너에 대한 리소스 요청 및 리소스 제한을 지정해야 합니다. 반대로 제한 범위를 사용하면 리소스 할당을 더 세밀하게 제어할 수 있습니다. 제한 범위를 사용하면 네임스페이스 내 파드 또는 컨테이너당 CPU 및 메모리 리소스를 최소/최대로 설정할 수 있습니다. 기본 리소스 요청(request)/리소스 제한(limit) 값이 제공되지 않은 경우 이를 사용하여 기본 요청/제한 값을 설정할 수도 있습니다. - -코드형 정책(PAC) 솔루션을 사용하여 요청 및 제한을 적용하거나 네임스페이스를 생성할 때 리소스 할당량 및 제한 범위를 만들 수도 있습니다. - -### 특권 에스컬레이션을 허용하지 않음 - -특권 에스컬레이션을 통해 프로세스는 실행 중인 보안 컨텍스트를 변경할 수 있습니다. Sudo는 SUID 또는 SGID 비트가 있는 바이너리와 마찬가지로 이에 대한 좋은 예입니다. 특권 에스컬레이션은 기본적으로 사용자가 다른 사용자 또는 그룹의 권한으로 파일을 실행하는 방법입니다. `allowPrivilegeEscalation` 을 `false`로 설정하는 정책 코드 변경 정책을 구현하거나 `podSpec`에서 `securityContext.allowPrivilegeEscalation`을 설정하여 컨테이너가 권한 있는 에스컬레이션을 사용하지 못하도록 방지 할 수 있습니다 . Policy-as-code 정책을 사용하여 잘못된 설정이 감지된 경우 API 서버 요청이 성공하지 못하도록 할 수도 있습니다. 파드 시큐리티 스탠다드을 사용하여 파드가 권한 에스컬레이션을 사용하지 못하도록 할 수도 있습니다. - -### ServiceAccount 토큰 탑재 비활성화 - -쿠버네티스 API에 액세스할 필요가 없는 파드의 경우, 파드 스펙 또는 특정 서비스어카운트를 사용하는 모든 파드에 대해 서비스어카운트 토큰의 자동 마운트를 비활성화할 수 있다. - -!!! attention - - 서비스어카운트 마운트를 비활성화해도 파드가 쿠버네티스 API에 네트워크로 액세스하는 것을 막을 수는 없습니다. 파드가 쿠버네티스 API에 네트워크로 액세스하는 것을 방지하려면 [EKS 클러스터 엔드포인트 액세스][eks-ep-access]를 수정하고 [네트워크정책](../network/ #network -policy)를 사용하여 파드 액세스를 차단합니다. - -[eks-ep-access]: https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: pod-no-automount -spec: - automountServiceAccountToken: false -``` - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: sa-no-automount -automountServiceAccountToken: false -``` - -### 서비스 검색 비활성화 - -클러스터 내 서비스를 조회하거나 호출할 필요가 없는 파드의 경우 파드에 제공되는 정보의 양을 줄일 수 있다. CoreDNS를 사용하지 않도록 Pod의 DNS 정책을 설정하고 파드 네임스페이스의 서비스를 환경 변수로 노출하지 않도록 설정할 수 있습니다. 서비스 링크에 대한 자세한 내용은 [환경 변수에 관한 쿠버네티스 문서][k8s-env-var-docs]를 참조하십시오. 파드 DNS 정책의 기본값은 클러스터 내 DNS를 사용하는 "ClusterFirst"이고, 기본값이 아닌 "Default"는 기본 노드의 DNS 확인을 사용합니다. 자세한 내용은 [파드 DNS 정책에 관한 쿠버네티스 문서][dns-policy] 를 참조하십시오. - -[k8s-env-var-docs]: https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables -[dns-policy]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy - -!!! attention - - 서비스 링크를 비활성화하고 파드의 DNS 정책을 변경해도 파드가 클러스터 내 DNS 서비스에 네트워크로 액세스하는 것을 막을 수는 없습니다. - 공격자는 여전히 클러스터 내 DNS 서비스에 접속하여 클러스터의 서비스를 열거할 수 있습니다.(예: `dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP`) 클러스터 내 서비스 검색을 방지하려면 [NetworkPolicy](../network/ #network -policy) 를 사용하여 파드 액세스를 차단합니다. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: pod-no-service-info -spec: - dnsPolicy: Default # "Default" is not the true default value - enableServiceLinks: false -``` - -### 읽기 전용 루트 파일 시스템으로 이미지 구성 - -읽기 전용 루트 파일 시스템으로 이미지를 구성하면 공격자가 애플리케이션에서 사용하는 파일 시스템의 바이너리를 덮어쓰는 것을 방지할 수 있습니다. 애플리케이션이 파일 시스템에 기록해야 하는 경우 임시 디렉터리에 쓰거나 볼륨을 연결하고 마운트하는 것을 고려해 보세요.다음과 같이 파드의 SecurityContext를 설정하여 이를 적용할 수 있다. - -```yaml -... -securityContext: - readOnlyRootFilesystem: true -... -``` - -코드형 정책(PaC) 및 파드 시큐리티 스탠다드를 사용하여 이 동작을 시행할 수 있습니다. - -!!! info - - [쿠버네티스의 Windows 컨테이너](https://kubernetes.io/docs/concepts/windows/intro/) 에 따르면 Windows에서 실행되는 컨테이너의 경우 `SecurityContext.readOnlyRootFileSystem`은 `true`로 설정할 수 없습니다. - 레지스트리 및 시스템 프로세스를 컨테이너 내에서 실행하려면 쓰기 권한이 필요하기 때문입니다. - -## 도구 및 리소스 - -- [open-policy-agent/gatekeeper-library: OPA Gatekeeper 정책 라이브러리](https://github.com/open-policy-agent/gatekeeper-library) PSP 대신 사용할 수 있는 OPA/게이트키퍼 정책 라이브러리입니다. -- [Kyverno 정책 라이브러리](https://kyverno.io/policies/) -- EKS를 위한 공통 OPA 및 Kyverno [정책](https://github.com/aws/aws-eks-best-practices/tree/master/policies) 모음입니다. -- [정책 기반 대책: 파트 1](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/) -- [정책 기반 대책: 파트 2](https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/) -- [Pod Security Policy Migrator](https://appvia.github.io/psp-migration/) PSP를 OPA/Gatekeeper, KubeWarden 또는 Kyverno 정책으로 변환하는 도구입니다. diff --git a/content/security/docs/runtime.ko.md b/content/security/docs/runtime.ko.md deleted file mode 100644 index 26137259d..000000000 --- a/content/security/docs/runtime.ko.md +++ /dev/null @@ -1,77 +0,0 @@ -# 런타임 보안 - -런타임 보안은 컨테이너가 실행되는 동안 컨테이너를 능동적으로 보호합니다. 컨테이너 내부에서 발생하는 악의적인 활동을 탐지 및 방지하는 것이 관건입니다. 이는 리눅스 기능, 보안 컴퓨팅 (seccomp), AppArmor 또는 SELinux와 같이 쿠버네티스와 통합된 리눅스 커널 또는 커널 익스텐션의 여러 메커니즘을 통해 달성할 수 있습니다. Amazon GuardDuty 및 타사 도구와 같은 옵션도 있습니다. 이러한 도구를 사용하면 Linux 커널 메커니즘을 수동으로 구성하지 않고도 기준을 설정하고 이상 활동을 탐지하는 데 도움을 줄 수 있습니다. - -!!! Attention - - 쿠버네티스는 현재 seccomp, AppArmor 또는 SELinux 프로파일을 노드에 로드하기 위한 네이티브 메커니즘을 제공하지 않는다. 수동으로 로드하거나 부트스트랩할 때 노드에 설치해야 합니다. 스케줄러가 어떤 노드에 프로파일이 있는지 인식하지 못하기 때문에 파드에서 참조하기 전에 이 작업을 수행해야 한다.Security Profiles Operator와 같은 도구를 사용하여 프로파일을 노드에 자동으로 프로비저닝하는 방법을 아래에서 확인하세요. - -## 보안 컨텍스트 및 빌트인 쿠버네티스 컨트롤 - -많은 리눅스 런타임 보안 메커니즘은 쿠버네티스와 긴밀하게 통합되어 있으며 쿠버네티스 [보안 컨텍스트](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)를 통해 구성할 수 있습니다. 이러한 옵션 중 하나는 `privileged` 플래그인데, 이 플래그는 기본적으로 `false`이며 활성화되면 기본적으로 호스트의 루트와 동일합니다. 프로덕션 워크로드에서 권한 모드를 활성화하는 것은 거의 항상 부적절하지만, 컨테이너에 적절한 권한을 더 세부적으로 제공할 수 있는 컨트롤은 훨씬 더 많습니다. - -### 리눅스 기능 - -Linux 기능을 사용하면 루트 사용자의 모든 기능을 제공하지 않고도 파드 또는 컨테이너에 특정 기능을 부여할 수 있습니다. 네트워크 인터페이스 또는 방화벽을 구성할 수 있는 `CAP_NET_ADMIN`이나 시스템 클럭을 조작할 수 있는 `CAP_SYS_TIME`이 그런 예입니다. - -### Seccomp - -Seccomp를 사용하면 컨테이너식 애플리케이션이 기본 호스트 운영 체제의 커널에 특정 시스템 호출을 수행하는 것을 방지할 수 있습니다. Linux 운영 체제에는 수백 개의 시스템 호출이 있지만 그 중 대부분은 컨테이너를 실행하는 데 필요하지 않습니다. 컨테이너에서 생성할 수 있는 시스템 호출을 제한하면 애플리케이션의 공격 범위를 효과적으로 줄일 수 있습니다. - -Seccomp는 시스템 호출을 가로채고 허용 목록에 있는 시스템만 통과하도록 하는 방식으로 작동합니다.Docker에는 대부분의 범용 워크로드에 적합한 [디폴트](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) seccomp 프로파일이 있으며, containerd와 같은 다른 컨테이너 런타임도 비슷한 디폴트값을 제공합니다. 파드 사양의 `SecurityContext` 섹션에 다음을 추가하여 컨테이너 또는 파드가 컨테이너 런타임의 디폴트 seccomp 프로파일을 사용하도록 구성할 수 있다. - -```yaml -securityContext: - seccompProfile: - type: RuntimeDefault -``` - -1.22 (Alpha, 1.27부터 Stable)부터, 위의 '런타임디폴트'는 [단일 kubelet 플래그](https://kubernetes.io/docs/tutorials/security/seccomp/#enable-the-use-of-runtimedefault-as-the-default-seccomp-profile-for-all-workloads), `--seccomp-default'를 사용하여 노드의 모든 파드에 사용할 수 있다. 그러면 'SecurityContext'에 지정된 프로파일은 다른 프로파일에만 필요합니다. - -또한 추가 권한이 필요한 항목에 대해 프로파일을 직접 만들 수도 있습니다. 수동으로 작업하기에는 매우 지루할 수 있지만 eBPF 또는 logs와 같은 도구를 사용하여 기본 권한 요구 사항을 seccomp 프로파일로 기록하는 것을 지원하는 [Inspektor Gadget](https://github.com/inspektor-gadget/inspektor-gadget)(네트워크 정책을 생성을 위해 [네트워크 보안 섹션](../network/) 문서에서도 권장) 및 [Security Profiles Operator](https://github.com/inspektor-gadget/inspektor-gadget)와 같은 도구가 있습니다. 또한 Security Profiles Operator를 사용하면 기록된 프로파일을 파드와 컨테이너에서 사용할 수 있도록 노드에 배포하는 작업을 자동화할 수 있다. - -### AppArmor와 SELinux - -AppMor와 SELinux는 [필수 액세스 제어(MAC 시스템)](https://en.wikipedia.org/wiki/Mandatory_access_control)로 알려져 있습니다. 이들은 seccomp와 개념적으로는 비슷하지만 API와 기능이 다르기 때문에 특정 파일 시스템 경로 또는 네트워크 포트 등에 대한 액세스 제어가 가능합니다. 이러한 도구에 대한 지원은 리눅스 배포판에 따라 달라지는데, 데비안/우분투는 AppArmor를 지원하고 RHEL/Centos/BottleRocket/Amazon Linux 2023은 SELinux를 지원합니다. SELinux에 대한 자세한 내용은 [인프라 보안 섹션](../hosts/#run-selinux)를 참조하십시오. - -AppArmor와 SELinux는 모두 쿠버네티스와 통합되어 있지만, 쿠버네티스 1.28부터 AppArmor 프로파일은 [어노테이션](https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod) 을 통해 지정해야 하며, SELinux 레이블은 보안 컨텍스트의 [SELinuxOptions](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#selinuxoptions-v1-core) 필드를 통해 직접 설정할 수 있습니다. - -seccomp 프로파일과 마찬가지로 위에서 언급한 보안 프로파일 운영자는 클러스터의 노드에 프로파일을 배포하는 데 도움을 줄 수 있습니다. (향후 이 프로젝트는 seccomp와 마찬가지로 AppMor 및 SELinux용 프로파일도 생성하는 것을 목표로 하고 있습니다.) - -## 권장 사항 - -### Amazon GuardDuty를 사용하여 런타임 모니터링 및 EKS 환경에 대한 위협을 탐지하십시오 - -현재 EKS 런타임을 지속적으로 모니터링하고, EKS 감사 로그를 분석하고, 멀웨어 및 기타 의심스러운 활동을 검사할 수 있는 솔루션이 없는 경우, Amazon은 AWS 환경을 보호하는 간단하고, 빠르고, 안전하고, 확장 가능하고, 비용 효율적인 원클릭 방법을 원하는 고객에게 [Amazon GuardDuty](https://aws.amazon.com/guardduty/)를 사용할 것을 강력히 권장합니다. Amazon GuardDuty는 AWS CloudTrail 관리 이벤트, AWS CloudTrail 이벤트 로그, VPC 플로우 로그(Amazon EC2 인스턴스 트래픽), 쿠버네티스 감사 로그 및 DNS 로그와 같은 기본 데이터 소스를 분석하고 처리하는 보안 모니터링 서비스입니다. 또한 EKS 런타임 모니터링도 포함됩니다. 지속적으로 업데이트되는 위협 인텔리전스 피드(예: 악성 IP 주소 및 도메인 목록), 기계 학습을 사용하여 AWS 환경 내에서 예상치 못한, 잠재적으로 승인되지 않은 악의적인 활동을 식별합니다. 여기에는 권한 상승, 노출된 자격 증명 사용, 악성 IP 주소, 도메인과의 통신, Amazon EC2 인스턴스 및 EKS 컨테이너 워크로드에 악성코드가 존재하거나 의심스러운 API 활동 발견과 같은 문제가 포함될 수 있습니다. GuardDuty는 GuardDuty 콘솔이나 Amazon EventBridge를 통해 확인할 수 있는 보안 조사 결과를 생성하여 AWS 환경의 상태를 알려줍니다. 또한 GuardDuty는 조사 결과를 Amazon 심플 스토리지 서비스 (S3) 버킷으로 내보내고 AWS Security Hub 및 Detective과 같은 다른 서비스와 통합할 수 있도록 지원합니다. - -위와 관련된 AWS 온라인 테크 토크인 ["Amazon GuardDuty를 통한 Amazon EKS의 향상된 위협 탐지 — AWS 온라인 테크 토크"](https://www.youtube.com/watch?v=oNHGRRroJuE)를 시청하여 이러한 추가 EKS 보안 기능을 몇 분 만에 단계별로 활성화하는 방법을 알아보십시오. - -### 런타임 방어를 위해 타사 솔루션 사용 - -Linux 보안에 익숙하지 않은 경우 seccomp 및 Apparmor 프로파일을 만들고 관리하기 어려울 수 있습니다. 능숙해질 시간이 없다면 상용 솔루션 사용을 고려하십시오. 그들 중 다수는 Apparmor 및 seccomp와 같은 정적 프로파일을 넘어 기계 학습을 사용하여 의심스러운 활동을 차단하거나 경고하기 시작했습니다. 이런 솔루션 중 일부는 아래의 [도구](#도구-및-리소스) 섹션에서 찾을 수 있습니다. 추가 옵션은 [AWS Marketplace for Containers](https://aws.amazon.com/marketplace/features/containers)에서 찾을 수 있습니다. - -### seccomp 정책을 작성하기 전에 Linux 기능 추가/삭제 고려 - -기능에는 시스템 콜이 도달할 수 있는 커널 기능의 다양한 검사가 포함됩니다. 확인에 실패하면 시스템 콜은 일반적으로 오류를 반환합니다. 확인은 특정 syscall의 시작 부분에서 바로 수행하거나 여러 다른 syscall을 통해 도달할 수 있는 커널의 더 깊은 영역(예: 특정 특권 파일에 쓰기)에서 수행할 수 있습니다. 반면에 Seccomp는 실행되기 전에 모든 시스템 콜에 적용되는 시스템 콜 필터입니다. 프로세스는 특정 시스템 콜 또는 특정 시스템 콜에 대한 특정 인수를 실행할 권한을 취소할 수 있는 필터를 설정할 수 있습니다. - -seccomp를 사용하기 전에 Linux 기능 추가/제거가 필요한 제어 기능을 제공하는지 고려하십시오. 자세한 내용은 [를 참조하십시오.](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container) - -### 파드 시큐리티 폴리시(PSP)을 사용하여 목표를 달성할 수 있는지 확인하십시오 - -PSP는 과도한 복잡성을 유발하지 않으면서 보안 태세를 개선할 수 있는 다양한 방법을 제공합니다. seccomp 및 Apparmor 프로파일을 구축하기 전에 PSP에서 사용할 수 있는 옵션을 살펴보세요. - -!!! Warning - 쿠버네티스 1.25부터 PSP가 제거되고 [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) 컨트롤러로 대체되었습니다. 현재 존재하는 타사 대안으로는 OPA/게이트키퍼 및 Kyverno가 있습니다. PSP에서 흔히 볼 수 있는 정책을 구현하기 위한 게이트키퍼 제약 조건 및 제약 조건 템플릿 모음은 GitHub의 [Gatekeeper 라이브러리](https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy) 저장소에서 가져올 수 있습니다. 또한 [Kyverno 정책 라이브러리](https://main.kyverno.io/policies/)에서 [파드 시큐리티 스탠다드(PSS)](https://kubernetes.io/docs/concepts/security/pod-security-standards/)의 전체 컬렉션을 포함하여 PSP를 대체할 수 있는 다양한 제품을 찾을 수 있습니다. - -## 도구 및 리소스 - -+ [시작하기 전에 알아야 할 7가지](https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6) -+ [AppArmor Loader](https://github.com/kubernetes/kubernetes/tree/master/test/images/apparmor-loader) -+ [프로파일을 사용하여 노드 설정](https://kubernetes.io/docs/tutorials/clusters/apparmor/#setting-up-nodes-with-profiles) -+ [Security Profiles Operator](https://github.com/kubernetes-sigs/security-profiles-operator)는 사용자가 쿠버네티스 클러스터에서 SELinux, seccomp 및 AppArmor를 더 쉽게 사용할 수 있도록 하는 것을 목표로 하는 쿠버네티스 개선 사항입니다. 워크로드를 실행하여 프로파일을 생성하고, 프로파일을 쿠버네티스 노드에 로드하여 파드에서 사용할 수 있는 기능을 모두 제공한다. -+ [Inspektor Gadget](https://github.com/inspektor-gadget/inspektor-gadget)를 사용하면 seccomp 프로파일 생성 지원을 포함하여 쿠버네티스에서 런타임 동작의 여러 측면을 검사, 추적 및 프로파일링할 수 있습니다. -+ [Aqua](https://www.aquasec.com/products/aqua-cloud-native-security-platform/) -+ [Qualys](https://www.qualys.com/apps/container-security/) -+ [Stackrox](https://www.stackrox.com/use-cases/threat-detection/) -+ [Sysdig Secure](https://sysdig.com/products/kubernetes-security/) -+ [Prisma](https://docs.paloaltonetworks.com/cn-series) diff --git a/latest/bpg/security/compliance.adoc b/latest/bpg/security/compliance.adoc new file mode 100644 index 000000000..e5a51188f --- /dev/null +++ b/latest/bpg/security/compliance.adoc @@ -0,0 +1,142 @@ +== Compliance + +Compliance is a shared responsibility between AWS and the consumers of +its services. Generally speaking, AWS is responsible for "`security of +the cloud`" whereas its users are responsible for "`security in the +cloud.`" The line that delineates what AWS and its users are responsible +for will vary depending on the service. For example, with Fargate, AWS +is responsible for managing the physical security of its data centers, +the hardware, the virtual infrastructure (Amazon EC2), and the container +runtime (Docker). Users of Fargate are responsible for securing the +container image and their application. Knowing who is responsible for +what is an important consideration when running workloads that must +adhere to compliance standards. + +The following table shows the compliance programs with which the +different container services conform. + +[width="99%",cols="30%,^17%,^17%,^19%,^17%",options="header",] +|=== +|Compliance Program |Amazon ECS Orchestrator |Amazon EKS Orchestrator +|ECS Fargate |Amazon ECR +|PCI DSS Level 1 |1 |1 |1 |1 + +|HIPAA Eligible |1 |1 |1 |1 + +|SOC I |1 |1 |1 |1 + +|SOC II |1 |1 |1 |1 + +|SOC III |1 |1 |1 |1 + +|ISO 27001:2013 |1 |1 |1 |1 + +|ISO 9001:2015 |1 |1 |1 |1 + +|ISO 27017:2015 |1 |1 |1 |1 + +|ISO 27018:2019 |1 |1 |1 |1 + +|IRAP |1 |1 |1 |1 + +|FedRAMP Moderate (East/West) |1 |1 |0 |1 + +|FedRAMP High (GovCloud) |1 |1 |0 |1 + +|DOD CC SRG |1 |DISA Review (IL5) |0 |1 + +|HIPAA BAA |1 |1 |1 |1 + +|MTCS |1 |1 |0 |1 + +|C5 |1 |1 |0 |1 + +|K-ISMS |1 |1 |0 |1 + +|ENS High |1 |1 |0 |1 + +|OSPAR |1 |1 |0 |1 + +|HITRUST CSF |1 |1 |1 |1 +|=== + +Compliance status changes over time. For the latest status, always refer +to https://aws.amazon.com/compliance/services-in-scope/. + +For further information about cloud accreditation models and best +practices, see the AWS whitepaper, +https://d1.awsstatic.com/whitepapers/accreditation-models-for-secure-cloud-adoption.pdf[Accreditation +Models for Secure Cloud Adoption] + +=== Shifting Left + +The concept of shifting left involves catching policy violations and +errors earlier in the software development lifecycle. From a security +perspective, this can be very beneficial. A developer, for example, can +fix issues with their configuration before their application is deployed +to the cluster. Catching mistakes like this earlier will help prevent +configurations that violate your policies from being deployed. + +==== Policy as Code + +Policy can be thought of as a set of rules for governing behaviors, +i.e. behaviors that are allowed or those that are prohibited. For +example, you may have a policy that says that all Dockerfiles should +include a USER directive that causes the container to run as a non-root +user. As a document, a policy like this can be hard to discover and +enforce. It may also become outdated as your requirements change. With +Policy as Code (PaC) solutions, you can automate security, compliance, +and privacy controls that detect, prevent, reduce, and counteract known +and persistent threats. Furthermore, they give you mechanism to codify +your policies and manage them as you do other code artifacts. The +benefit of this approach is that you can reuse your DevOps and GitOps +strategies to manage and consistently apply policies across fleets of +Kubernetes clusters. Please refer to +https://aws.github.io/aws-eks-best-practices/security/docs/pods/#pod-security[Pod +Security] for information about PaC options and the future of PSPs. + +==== Use policy-as-code tools in pipelines to detect violations before deployment + +* https://www.openpolicyagent.org/[OPA] is an open source policy engine +that’s part of the CNCF. It’s used for making policy decisions and can +be run a variety of different ways, e.g. as a language library or a +service. OPA policies are written in a Domain Specific Language (DSL) +called Rego. While it is often run as part of a Kubernetes Dynamic +Admission Controller as the +https://github.com/open-policy-agent/gatekeeper[Gatekeeper] project, OPA +can also be incorporated into your CI/CD pipeline. This allows +developers to get feedback about their configuration earlier in the +release cycle which can subsequently help them resolve issues before +they get to production. A collection of common OPA policies can be found +in the GitHub +https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository] +for this project. +* https://github.com/open-policy-agent/conftest[Conftest] is built on +top of OPA and it provides a developer focused experience for testing +Kubernetes configuration. +* https://kyverno.io/[Kyverno] is a policy engine designed for +Kubernetes. With Kyverno, policies are managed as Kubernetes resources +and no new language is required to write policies. This allows using +familiar tools such as kubectl, git, and kustomize to manage policies. +Kyverno policies can validate, mutate, and generate Kubernetes resources +plus ensure OCI image supply chain security. The +https://kyverno.io/docs/kyverno-cli/[Kyverno CLI] can be used to test +policies and validate resources as part of a CI/CD pipeline. All the +Kyverno community policies can be found on the +https://kyverno.io/policies/[Kyverno website], and for examples using +the Kyverno CLI to write tests in pipelines, see the +https://github.com/kyverno/policies[policies repository]. + +=== Tools and resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/10-regulatory-compliance[Amazon +EKS Security Immersion Workshop - Regulatory Compliance] +* https://github.com/aquasecurity/kube-bench[kube-bench] +* https://github.com/docker/docker-bench-security[docker-bench-security] +* https://aws.amazon.com/inspector/[AWS Inspector] +* https://github.com/kubernetes/community/blob/master/sig-security/security-audit-2019/findings/Kubernetes%20Final%20Report.pdf[Kubernetes +Security Review] A 3rd party security assessment of Kubernetes 1.13.4 +(2019) +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides compliance reporting +and custom compliance checks diff --git a/latest/bpg/security/data.adoc b/latest/bpg/security/data.adoc new file mode 100644 index 000000000..10002f6d8 --- /dev/null +++ b/latest/bpg/security/data.adoc @@ -0,0 +1,246 @@ +== Data encryption and secrets management + +=== Encryption at rest + +There are three different AWS-native storage options you can use with +Kubernetes: +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html[EBS], +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html[EFS], +and https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html[FSx +for Lustre]. All three offer encryption at rest using a service managed +key or a customer master key (CMK). For EBS you can use the in-tree +storage driver or the +https://github.com/kubernetes-sigs/aws-ebs-csi-driver[EBS CSI driver]. +Both include parameters for encrypting volumes and supplying a CMK. For +EFS, you can use the +https://github.com/kubernetes-sigs/aws-efs-csi-driver[EFS CSI driver], +however, unlike EBS, the EFS CSI driver does not support dynamic +provisioning. If you want to use EFS with EKS, you will need to +provision and configure at-rest encryption for the file system prior to +creating a PV. For further information about EFS file encryption, please +refer to +https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html[Encrypting +Data at Rest]. Besides offering at-rest encryption, EFS and FSx for +Lustre include an option for encrypting data in transit. FSx for Lustre +does this by default. For EFS, you can add transport encryption by +adding the `+tls+` parameter to `+mountOptions+` in your PV as in this +example: + +[source,yaml] +---- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: efs-pv +spec: + capacity: + storage: 5Gi + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Retain + storageClassName: efs-sc + mountOptions: + - tls + csi: + driver: efs.csi.aws.com + volumeHandle: +---- + +The https://github.com/kubernetes-sigs/aws-fsx-csi-driver[FSx CSI +driver] supports dynamic provisioning of Lustre file systems. It +encrypts data with a service managed key by default, although there is +an option to provide your own CMK as in this example: + +[source,yaml] +---- +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fsx-sc +provisioner: fsx.csi.aws.com +parameters: + subnetId: subnet-056da83524edbe641 + securityGroupIds: sg-086f61ea73388fb6b + deploymentType: PERSISTENT_1 + kmsKeyId: +---- + +!!! attention As of May 28, 2020 all data written to the ephemeral +volume in EKS Fargate pods is encrypted by default using an +industry-standard AES-256 cryptographic algorithm. No modifications to +your application are necessary as encryption and decryption are handled +seamlessly by the service. + +==== Encrypt data at rest + +Encrypting data at rest is considered a best practice. If you’re unsure +whether encryption is necessary, encrypt your data. + +==== Rotate your CMKs periodically + +Configure KMS to automatically rotate your CMKs. This will rotate your +keys once a year while saving old keys indefinitely so that your data +can still be decrypted. For additional information see +https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html[Rotating +customer master keys] + +==== Use EFS access points to simplify access to shared datasets + +If you have shared datasets with different POSIX file permissions or +want to restrict access to part of the shared file system by creating +different mount points, consider using EFS access points. To learn more +about working with access points, see +https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today, +if you want to use an access point (AP) you’ll need to reference the AP +in the PV’s `+volumeHandle+` parameter. + +!!! attention As of March 23, 2021 the EFS CSI driver supports dynamic +provisioning of EFS Access Points. Access points are +application-specific entry points into an EFS file system that make it +easier to share a file system between multiple pods. Each EFS file +system can have up to 120 PVs. See +https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/[Introducing +Amazon EFS CSI dynamic provisioning] for additional information. + +=== Secrets management + +Kubernetes secrets are used to store sensitive information, such as user +certificates, passwords, or API keys. They are persisted in etcd as +base64 encoded strings. On EKS, the EBS volumes for etcd nodes are +encrypted with +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html[EBS +encryption]. A pod can retrieve a Kubernetes secrets objects by +referencing the secret in the `+podSpec+`. These secrets can either be +mapped to an environment variable or mounted as volume. For additional +information on creating secrets, see +https://kubernetes.io/docs/concepts/configuration/secret/. + +!!! caution Secrets in a particular namespace can be referenced by all +pods in the secret’s namespace. + +!!! caution The node authorizer allows the Kubelet to read all of the +secrets mounted to the node. + +==== Use AWS KMS for envelope encryption of Kubernetes secrets + +This allows you to encrypt your secrets with a unique data encryption +key (DEK). The DEK is then encrypted using a key encryption key (KEK) +from AWS KMS which can be automatically rotated on a recurring schedule. +With the KMS plugin for Kubernetes, all Kubernetes secrets are stored in +etcd in ciphertext instead of plain text and can only be decrypted by +the Kubernetes API server. For additional details, see +https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/[using +EKS encryption provider support for defense in depth] + +==== Audit the use of Kubernetes Secrets + +On EKS, turn on audit logging and create a CloudWatch metrics filter and +alarm to alert you when a secret is used (optional). The following is an +example of a metrics filter for the Kubernetes audit log, +`+{($.verb="get") && ($.objectRef.resource="secret")}+`. You can also +use the following queries with CloudWatch Log Insights: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| stats count(*) by objectRef.name as secret +| filter verb="get" and objectRef.resource="secrets" +---- + +The above query will display the number of times a secret has been +accessed within a specific timeframe. + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter verb="get" and objectRef.resource="secrets" +| display objectRef.namespace, objectRef.name, user.username, responseStatus.code +---- + +This query will display the secret, along with the namespace and +username of the user who attempted to access the secret and the response +code. + +==== Rotate your secrets periodically + +Kubernetes doesn’t automatically rotate secrets. If you have to rotate +secrets, consider using an external secret store, e.g. Vault or AWS +Secrets Manager. + +==== Use separate namespaces as a way to isolate secrets from different applications + +If you have secrets that cannot be shared between applications in a +namespace, create a separate namespace for those applications. + +==== Use volume mounts instead of environment variables + +The values of environment variables can unintentionally appear in logs. +Secrets mounted as volumes are instantiated as tmpfs volumes (a RAM +backed file system) that are automatically removed from the node when +the pod is deleted. + +==== Use an external secrets provider + +There are several viable alternatives to using Kubernetes secrets, +including https://aws.amazon.com/secrets-manager/[AWS Secrets Manager] +and Hashicorp’s +https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar/[Vault]. +These services offer features such as fine grained access controls, +strong encryption, and automatic rotation of secrets that are not +available with Kubernetes Secrets. Bitnami’s +https://github.com/bitnami-labs/sealed-secrets[Sealed Secrets] is +another approach that uses asymmetric encryption to create "`sealed +secrets`". A public key is used to encrypt the secret while the private +key used to decrypt the secret is kept within the cluster, allowing you +to safely store sealed secrets in source control systems like Git. See +https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/[Managing +secrets deployment in Kubernetes using Sealed Secrets] for further +information. + +As the use of external secrets stores has grown, so has need for +integrating them with Kubernetes. The +https://github.com/kubernetes-sigs/secrets-store-csi-driver[Secret Store +CSI Driver] is a community project that uses the CSI driver model to +fetch secrets from external secret stores. Currently, the Driver has +support for +https://github.com/aws/secrets-store-csi-driver-provider-aws[AWS Secrets +Manager], Azure, Vault, and GCP. The AWS provider supports both AWS +Secrets Manager *and* AWS Parameter Store. It can also be configured to +rotate secrets when they expire and can synchronize AWS Secrets Manager +secrets to Kubernetes Secrets. Synchronization of secrets can be useful +when you need to reference a secret as an environment variable instead +of reading them from a volume. + +!!! note When the the secret store CSI driver has to fetch a secret, it +assumes the IRSA role assigned to the pod that references a secret. The +code for this operation can be found +https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go[here]. + +For additional information about the AWS Secrets & Configuration +Provider (ASCP) refer to the following resources: + +* https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-configuration-provider-with-kubernetes-secrets-store-csi-driver/[How +to use AWS Secrets Configuration Provider with Kubernetes Secret Store +CSI Driver] +* https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_csi_driver.html[Integrating +Secrets Manager secrets with Kubernetes Secrets Store CSI Driver] + +https://github.com/external-secrets/external-secrets[external-secrets] +is yet another way to use an external secret store with Kubernetes. Like +the CSI Driver, external-secrets works against a variety of different +backends, including AWS Secrets Manager. The difference is, rather than +retrieving secrets from the external secret store, external-secrets +copies secrets from these backends to Kubernetes as Secrets. This lets +you manage secrets using your preferred secret store and interact with +secrets in a Kubernetes-native way. + +=== Tools and resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/13-data-encryption-and-secret-management[Amazon +EKS Security Immersion Workshop - Data Encryption and Secrets +Management] diff --git a/latest/bpg/security/detective.adoc b/latest/bpg/security/detective.adoc new file mode 100644 index 000000000..be54a3515 --- /dev/null +++ b/latest/bpg/security/detective.adoc @@ -0,0 +1,351 @@ +== Auditing and logging + +Collecting and analyzing [audit] logs is useful for a variety of +different reasons. Logs can help with root cause analysis and +attribution, i.e. ascribing a change to a particular user. When enough +logs have been collected, they can be used to detect anomalous behaviors +too. On EKS, the audit logs are sent to Amazon Cloudwatch Logs. The +audit policy for EKS is as follows: + +[source,yaml] +---- +apiVersion: audit.k8s.io/v1beta1 +kind: Policy +rules: + # Log aws-auth configmap changes + - level: RequestResponse + namespaces: ["kube-system"] + verbs: ["update", "patch", "delete"] + resources: + - group: "" # core + resources: ["configmaps"] + resourceNames: ["aws-auth"] + omitStages: + - "RequestReceived" + - level: None + users: ["system:kube-proxy"] + verbs: ["watch"] + resources: + - group: "" # core + resources: ["endpoints", "services", "services/status"] + - level: None + users: ["kubelet"] # legacy kubelet identity + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + userGroups: ["system:nodes"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["nodes", "nodes/status"] + - level: None + users: + - system:kube-controller-manager + - system:kube-scheduler + - system:serviceaccount:kube-system:endpoint-controller + verbs: ["get", "update"] + namespaces: ["kube-system"] + resources: + - group: "" # core + resources: ["endpoints"] + - level: None + users: ["system:apiserver"] + verbs: ["get"] + resources: + - group: "" # core + resources: ["namespaces", "namespaces/status", "namespaces/finalize"] + - level: None + users: + - system:kube-controller-manager + verbs: ["get", "list"] + resources: + - group: "metrics.k8s.io" + - level: None + nonResourceURLs: + - /healthz* + - /version + - /swagger* + - level: None + resources: + - group: "" # core + resources: ["events"] + - level: Request + users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"] + verbs: ["update","patch"] + resources: + - group: "" # core + resources: ["nodes/status", "pods/status"] + omitStages: + - "RequestReceived" + - level: Request + userGroups: ["system:nodes"] + verbs: ["update","patch"] + resources: + - group: "" # core + resources: ["nodes/status", "pods/status"] + omitStages: + - "RequestReceived" + - level: Request + users: ["system:serviceaccount:kube-system:namespace-controller"] + verbs: ["deletecollection"] + omitStages: + - "RequestReceived" + # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data, + # so only log at the Metadata level. + - level: Metadata + resources: + - group: "" # core + resources: ["secrets", "configmaps"] + - group: authentication.k8s.io + resources: ["tokenreviews"] + omitStages: + - "RequestReceived" + - level: Request + resources: + - group: "" + resources: ["serviceaccounts/token"] + - level: Request + verbs: ["get", "list", "watch"] + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "scheduling.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for known APIs + - level: RequestResponse + resources: + - group: "" # core + - group: "admissionregistration.k8s.io" + - group: "apiextensions.k8s.io" + - group: "apiregistration.k8s.io" + - group: "apps" + - group: "authentication.k8s.io" + - group: "authorization.k8s.io" + - group: "autoscaling" + - group: "batch" + - group: "certificates.k8s.io" + - group: "extensions" + - group: "metrics.k8s.io" + - group: "networking.k8s.io" + - group: "policy" + - group: "rbac.authorization.k8s.io" + - group: "scheduling.k8s.io" + - group: "settings.k8s.io" + - group: "storage.k8s.io" + omitStages: + - "RequestReceived" + # Default level for all other requests. + - level: Metadata + omitStages: + - "RequestReceived" +---- + +=== Recommendations + +==== Enable audit logs + +The audit logs are part of the EKS managed Kubernetes control plane logs +that are managed by EKS. Instructions for enabling/disabling the control +plane logs, which includes the logs for the Kubernetes API server, the +controller manager, and the scheduler, along with the audit log, can be +found here, +https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export. + +!!! info When you enable control plane logging, you will incur +https://aws.amazon.com/cloudwatch/pricing/[costs] for storing the logs +in CloudWatch. This raises a broader issue about the ongoing cost of +security. Ultimately you will have to weigh those costs against the cost +of a security breach, e.g. financial loss, damage to your reputation, +etc. You may find that you can adequately secure your environment by +implementing only some of the recommendations in this guide. + +!!! warning The maximum size for a CloudWatch Logs entry is +https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html[256KB] +whereas the maximum Kubernetes API request size is 1.5MiB. Log entries +greater than 256KB will either be truncated or only include the request +metadata. + +==== Utilize audit metadata + +Kubernetes audit logs include two annotations that indicate whether or +not a request was authorized `+authorization.k8s.io/decision+` and the +reason for the decision `+authorization.k8s.io/reason+`. Use these +attributes to ascertain why a particular API call was allowed. + +==== Create alarms for suspicious events + +Create an alarm to automatically alert you where there is an increase in +403 Forbidden and 401 Unauthorized responses, and then use attributes +like `+host+`, `+sourceIPs+`, and `+k8s_user.username+` to find out +where those requests are coming from. + +==== Analyze logs with Log Insights + +Use CloudWatch Log Insights to monitor changes to RBAC objects, +e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few +sample queries appear below: + +Lists updates to the `+aws-auth+` ConfigMap: + +[source,bash] +---- +fields @timestamp, @message +| filter @logStream like "kube-apiserver-audit" +| filter verb in ["update", "patch"] +| filter objectRef.resource = "configmaps" and objectRef.name = "aws-auth" and objectRef.namespace = "kube-system" +| sort @timestamp desc +---- + +Lists creation of new or changes to validation webhooks: + +[source,bash] +---- +fields @timestamp, @message +| filter @logStream like "kube-apiserver-audit" +| filter verb in ["create", "update", "patch"] and responseStatus.code = 201 +| filter objectRef.resource = "validatingwebhookconfigurations" +| sort @timestamp desc +---- + +Lists create, update, delete operations to Roles: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"] +---- + +Lists create, update, delete operations to RoleBindings: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"] +---- + +Lists create, update, delete operations to ClusterRoles: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"] +---- + +Lists create, update, delete operations to ClusterRoleBindings: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"] +---- + +Plots unauthorized read operations against Secrets: + +[source,bash] +---- +fields @timestamp, @message +| sort @timestamp desc +| limit 100 +| filter objectRef.resource="secrets" and verb in ["get", "watch", "list"] and responseStatus.code="401" +| stats count() by bin(1m) +---- + +List of failed anonymous requests: + +[source,bash] +---- +fields @timestamp, @message, sourceIPs.0 +| sort @timestamp desc +| limit 100 +| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"] +---- + +==== Audit your CloudTrail logs + +AWS APIs called by pods that are utilizing IAM Roles for Service +Accounts (IRSA) are automatically logged to CloudTrail along with the +name of the service account. If the name of a service account that +wasn’t explicitly authorized to call an API appears in the log, it may +be an indication that the IAM role’s trust policy was misconfigured. +Generally speaking, Cloudtrail is a great way to ascribe AWS API calls +to specific IAM principals. + +==== Use CloudTrail Insights to unearth suspicious activity + +CloudTrail insights automatically analyzes write management events from +CloudTrail trails and alerts you of unusual activity. This can help you +identify when there’s an increase in call volume on write APIs in your +AWS account, including from pods that use IRSA to assume an IAM role. +See +https://aws.amazon.com/blogs/aws/announcing-cloudtrail-insights-identify-and-respond-to-unusual-api-activity/[Announcing +CloudTrail Insights: Identify and Response to Unusual API Activity] for +further information. + +==== Additional resources + +As the volume of logs increases, parsing and filtering them with Log +Insights or another log analysis tool may become ineffective. As an +alternative, you might want to consider running +https://github.com/falcosecurity/falco[Sysdig Falco] and +https://github.com/sysdiglabs/ekscloudwatch[ekscloudwatch]. Falco +analyzes audit logs and flags anomalies or abuse over an extended period +of time. The ekscloudwatch project forwards audit log events from +CloudWatch to Falco for analysis. Falco provides a set of +https://github.com/falcosecurity/plugins/blob/master/plugins/k8saudit/rules/k8s_audit_rules.yaml[default +audit rules] along with the ability to add your own. + +Yet another option might be to store the audit logs in S3 and use the +SageMaker +https://docs.aws.amazon.com/sagemaker/latest/dg/randomcutforest.html[Random +Cut Forest] algorithm to anomalous behaviors that warrant further +investigation. + +=== Tools and resources + +The following commercial and open source projects can be used to assess +your cluster’s alignment with established best practices: + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/5-detective-controls[Amazon +EKS Security Immersion Workshop - Detective Controls] +* https://github.com/Shopify/kubeaudit[kubeaudit] +* https://github.com/octarinesec/kube-scan[kube-scan] Assigns a risk +score to the workloads running in your cluster in accordance with the +Kubernetes Common Configuration Scoring System framework +* https://kubesec.io/[kubesec.io] +* https://github.com/FairwindsOps/polaris[polaris] +* https://github.com/aquasecurity/starboard[Starboard] +* https://support.snyk.io/hc/en-us/articles/360003916138-Kubernetes-integration-overview[Snyk] +* https://github.com/kubescape/kubescape[Kubescape] Kubescape is an open +source kubernetes security tool that scans clusters, YAML files, and +Helm charts. It detects misconfigurations according to multiple +frameworks (including +https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo/?utm_source=github&utm_medium=repository[NSA-CISA] +and +https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/[MITRE +ATT&CK®].) diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc new file mode 100644 index 000000000..7d617094f --- /dev/null +++ b/latest/bpg/security/hosts.adoc @@ -0,0 +1,357 @@ +== Protecting the infrastructure (hosts) + +Inasmuch as it’s important to secure your container images, it’s equally +important to safeguard the infrastructure that runs them. This section +explores different ways to mitigate risks from attacks launched directly +against the host. These guidelines should be used in conjunction with +those outlined in the link:runtime.md[Runtime Security] section. + +=== Recommendations + +==== Use an OS optimized for running containers + +Consider using Flatcar Linux, Project Atomic, RancherOS, and +https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a +special purpose OS from AWS designed for running Linux containers. It +includes a reduced attack surface, a disk image that is verified on +boot, and enforced permission boundaries using SELinux. + +Alternately, use the +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html[EKS +optimized AMI] for your Kubernetes worker nodes. The EKS optimized AMI +is released regularly and contains a minimal set of OS packages and +binaries necessary to run your containerized workloads. + +Please refer https://github.com/aws-samples/amazon-eks-ami-rhel[Amazon +EKS AMI RHEL Build Specification] for a sample configuration script +which can be used for building a custom Amazon EKS AMI running on Red +Hat Enterprise Linux using Hashicorp Packer. This script can be further +leveraged to build STIG compliant EKS custom AMIs. + +==== Keep your worker node OS updated + +Regardless of whether you use a container-optimized host OS like +Bottlerocket or a larger, but still minimalist, Amazon Machine Image +like the EKS optimized AMIs, it is best practice to keep these host OS +images up to date with the latest security patches. + +For the EKS optimized AMIs, regularly check the +https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md[CHANGELOG] +and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes +channel] and automate the rollout of updated worker node images into +your cluster. + +==== Treat your infrastructure as immutable and automate the replacement of your worker nodes + +Rather than performing in-place upgrades, replace your workers when a +new patch or update becomes available. This can be approached a couple +of ways. You can either add instances to an existing autoscaling group +using the latest AMI as you sequentially cordon and drain nodes until +all of the nodes in the group have been replaced with the latest AMI. +Alternatively, you can add instances to a new node group while you +sequentially cordon and drain nodes from the old node group until all of +the nodes have been replaced. EKS +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed +node groups] uses the first approach and will display a message in the +console to upgrade your workers when a new AMI becomes available. +`+eksctl+` also has a mechanism for creating node groups with the latest +AMI and for gracefully cordoning and draining pods from nodes groups +before the instances are terminated. If you decide to use a different +method for replacing your worker nodes, it is strongly recommended that +you automate the process to minimize human oversight as you will likely +need to replace workers regularly as new updates/patches are released +and when the control plane is upgraded. + +With EKS Fargate, AWS will automatically update the underlying +infrastructure as updates become available. Oftentimes this can be done +seamlessly, but there may be times when an update will cause your pod to +be rescheduled. Hence, we recommend that you create deployments with +multiple replicas when running your application as a Fargate pod. + +==== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] + +kube-bench is an open source project from Aqua that evaluates your +cluster against the CIS benchmarks for Kubernetes. The benchmark +describes the best practices for securing unmanaged Kubernetes clusters. +The CIS Kubernetes Benchmark encompasses the control plane and the data +plane. Since Amazon EKS provides a fully managed control plane, not all +of the recommendations from the CIS Kubernetes Benchmark are applicable. +To ensure this scope reflects how Amazon EKS is implemented, AWS created +the _CIS Amazon EKS Benchmark_. The EKS benchmark inherits from CIS +Kubernetes Benchmark with additional inputs from the community with +specific configuration considerations for EKS clusters. + +When running https://github.com/aquasecurity/kube-bench[kube-bench] +against an EKS cluster, follow +https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster[these +instructions] from Aqua Security. For further information see +https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing +The CIS Amazon EKS Benchmark]. + +==== Minimize access to worker nodes + +Instead of enabling SSH access, use +https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM +Session Manager] when you need to remote into a host. Unlike SSH keys +which can be lost, copied, or shared, Session Manager allows you to +control access to EC2 instances using IAM. Moreover, it provides an +audit trail and log of the commands that were run on the instance. + +As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 +Launch Templates. This allows you to embed the SSM agent into the AMI or +install it as the worker node is being bootstrapped. If you rather not +modify the Optimized AMI or the ASG’s launch template, you can install +the SSM agent with a DaemonSet as in +https://github.com/aws-samples/ssm-agent-daemonset-installer[this +example]. + +===== Minimal IAM policy for SSM based SSH Access + +The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a +number of permissions that are not required for SSM Session Manager / +SSM RunCommand if you’re just looking to avoid SSH access. Of concern +specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which +would allow for the role to access all parameters in Parameter Store +(including SecureStrings with the AWS managed KMS key configured). + +The following IAM policy contains the minimal set of permissions to +enable node access via SSM Systems Manager. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "EnableAccessViaSSMSessionManager", + "Effect": "Allow", + "Action": [ + "ssmmessages:OpenDataChannel", + "ssmmessages:OpenControlChannel", + "ssmmessages:CreateDataChannel", + "ssmmessages:CreateControlChannel", + "ssm:UpdateInstanceInformation" + ], + "Resource": "*" + }, + { + "Sid": "EnableSSMRunCommand", + "Effect": "Allow", + "Action": [ + "ssm:UpdateInstanceInformation", + "ec2messages:SendReply", + "ec2messages:GetMessages", + "ec2messages:GetEndpoint", + "ec2messages:FailMessage", + "ec2messages:DeleteMessage", + "ec2messages:AcknowledgeMessage" + ], + "Resource": "*" + } + ] +} +---- + +With this policy in place and the +https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html[Session +Manager plugin] installed, you can then run + +[source,bash] +---- +aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE] +---- + +to access the node. + +!!! note You may also want to consider adding permissions to +https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable +Session Manager logging]. + +==== Deploy workers onto private subnets + +By deploying workers onto private subnets, you minimize their exposure +to the Internet where attacks often originate. Beginning April 22, 2020, +the assignment of public IP addresses to nodes in a managed node groups +will be controlled by the subnet they are deployed onto. Prior to this, +nodes in a Managed Node Group were automatically assigned a public IP. +If you choose to deploy your worker nodes on to public subnets, +implement restrictive AWS security group rules to limit their exposure. + +==== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices + +You can use +https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon +Inspector] to check for unintended network access to your nodes and for +vulnerabilities on the underlying Amazon EC2 instances. + +Amazon Inspector can provide common vulnerabilities and exposures (CVE) +data for your Amazon EC2 instances only if the Amazon EC2 Systems +Manager (SSM) agent is installed and enabled. This agent is preinstalled +on several +https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html[Amazon +Machine Images (AMIs)] including +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS +optimized Amazon Linux AMIs]. Regardless of SSM agent status, all of +your Amazon EC2 instances are scanned for network reachability issues. +For more information about configuring scans for Amazon EC2, see +https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html[Scanning +Amazon EC2 instances]. + +!!! attention Inspector cannot be run on the infrastructure used to run +Fargate pods. + +=== Alternatives + +==== Run SELinux + +!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, +Bottlerocket, and Amazon Linux 2023 + +SELinux provides an additional layer of security to keep containers +isolated from each other and from the host. SELinux allows +administrators to enforce mandatory access controls (MAC) for every +user, application, process, and file. Think of it as a backstop that +restricts the operations that can be performed against to specific +resources based on a set of labels. On EKS, SELinux can be used to +prevent containers from accessing each other’s resources. + +Container SELinux policies are defined in the +https://github.com/containers/container-selinux[container-selinux] +package. Docker CE requires this package (along with its dependencies) +so that the processes and files created by Docker (or other container +runtimes) run with limited system access. Containers leverage the +`+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +policies effectively prevent containers from accessing certain features +of the host. + +When you configure SELinux for Docker, Docker automatically labels +workloads `+container_t+` as a type and gives each container a unique +MCS level. This will isolate containers from one another. If you need +looser restrictions, you can create your own profile in SElinux which +grants a container permissions to specific areas of the file system. +This is similar to PSPs in that you can create different profiles for +different containers/pods. For example, you can have a profile for +general workloads with a set of restrictive controls and another for +things that require privileged access. + +SELinux for Containers has a set of options that can be configured to +modify the default restrictions. The following SELinux Booleans can be +enabled or disabled based on your needs: + +[width="100%",cols="30%,^40%,30%",options="header",] +|=== +|Boolean |Default |Description +|`+container_connect_any+` |`+off+` |Allow containers to access +privileged ports on the host. For example, if you have a container that +needs to map ports to 443 or 80 on the host. + +|`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +configuration. For example, a container running systemd will need this +to be enabled. + +|`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file +system. +|=== + +By default, containers are allowed to read/execute under `+/usr+` and +read most content from `+/etc+`. The files under `+/var/lib/docker+` and +`+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +a full list of default, labels see the +https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] +file. + +[source,bash] +---- +docker container run -it \ + -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ + centos:7 cat /host/repositories.json +# cat: /host/repositories.json: Permission denied + +docker container run -it \ + -v /etc/passwd:/host/etc/passwd \ + centos:7 cat /host/etc/passwd +# cat: /host/etc/passwd: Permission denied +---- + +Files labeled with `+container_file_t+` are the only files that are +writable by containers. If you want a volume mount to be writeable, you +will needed to specify `+:z+` or `+:Z+` at the end. + +* `+:z+` will re-label the files so that the container can read/write +* `+:Z+` will re-label the files so that *only* the container can +read/write + +[source,bash] +---- +ls -Z /var/lib/misc +# -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp + +docker container run -it \ + -v /var/lib/misc:/host/var/lib/misc:z \ + centos:7 echo "Relabeled!" + +ls -Z /var/lib/misc +#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp +---- + +[source,bash] +---- +docker container run -it \ + -v /var/log:/host/var/log:Z \ + fluentbit:latest +---- + +In Kubernetes, relabeling is slightly different. Rather than having +Docker automatically relabel the files, you can specify a custom MCS +label to run the pod. Volumes that support relabeling will automatically +be relabeled so that they are accessible. Pods with a matching MCS label +will be able to access the volume. If you need strict isolation, set a +different MCS label for each pod. + +[source,yaml] +---- +securityContext: + seLinuxOptions: + # Provide a unique MCS label per container + # You can specify user, role, and type also + # enforcement based on type and level (svert) + level: s0:c144:c154 +---- + +In this example `+s0:c144:c154+` corresponds to an MCS label assigned to +a file that the container is allowed to access. + +On EKS you could create policies that allow for privileged containers to +run, like FluentD and create an SELinux policy to allow it to read from +/var/log on the host without needing to relabel the host directory. Pods +with the same label will be able to access the same host volumes. + +We have implemented +https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for +Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These +AMIs were developed to demonstrate sample implementations that meet +requirements of highly regulated customers, such as STIG, CJIS, and C2S. + +!!! caution SELinux will ignore containers where the type is unconfined. + +=== Tools and resources + +* https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux +Kubernetes RBAC and Shipping Security Policies for On-prem Applications] +* https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html[Iterative +Hardening of Kubernetes] +* https://linux.die.net/man/1/audit2allow[Audit2Allow] +* https://linux.die.net/man/8/sealert[SEAlert] +* https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica[Generate +SELinux policies for containers with Udica] describes a tool that looks +at container spec files for Linux capabilities, ports, and mount points, +and generates a set of SELinux rules that allow the container to run +properly +* https://github.com/aws-samples/amazon-eks-custom-amis#hardening[AMI +Hardening] playbooks for hardening the OS to meet different regulatory +requirements +* https://github.com/keikoproj/upgrade-manager[Keiko Upgrade Manager] an +open source project from Intuit that orchestrates the rotation of worker +nodes. +* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] +* https://eksctl.io/[eksctl] diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc new file mode 100644 index 000000000..21c652bd8 --- /dev/null +++ b/latest/bpg/security/iam.adoc @@ -0,0 +1,1435 @@ +== Identity and Access Management + +https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html[Identity +and Access Management] (IAM) is an AWS service that performs two +essential functions: Authentication and Authorization. Authentication +involves the verification of a identity whereas authorization governs +the actions that can be performed by AWS resources. Within AWS, a +resource can be another AWS service, e.g. EC2, or an AWS +https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal[principal] +such as an +https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-users[IAM +User] or +https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-roles[Role]. +The rules governing the actions that a resource is allowed to perform +are expressed as +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html[IAM +policies]. + +=== Controlling Access to EKS Clusters + +The Kubernetes project supports a variety of different strategies to +authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, +X.509 certificates, OIDC, etc. EKS currently has native support for +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication[webhook +token authentication], +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens[service +account tokens], and as of February 21, 2021, OIDC authentication. + +The webhook authentication strategy calls a webhook that verifies bearer +tokens. On EKS, these bearer tokens are generated by the AWS CLI or the +https://github.com/kubernetes-sigs/aws-iam-authenticator[aws-iam-authenticator] +client when you run `+kubectl+` commands. As you execute commands, the +token is passed to the kube-apiserver which forwards it to the +authentication webhook. If the request is well-formed, the webhook calls +a pre-signed URL embedded in the token’s body. This URL validates the +request’s signature and returns information about the user, e.g. the +user’s account, Arn, and UserId to the kube-apiserver. + +To manually generate a authentication token, type the following command +in a terminal window: + +[source,bash] +---- +aws eks get-token --cluster-name +---- + +You can also get a token programmatically. Below is an example written +in Go: + +[source,golang] +---- +package main + +import ( + "fmt" + "log" + "sigs.k8s.io/aws-iam-authenticator/pkg/token" +) + +func main() { + g, _ := token.NewGenerator(false, false) + tk, err := g.Get("") + if err != nil { + log.Fatal(err) + } + fmt.Println(tk) +} +---- + +The output should resemble this: + +[source,json] +---- +{ + "kind": "ExecCredential", + "apiVersion": "client.authentication.k8s.io/v1alpha1", + "spec": {}, + "status": { + "expirationTimestamp": "2020-02-19T16:08:27Z", + "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" + } +} +---- + +Each token starts with `+k8s-aws-v1.+` followed by a base64 encoded +string. The string, when decoded, should resemble to something similar +to this: + +[source,bash] +---- +https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393 +---- + +The token consists of a pre-signed URL that includes an Amazon +credential and signature. For additional details see +https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. + +The token has a time to live (TTL) of 15 minutes after which a new token +will need to be generated. This is handled automatically when you use a +client like `+kubectl+`, however, if you’re using the Kubernetes +dashboard, you will need to generate a new token and re-authenticate +each time the token expires. + +Once the user’s identity has been authenticated by the AWS IAM service, +the kube-apiserver reads the `+aws-auth+` ConfigMap in the +`+kube-system+` Namespace to determine the RBAC group to associate with +the user. The `+aws-auth+` ConfigMap is used to create a static mapping +between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC +groups. RBAC groups can be referenced in Kubernetes RoleBindings or +ClusterRoleBindings. They are similar to IAM Roles in that they define a +set of actions (verbs) that can be performed against a collection of +Kubernetes resources (objects). + +==== Cluster Access Manager + +Cluster Access Manager, now the preferred way to manage access of AWS +IAM principals to Amazon EKS clusters, is a functionality of the AWS API +and is an opt-in feature for EKS v1.23 and later clusters (new or +existing). It simplifies identity mapping between AWS IAM and Kubernetes +RBACs, eliminating the need to switch between AWS and Kubernetes APIs or +editing the `+aws-auth+` ConfigMap for access management, reducing +operational overhead, and helping address misconfigurations. The tool +also enables cluster administrators to revoke or refine +`+cluster-admin+` permissions automatically granted to the AWS IAM +principal used to create the cluster. + +This API relies on two concepts: + +* *Access Entries:* A cluster identity directly linked to an AWS IAM +principal (user or role) allowed to authenticate to an Amazon EKS +cluster. +* *Access Policies:* Are Amazon EKS specific policies that provides the +authorization for an Access Entry to perform actions in the Amazon EKS +cluster. + +____ +At launch Amazon EKS supports only predefined and AWS managed policies. +Access policies are not IAM entities and are defined and managed by +Amazon EKS. +____ + +Cluster Access Manager allows the combination of upstream RBAC with +Access Policies supporting allow and pass (but not deny) on Kubernetes +AuthZ decisions regarding API server requests. A deny decision will +happen when both, the upstream RBAC and Amazon EKS authorizers can’t +determine the outcome of a request evaluation. + +With this feature, Amazon EKS supports three modes of authentication: + +[arabic] +. `+CONFIG_MAP+` to continue using `+aws-auth+` configMap exclusively. +. `+API_AND_CONFIG_MAP+` to source authenticated IAM principals from +both EKS Access Entry APIs and the `+aws-auth+` configMap, prioritizing +the Access Entries. Ideal to migrate existing `+aws-auth+` permissions +to Access Entries. +. `+API+` to exclusively rely on EKS Access Entry APIs. This is the new +*recommended approach*. + +To get started, cluster administrators can create or update Amazon EKS +clusters, setting the preferred authentication to `+API_AND_CONFIG_MAP+` +or `+API+` method and define Access Entries to grant access the desired +AWS IAM principals. + +[source,bash] +---- +$ aws eks create-cluster \ + --name \ + --role-arn \ + --resources-vpc-config subnetIds=,endpointPublicAccess=true,endpointPrivateAccess=true \ + --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ + --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false +---- + +The above command is an example to create an Amazon EKS cluster already +without the admin permissions of the cluster creator. + +It is possible to update Amazon EKS clusters configuration to enable +`+API+` authenticationMode using the `+update-cluster-config+` command, +to do that on existing clusters using `+CONFIG_MAP+` you will have to +first update to `+API_AND_CONFIG_MAP+` and then to `+API+`. *These +operations cannot be reverted*, meaning that’s not possible to switch +from `+API+` to `+API_AND_CONFIG_MAP+` or `+CONFIG_MAP+`, and also from +`+API_AND_CONFIG_MAP+` to `+CONFIG_MAP+`. + +[source,bash] +---- +$ aws eks update-cluster-config \ + --name \ + --access-config authenticationMode=API +---- + +The API support commands to add and revoke access to the cluster, as +well as validate the existing Access Policies and Access Entries for the +specified cluster. The default policies are created to match Kubernetes +RBACs as follows. + +[cols=",",options="header",] +|=== +|EKS Access Policy |Kubernetes RBAC +|AmazonEKSClusterAdminPolicy |cluster-admin +|AmazonEKSAdminPolicy |admin +|AmazonEKSEditPolicy |edit +|AmazonEKSViewPolicy |view +|=== + +[source,bash] +---- +$ aws eks list-access-policies +{ + "accessPolicies": [ + { + "name": "AmazonEKSAdminPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" + }, + { + "name": "AmazonEKSClusterAdminPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" + }, + { + "name": "AmazonEKSEditPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" + }, + { + "name": "AmazonEKSViewPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" + } + ] +} + +$ aws eks list-access-entries --cluster-name + +{ + "accessEntries": [] +} +---- + +____ +No Access Entries are available when the cluster is created without the +cluster creator admin permission, which is the only entry created by +default. +____ + +==== The `+aws-auth+` ConfigMap _(deprecated)_ + +One way Kubernetes integration with AWS authentication can be done is +via the `+aws-auth+` ConfigMap, which resides in the `+kube-system+` +Namespace. It is responsible for mapping the AWS IAM Identities (Users, +Groups, and Roles) authentication, to Kubernetes role-based access +control (RBAC) authorization. The `+aws-auth+` ConfigMap is +automatically created in your Amazon EKS cluster during its provisioning +phase. It was initially created to allow nodes to join your cluster, but +as mentioned you can also use this ConfigMap to add RBACs access to IAM +principals. + +To check your cluster’s `+aws-auth+` ConfigMap, you can use the +following command. + +[source,bash] +---- +kubectl -n kube-system get configmap aws-auth -o yaml +---- + +This is a sample of a default configuration of the `+aws-auth+` +ConfigMap. + +[source,yaml] +---- +apiVersion: v1 +data: + mapRoles: | + - groups: + - system:bootstrappers + - system:nodes + - system:node-proxier + rolearn: arn:aws:iam:::role/kube-system- + username: system:node:{{SessionName}} +kind: ConfigMap +metadata: + creationTimestamp: "2023-10-22T18:19:30Z" + name: aws-auth + namespace: kube-system +---- + +The main session of this ConfigMap, is under `+data+` in the +`+mapRoles+` block, which is basically composed by 3 parameters. + +* *groups:* The Kubernetes group(s) to map the IAM Role to. This can be +a default group, or a custom group specified in a `+clusterrolebinding+` +or `+rolebinding+`. In the above example we have just system groups +declared. +* *rolearn:* The ARN of the AWS IAM Role be mapped to the Kubernetes +group(s) add, using the following format +`+arn::iam:::role/role-name+`. +* *username:* The username within Kubernetes to map to the AWS IAM role. +This can be any custom name. + +____ +It is also possible to map permissions for AWS IAM Users, defining a new +configuration block for `+mapUsers+`, under `+data+` in the `+aws-auth+` +ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a +*Best Practice* it’s always recommended to user `+mapRoles+` instead. +____ + +To manage permissions, you can edit the `+aws-auth+` ConfigMap adding or +removing access to your Amazon EKS cluster. Although it’s possible to +edit the `+aws-auth+` ConfigMap manually, it’s recommended using tools +like `+eksctl+`, since this is a very senstitive configuration, and an +inaccurate configuration can lock you outside your Amazon EKS Cluster. +Check the subsection +https://aws.github.io/aws-eks-best-practices/security/docs/iam/#use-tools-to-make-changes-to-the-aws-auth-configmap[Use +tools to make changes to the aws-auth ConfigMap] below for more details. + +=== Cluster Access Recommendations + +==== Make the EKS Cluster Endpoint private + +By default when you provision an EKS cluster, the API cluster endpoint +is set to public, i.e. it can be accessed from the Internet. Despite +being accessible from the Internet, the endpoint is still considered +secure because it requires all API requests to be authenticated by IAM +and then authorized by Kubernetes RBAC. That said, if your corporate +security policy mandates that you restrict access to the API from the +Internet or prevents you from routing traffic outside the cluster VPC, +you can: + +* Configure the EKS cluster endpoint to be private. See +https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[Modifying +Cluster Endpoint Access] for further information on this topic. +* Leave the cluster endpoint public and specify which CIDR blocks can +communicate with the cluster endpoint. The blocks are effectively a +whitelisted set of public IP addresses that are allowed to access the +cluster endpoint. +* Configure public access with a set of whitelisted CIDR blocks and set +private endpoint access to enabled. This will allow public access from a +specific range of public IPs while forcing all network traffic between +the kubelets (workers) and the Kubernetes API through the cross-account +ENIs that get provisioned into the cluster VPC when the control plane is +provisioned. + +==== Don’t use a service account token for authentication + +A service account token is a long-lived, static credential. If it is +compromised, lost, or stolen, an attacker may be able to perform all the +actions associated with that token until the service account is deleted. +At times, you may need to grant an exception for applications that have +to consume the Kubernetes API from outside the cluster, e.g. a CI/CD +pipeline application. If such applications run on AWS infrastructure, +like EC2 instances, consider using an instance profile and mapping that +to a Kubernetes RBAC role. + +==== Employ least privileged access to AWS Resources + +An IAM User does not need to be assigned privileges to AWS resources to +access the Kubernetes API. If you need to grant an IAM user access to an +EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user +that maps to a specific Kubernetes RBAC group. + +==== Remove the cluster-admin permissions from the cluster creator principal + +By default Amazon EKS clusters are created with a permanent +`+cluster-admin+` permission bound to the cluster creator principal. +With the Cluster Access Manager API, it’s possible to create clusters +without this permission setting the +`+--access-config bootstrapClusterCreatorAdminPermissions+` to +`+false+`, when using `+API_AND_CONFIG_MAP+` or `+API+` authentication +mode. Revoke this access considered a best practice to avoid any +unwanted changes to the cluster configuration. The process to revoke +this access, follows the same process to revoke any other access to the +cluster. + +The API gives you flexibility to only disassociate an IAM principal from +an Access Policy, in this case the `+AmazonEKSClusterAdminPolicy+`. + +[source,bash] +---- +$ aws eks list-associated-access-policies \ + --cluster-name \ + --principal-arn + +$ aws eks disassociate-access-policy --cluster-name \ + --principal-arn + +{ + "accessEntries": [] +} + +$ aws eks delete-access-entry --cluster-name \ + --principal-arn +---- + +____ +This access can be granted again if needed during an incident, emergency +or break glass scenario where the cluster is otherwise inaccessible. +____ + +If the cluster still configured with the `+CONFIG_MAP+` authentication +method, all additional users should be granted access to the cluster +through the `+aws-auth+` ConfigMap, and after `+aws-auth+` ConfigMap is +configured, the role assigned to the entity that created the cluster, +can be deleted and only recreated in case of an incident, emergency or +break glass scenario, or where the `+aws-auth+` ConfigMap is corrupted +and the cluster is otherwise inaccessible. This can be particularly +useful in production clusters. + +==== Use IAM Roles when multiple users need identical access to the cluster + +Rather than creating an entry for each individual IAM User, allow those +users to assume an IAM Role and map that role to a Kubernetes RBAC +group. This will be easier to maintain, especially as the number of +users that require access grows. + +!!! attention When accessing the EKS cluster with the IAM entity mapped +by `+aws-auth+` ConfigMap, the username described is recorded in the +user field of the Kubernetes audit log. If you’re using an IAM role, the +actual users who assume that role aren’t recorded and can’t be audited. + +If still using the `+aws-auth+` configMap as the authentication method, +when assigning K8s RBAC permissions to an IAM role, you should include +\{\{SessionName}} in your username. That way, the audit log will record +the session name so you can track who the actual user assume this role +along with the CloudTrail log. + +[source,yaml] +---- +- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole + username: testRole:{{SessionName}} + groups: + - system:masters +---- + +____ +In Kubernetes 1.20 and above, this change is no longer required, since +`+user.extra.sessionName.0+` was added to the Kubernetes audit log. +____ + +==== Employ least privileged access when creating RoleBindings and ClusterRoleBindings + +Like the earlier point about granting access to AWS Resources, +RoleBindings and ClusterRoleBindings should only include the set of +permissions necessary to perform a specific function. Avoid using +`+["*"]+` in your Roles and ClusterRoles unless it’s absolutely +necessary. If you’re unsure what permissions to assign, consider using a +tool like https://github.com/liggitt/audit2rbac[audit2rbac] to +automatically generate Roles and binding based on the observed API calls +in the Kubernetes Audit Log. + +==== Create cluster using an automated process + +As seen in earlier steps, when creating an Amazon EKS cluster, if not +using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, +and not opting out to delegate `+cluster-admin+` permissions to the +cluster creator, the IAM entity user or role, such as a federated +user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster’s RBAC +configuration. Even being a best practice to remove this permission, as +described +link:#remove-the-cluster-admin-permissions-from-the-cluster-creator-principal[here] +if using the `+CONFIG_MAP+` authentication method, relying on +`+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a +good idea to create the cluster with an infrastructure automation +pipeline tied to dedicated IAM role, with no permissions to be assumed +by other users or entities and regularly audit this role’s permissions, +policies, and who has access to trigger the pipeline. Also, this role +should not be used to perform routine actions on the cluster, and be +exclusively used to cluster level actions triggered by the pipeline, via +SCM code changes for example. + +==== Create the cluster with a dedicated IAM role + +When you create an Amazon EKS cluster, the IAM entity user or role, such +as a federated user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster’s RBAC +configuration. This access cannot be removed and is not managed through +the `+aws-auth+` ConfigMap. Therefore it is a good idea to create the +cluster with a dedicated IAM role and regularly audit who can assume +this role. This role should not be used to perform routine actions on +the cluster, and instead additional users should be granted access to +the cluster through the `+aws-auth+` ConfigMap for this purpose. After +the `+aws-auth+` ConfigMap is configured, the role should be secured and +only used in temporary elevated privilege mode / break glass for +scenarios where the cluster is otherwise inaccessible. This can be +particularly useful in clusters which do not have direct user access +configured. + +==== Regularly audit access to the cluster + +Who requires access is likely to change over time. Plan to periodically +audit the `+aws-auth+` ConfigMap to see who has been granted access and +the rights they’ve been assigned. You can also use open source tooling +like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], +or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine +the roles bound to a particular service account, user, or group. We’ll +explore this topic further when we get to the section on +link:detective.md[auditing]. Additional ideas can be found in this +https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] +from NCC Group. + +==== If relying on `+aws-auth+` configMap use tools to make changes + +An improperly formatted aws-auth ConfigMap may cause you to lose access +to the cluster. If you need to make changes to the ConfigMap, use a +tool. + +*eksctl* The `+eksctl+` CLI includes a command for adding identity +mappings to the aws-auth ConfigMap. + +View CLI Help: + +[source,bash] +---- +$ eksctl create iamidentitymapping --help +... +---- + +Check the identities mapped to your Amazon EKS Cluster. + +[source,bash] +---- +$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION +ARN USERNAME GROUPS ACCOUNT +arn:aws:iam::788355785855:role/kube-system- system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier +---- + +Make an IAM Role a Cluster Admin: + +[source,bash] +---- +$ eksctl create iamidentitymapping --cluster --region= --arn arn:aws:iam::123456:role/testing --group system:masters --username admin +... +---- + +For more information, review +https://eksctl.io/usage/iam-identity-mappings/[`+eksctl+` docs] + +*https://github.com/keikoproj/aws-auth[aws-auth] by keikoproj* + +`+aws-auth+` by keikoproj includes both a cli and a go library. + +Download and view help CLI help: + +[source,bash] +---- +$ go get github.com/keikoproj/aws-auth +... +$ aws-auth help +... +---- + +Alternatively, install `+aws-auth+` with the +https://krew.sigs.k8s.io[krew plugin manager] for kubectl. + +[source,bash] +---- +$ kubectl krew install aws-auth +... +$ kubectl aws-auth +... +---- + +https://github.com/keikoproj/aws-auth/blob/master/README.md[Review the +aws-auth docs on GitHub] for more information, including the go library. + +*https://github.com/kubernetes-sigs/aws-iam-authenticator/tree/master/cmd/aws-iam-authenticator[AWS +IAM Authenticator CLI]* + +The `+aws-iam-authenticator+` project includes a CLI for updating the +ConfigMap. + +https://github.com/kubernetes-sigs/aws-iam-authenticator/releases[Download +a release] on GitHub. + +Add cluster permissions to an IAM Role: + +[source,bash] +---- +$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config +... +---- + +==== Alternative Approaches to Authentication and Access Management + +While IAM is the preferred way to authenticate users who need access to +an EKS cluster, it is possible to use an OIDC identity provider such as +GitHub using an authentication proxy and Kubernetes +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation[impersonation]. +Posts for two such solutions have been published on the AWS Open Source +blog: + +* https://aws.amazon.com/blogs/opensource/authenticating-eks-github-credentials-teleport/[Authenticating +to EKS Using GitHub Credentials with Teleport] +* https://aws.amazon.com/blogs/opensource/consistent-oidc-authentication-across-multiple-eks-clusters-using-kube-oidc-proxy/[Consistent +OIDC authentication across multiple EKS clusters using kube-oidc-proxy] + +!!! attention EKS natively supports OIDC authentication without using a +proxy. For further information, please read the launch blog, +https://aws.amazon.com/blogs/containers/introducing-oidc-identity-provider-authentication-amazon-eks/[Introducing +OIDC identity provider authentication for Amazon EKS]. For an example +showing how to configure EKS with Dex, a popular open source OIDC +provider with connectors for a variety of different authention methods, +see +https://aws.amazon.com/blogs/containers/using-dex-dex-k8s-authenticator-to-authenticate-to-amazon-eks/[Using +Dex & dex-k8s-authenticator to authenticate to Amazon EKS]. As described +in the blogs, the username/group of users authenticated by an OIDC +provider will appear in the Kubernetes audit log. + +You can also use +https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[AWS +SSO] to federate AWS with an external identity provider, e.g. Azure AD. +If you decide to use this, the AWS CLI v2.0 includes an option to create +a named profile that makes it easy to associate an SSO session with your +current CLI session and assume an IAM role. Know that you must assume a +role _prior_ to running `+kubectl+` as the IAM role is used to determine +the user’s Kubernetes RBAC group. + +=== Identities and Credentials for EKS pods + +Certain applications that run within a Kubernetes cluster need +permission to call the Kubernetes API to function properly. For example, +the https://github.com/kubernetes-sigs/aws-load-balancer-controller[AWS +Load Balancer Controller] needs to be able to list a Service’s +Endpoints. The controller also needs to be able to invoke AWS APIs to +provision and configure an ALB. In this section we will explore the best +practices for assigning rights and privileges to Pods. + +==== Kubernetes Service Accounts + +A service account is a special type of object that allows you to assign +a Kubernetes RBAC role to a pod. A default service account is created +automatically for each Namespace within a cluster. When you deploy a pod +into a Namespace without referencing a specific service account, the +default service account for that Namespace will automatically get +assigned to the Pod and the Secret, i.e. the service account (JWT) token +for that service account, will get mounted to the pod as a volume at +`+/var/run/secrets/kubernetes.io/serviceaccount+`. Decoding the service +account token in that directory will reveal the following metadata: + +[source,json] +---- +{ + "iss": "kubernetes/serviceaccount", + "kubernetes.io/serviceaccount/namespace": "default", + "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", + "kubernetes.io/serviceaccount/service-account.name": "default", + "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", + "sub": "system:serviceaccount:default:default" +} +---- + +The default service account has the following permissions to the +Kubernetes API. + +[source,yaml] +---- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: "2020-01-30T18:13:25Z" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:discovery + resourceVersion: "43" + selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery + uid: 350d2ab8-438c-11ea-9438-063a49b60fba +rules: +- nonResourceURLs: + - /api + - /api/* + - /apis + - /apis/* + - /healthz + - /openapi + - /openapi/* + - /version + - /version/ + verbs: + - get +---- + +This role authorizes unauthenticated and authenticated users to read API +information and is deemed safe to be publicly accessible. + +When an application running within a Pod calls the Kubernetes APIs, the +Pod needs to be assigned a service account that explicitly grants it +permission to call those APIs. Similar to guidelines for user access, +the Role or ClusterRole bound to a service account should be restricted +to the API resources and methods that the application needs to function +and nothing else. To use a non-default service account simply set the +`+spec.serviceAccountName+` field of a Pod to the name of the service +account you wish to use. For additional information about creating +service accounts, see +https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions. + +!!! note Prior to Kubernetes 1.24, Kubernetes would automatically create +a secret for each a service account. This secret was mounted to the pod +at /var/run/secrets/kubernetes.io/serviceaccount and would be used by +the pod to authenticate to the Kubernetes API server. In Kubernetes +1.24, a service account token is dynamically generated when the pod runs +and is only valid for an hour by default. A secret for the service +account will not be created. If you have an application that runs +outside the cluster that needs to authenticate to the Kubernetes API, +e.g. Jenkins, you will need to create a secret of type +`+kubernetes.io/service-account-token+` along with an annotation that +references the service account such as +`+metadata.annotations.kubernetes.io/service-account.name: +`. +Secrets created in this way do not expire. + +==== IAM Roles for Service Accounts (IRSA) + +IRSA is a feature that allows you to assign an IAM role to a Kubernetes +service account. It works by leveraging a Kubernetes feature known as +https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection[Service +Account Token Volume Projection]. When Pods are configured with a +Service Account that references an IAM Role, the Kubernetes API server +will call the public OIDC discovery endpoint for the cluster on startup. +The endpoint cryptographically signs the OIDC token issued by Kubernetes +and the resulting token mounted as a volume. This signed token allows +the Pod to call the AWS APIs associated IAM role. When an AWS API is +invoked, the AWS SDKs calls `+sts:AssumeRoleWithWebIdentity+`. After +validating the token’s signature, IAM exchanges the Kubernetes issued +token for a temporary AWS role credential. + +When using IRSA, it is important to +link:#reuse-aws-sdk-sessions-with-irsa[reuse AWS SDK sessions] to avoid +unneeded calls to AWS STS. + +Decoding the (JWT) token for IRSA will produce output similar to the +example you see below: + +[source,json] +---- +{ + "aud": [ + "sts.amazonaws.com" + ], + "exp": 1582306514, + "iat": 1582220114, + "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", + "kubernetes.io": { + "namespace": "default", + "pod": { + "name": "alpine-57b5664646-rf966", + "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" + }, + "serviceaccount": { + "name": "s3-read-only", + "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" + } + }, + "nbf": 1582220114, + "sub": "system:serviceaccount:default:s3-read-only" +} +---- + +This particular token grants the Pod view-only privileges to S3 by +assuming an IAM role. When the application attempts to read from S3, the +token is exchanged for a temporary set of IAM credentials that resembles +this: + +[source,json] +---- +{ + "AssumedRoleUser": { + "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", + "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" + }, + "Audience": "sts.amazonaws.com", + "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", + "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", + "Credentials": { + "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1", + "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", + "Expiration": "2020-02-20T18:49:50Z", + "AccessKeyId": "XXXX36C6WWEJUMHA3L7Z" + } +} +---- + +A mutating webhook that runs as part of the EKS control plane injects +the AWS Role ARN and the path to a web identity token file into the Pod +as environment variables. These values can also be supplied manually. + +[source,bash] +---- +AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME +AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token +---- + +The kubelet will automatically rotate the projected token when it is +older than 80% of its total TTL, or after 24 hours. The AWS SDKs are +responsible for reloading the token when it rotates. For further +information about IRSA, see +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html. + +==== EKS Pod Identities + +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] is a feature launched at re:Invent 2023 that allows you +to assign an IAM role to a kubernetes service account, without the need +to configure an Open Id Connect (OIDC) identity provider(IDP) for each +cluster in your AWS account. To use EKS Pod Identity, you must deploy an +agent which runs as a DaemonSet pod on every eligible worker node. This +agent is made available to you as an EKS Add-on and is a pre-requisite +to use EKS Pod Identity feature. Your applications must use a +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html[supported +version of the AWS SDK] to use this feature. + +When EKS Pod Identities are configured for a Pod, EKS will mount and +refresh a pod identity token at +`+/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token+`. +This token will be used by the AWS SDK to communicate with the EKS Pod +Identity Agent, which uses the pod identity token and the agent’s IAM +role to create temporary credentials for your pods by calling the +https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html[AssumeRoleForPodIdentity +API]. The pod identity token delivered to your pods is a JWT issued from +your EKS cluster and cryptographically signed, with appropriate JWT +claims for use with EKS Pod Identities. + +To learn more about EKS Pod Identities, please see +https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/[this +blog]. + +You do not have to make any modifications to your application code to +use EKS Pod Identities. Supported AWS SDK versions will automatically +discover credentials made available with EKS Pod Identities by using the +https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html[credential +provider chain]. Like IRSA, EKS pod identities sets variables within +your pods to direct them how to find AWS credentials. + +===== Working with IAM roles for EKS Pod Identities + +* EKS Pod Identities can only directly assume an IAM role that belongs +to the same AWS account as the EKS cluster. To access an IAM role in +another AWS account, you must assume that role by +https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html[configuring +a profile in your SDK configuration], or in your +https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application’s +code]. +* When EKS Pod Identities are being configured for Service Accounts, the +person or process configuring the Pod Identity Association must have the +`+iam:PassRole+` entitlement for that role. +* Each Service Account may only have one IAM role associated with it +through EKS Pod Identities, however you can associate the same IAM role +with multiple service accounts. +* IAM roles used with EKS Pod Identities must allow the +`+pods.eks.amazonaws.com+` Service Principal to assume them, _and_ set +session tags. The following is an example role trust policy which allows +EKS Pod Identities to use an IAM role: + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "pods.eks.amazonaws.com" + }, + "Action": [ + "sts:AssumeRole", + "sts:TagSession" + ], + "Condition": { + "StringEquals": { + "aws:SourceOrgId": "${aws:ResourceOrgId}" + } + } + } + ] +} +---- + +AWS recommends using condition keys like `+aws:SourceOrgId+` to help +protect against the +https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention[cross-service +confused deputy problem]. In the above example role trust policy, the +`+ResourceOrgId+` is a variable equal to the AWS Organizations +Organization ID of the AWS Organization that the AWS account belongs to. +EKS will pass in a value for `+aws:SourceOrgId+` equal to that when +assuming a role with EKS Pod Identities. + +===== ABAC and EKS Pod Identities + +When EKS Pod Identities assumes an IAM role, it sets the following +session tags: + +[width="100%",cols="<50%,<50%",options="header",] +|=== +|EKS Pod Identities Session Tag |Value +|kubernetes-namespace |The namespace the pod associated with EKS Pod +Identities runs in. + +|kubernetes-service-account |The name of the kubernetes service account +associated with EKS Pod Identities + +|eks-cluster-arn |The ARN of the EKS cluster, +e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. +The cluster ARN is unique, but if a cluster is deleted and recreated in +the same region with the same name, within the same AWS account, it will +have the same ARN. + +|eks-cluster-name |The name of the EKS cluster. Please note that EKS +cluster names can be same within your AWS account, and EKS clusters in +other AWS accounts. + +|kubernetes-pod-name |The name of the pod in EKS. + +|kubernetes-pod-uid |The UID of the pod in EKS. +|=== + +These session tags allow you to use +https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html[Attribute +Based Access Control(ABAC)] to grant access to your AWS resources to +only specific kubernetes service accounts. When doing so, it is _very +important_ to understand that kubernetes service accounts are only +unique within a namespace, and kubernetes namespaces are only unique +within an EKS cluster. These session tags can be accessed in AWS +policies by using the `+aws:PrincipalTag/+` global condition +key, such as `+aws:PrincipalTag/eks-cluster-arn+` + +For example, if you wanted to grant access to only a specific service +account to access an AWS resource in your account with an IAM or +resource policy, you would need to check `+eks-cluster-arn+` and +`+kubernetes-namespace+` tags as well as the +`+kubernetes-service-account+` to ensure that only that service accounts +from the intended cluster have access to that resource as other clusters +could have identical `+kubernetes-service-accounts+` and +`+kubernetes-namespaces+`. + +This example S3 Bucket policy only grants access to objects in the S3 +bucket it’s attached to, only if `+kubernetes-service-account+`, +`+kubernetes-namespace+`, `+eks-cluster-arn+` all meet their expected +values, where the EKS cluster is hosted in the AWS account +`+111122223333+`. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111122223333:root" + }, + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::ExampleBucket/*" + ], + "Condition": { + "StringEquals": { + "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", + "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", + "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" + } + } + } + ] +} +---- + +==== EKS Pod Identities compared to IRSA + +Both EKS Pod Identities and IRSA are preferred ways to deliver temporary +AWS credentials to your EKS pods. Unless you have specific usecases for +IRSA, we recommend you use EKS Pod Identities when using EKS. This table +helps compare the two features. + +[width="100%",cols="<34%,<33%,<33%",options="header",] +|=== +|# |EKS Pod Identities |IRSA +|Requires permission to create an OIDC IDP in your AWS accounts? |No +|Yes + +|Requires unique IDP setup per cluster |No |Yes + +|Sets relevant session tags for use with ABAC |Yes |No + +|Requires an iam:PassRole Check? |Yes |No + +|Uses AWS STS Quota from your AWS account? |No |Yes + +|Can access other AWS accounts |Indirectly with role chaining |Directly +with sts:AssumeRoleWithWebIdentity + +|Compatible with AWS SDKs |Yes |Yes + +|Requires Pod Identity Agent Daemonset on nodes? |Yes |No +|=== + +=== Identities and Credentials for EKS pods Recommendations + +==== Update the aws-node daemonset to use IRSA + +At present, the aws-node daemonset is configured to use a role assigned +to the EC2 instances to assign IPs to pods. This role includes several +AWS managed policies, e.g. AmazonEKS_CNI_Policy and +EC2ContainerRegistryReadOnly that effectively allow *all* pods running +on a node to attach/detach ENIs, assign/unassign IP addresses, or pull +images from ECR. Since this presents a risk to your cluster, it is +recommended that you update the aws-node daemonset to use IRSA. A script +for doing this can be found in the +https://github.com/aws/aws-eks-best-practices/tree/master/projects/enable-irsa/src[repository] +for this guide. + +The aws-node daemonset does not support EKS Pod Identities at this time. + +==== Restrict access to the instance profile assigned to the worker node + +When you use IRSA or EKS Pod Identities, it updates the credential chain +of the pod to use IRSA or EKS Pod Identities first, however, the pod +_can still inherit the rights of the instance profile assigned to the +worker node_. When using IRSA or EKS Pod Identities, it is *strongly* +recommended that you block access +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[instance +metadata] to help ensure that your applications only have the +permissions they require, and not their nodes. + +!!! caution Blocking access to instance metadata will prevent pods that +do not use IRSA or EKS Pod Identities from inheriting the role assigned +to the worker node. + +You can block access to instance metadata by requiring the instance to +use IMDSv2 only and updating the hop count to 1 as in the example below. +You can also include these settings in the node group’s launch template. +Do *not* disable instance metadata as this will prevent components like +the node termination handler and other things that rely on instance +metadata from working properly. + +[source,bash] +---- +$ aws ec2 modify-instance-metadata-options --instance-id --http-tokens required --http-put-response-hop-limit 1 +... +---- + +If you are using Terraform to create launch templates for use with +Managed Node Groups, add the metadata block to configure the hop count +as seen in this code snippet: + +`+tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...+` + +You can also block a pod’s access to EC2 metadata by manipulating +iptables on the node. For further information about this method, see +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access[Limiting +access to the instance metadata service]. + +If you have an application that is using an older version of the AWS SDK +that doesn’t support IRSA or EKS Pod Identities, you should update the +SDK version. + +==== Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster + +The trust policy can be scoped to a Namespace or a specific service +account within a Namespace. When using IRSA it’s best to make the role +trust policy as explicit as possible by including the service account +name. This will effectively prevent other Pods within the same Namespace +from assuming the role. The CLI `+eksctl+` will do this automatically +when you use it to create service accounts/IAM roles. See +https://eksctl.io/usage/iamserviceaccounts/ for further information. + +When working with IAM directly, this is adding condition into the role’s +trust policy that uses conditions to ensure the `+:sub+` claim are the +namespace and service account you expect. As an example, before we had +an IRSA token with a sub claim of +"`system:serviceaccount:default:s3-read-only`" . This is the `+default+` +namespace and the service account is `+s3-read-only+`. You would use a +condition like the following to ensure that only your service account in +a given namespace from your cluster can assume that role: + +[source,json] +---- + "Condition": { + "StringEquals": { + "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", + "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" + } + } +---- + +==== Use one IAM role per application + +With both IRSA and EKS Pod Identity, it is a best practice to give each +application its own IAM role. This gives you improved isolation as you +can modify one application without impacting another, and allows you to +apply the principal of least privilege by only granting an application +the permissions it needs. + +When using ABAC with EKS Pod Identity, you may use a common IAM role +across multiple service accounts and rely on their session attributes +for access control. This is especially useful when operating at scale, +as ABAC allows you to operate with fewer IAM roles. + +==== When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2 + +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[IMDSv2] +requires you use a PUT request to get a session token. The initial PUT +request has to include a TTL for the session token. Newer versions of +the AWS SDKs will handle this and the renewal of said token +automatically. It’s also important to be aware that the default hop +limit on EC2 instances is intentionally set to 1 to prevent IP +forwarding. As a consequence, Pods that request a session token that are +run on EC2 instances may eventually time out and fallback to using the +IMDSv1 data flow. EKS adds support IMDSv2 by _enabling_ both v1 and v2 +and changing the hop limit to 2 on nodes provisioned by eksctl or with +the official CloudFormation templates. + +==== Disable auto-mounting of service account tokens + +If your application doesn’t need to call the Kubernetes API set the +`+automountServiceAccountToken+` attribute to `+false+` in the PodSpec +for your application or patch the default service account in each +namespace so that it’s no longer mounted to pods automatically. For +example: + +[source,bash] +---- +kubectl patch serviceaccount default -p $'automountServiceAccountToken: false' +---- + +==== Use dedicated service accounts for each application + +Each application should have its own dedicated service account. This +applies to service accounts for the Kubernetes API as well as IRSA and +EKS Pod Identity. + +!!! attention If you employ a blue/green approach to cluster upgrades +instead of performing an in-place cluster upgrade when using IRSA, you +will need to update the trust policy of each of the IRSA IAM roles with +the OIDC endpoint of the new cluster. A blue/green cluster upgrade is +where you create a cluster running a newer version of Kubernetes +alongside the old cluster and use a load balancer or a service mesh to +seamlessly shift traffic from services running on the old cluster to the +new cluster. When using blue/green cluster upgrades with EKS Pod +Identity, you would create pod identity associations between the IAM +roles and service accounts in the new cluster. And update the IAM role +trust policy if you have a `+sourceArn+` condition. + +==== Run the application as a non-root user + +Containers run as root by default. While this allows them to read the +web identity token file, running a container as root is not considered a +best practice. As an alternative, consider adding the +`+spec.securityContext.runAsUser+` attribute to the PodSpec. The value +of `+runAsUser+` is arbitrary value. + +In the following example, all processes within the Pod will run under +the user ID specified in the `+runAsUser+` field. + +[source,yaml] +---- +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + containers: + - name: sec-ctx-demo + image: busybox + command: [ "sh", "-c", "sleep 1h" ] +---- + +When you run a container as a non-root user, it prevents the container +from reading the IRSA service account token because the token is +assigned 0600 [root] permissions by default. If you update the +securityContext for your container to include fsgroup=65534 [Nobody] it +will allow the container to read the token. + +[source,yaml] +---- +spec: + securityContext: + fsGroup: 65534 +---- + +In Kubernetes 1.19 and above, this change is no longer required and +applications can read the IRSA service account token without adding them +to the Nobody group. + +==== Grant least privileged access to applications + +https://github.com/princespaghetti/actionhero[Action Hero] is a utility +that you can run alongside your application to identify the AWS API +calls and corresponding IAM permissions your application needs to +function properly. It is similar to +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html[IAM +Access Advisor] in that it helps you gradually limit the scope of IAM +roles assigned to applications. Consult the documentation on granting +https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege[least +privileged access] to AWS resources for further information. + +Consider setting a +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html[permissions +boundary] on IAM roles used with IRSA and Pod Identities. You can use +the permissions boundary to ensure that the roles used by IRSA or Pod +Identities can not exceed a maximum level of permissions. For an example +guide on getting started with permissions boundaries with an example +permissions boundary policy, please see this +https://github.com/aws-samples/example-permissions-boundary[github +repo]. + +==== Review and revoke unnecessary anonymous access to your EKS cluster + +Ideally anonymous access should be disabled for all API actions. +Anonymous access is granted by creating a RoleBinding or +ClusterRoleBinding for the Kubernetes built-in user system:anonymous. +You can use the https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] +tool to identify permissions that system:anonymous user has on your +cluster: + +[source,bash] +---- +./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' +system:anonymous cluster-wide ClusterRole/system:discovery +system:unauthenticated cluster-wide ClusterRole/system:discovery +system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer +---- + +Any role or ClusterRole other than system:public-info-viewer should not +be bound to system:anonymous user or system:unauthenticated group. + +There may be some legitimate reasons to enable anonymous access on +specific APIs. If this is the case for your cluster ensure that only +those specific APIs are accessible by anonymous user and exposing those +APIs without authentication doesn’t make your cluster vulnerable. + +Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was +associated to system:discovery and system:basic-user ClusterRoles by +default. Note that even if you have updated your cluster to version 1.14 +or higher, these permissions may still be enabled on your cluster, since +cluster updates do not revoke these permissions. To check which +ClusterRoles have "`system:unauthenticated`" except +system:public-info-viewer you can run the following command (requires jq +util): + +[source,bash] +---- +kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name' +---- + +And "`system:unauthenticated`" can be removed from all the roles except +"`system:public-info-viewer`" using: + +[source,bash] +---- +kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f - +---- + +Alternatively, you can check and remove it manually by kubectl describe +and kubectl edit. To check if system:unauthenticated group has +system:discovery permissions on your cluster run the following command: + +[source,bash] +---- +kubectl describe clusterrolebindings system:discovery + +Name: system:discovery +Labels: kubernetes.io/bootstrapping=rbac-defaults +Annotations: rbac.authorization.kubernetes.io/autoupdate: true +Role: + Kind: ClusterRole + Name: system:discovery +Subjects: + Kind Name Namespace + ---- ---- --------- + Group system:authenticated + Group system:unauthenticated +---- + +To check if system:unauthenticated group has system:basic-user +permission on your cluster run the following command: + +[source,bash] +---- +kubectl describe clusterrolebindings system:basic-user + +Name: system:basic-user +Labels: kubernetes.io/bootstrapping=rbac-defaults +Annotations: rbac.authorization.kubernetes.io/autoupdate: true +Role: + Kind: ClusterRole + Name: system:basic-user +Subjects: + Kind Name Namespace + ---- ---- --------- + Group system:authenticated + Group system:unauthenticated +---- + +If system:unauthenticated group is bound to system:discovery and/or +system:basic-user ClusterRoles on your cluster, you should disassociate +these roles from system:unauthenticated group. Edit system:discovery +ClusterRoleBinding using the following command: + +[source,bash] +---- +kubectl edit clusterrolebindings system:discovery +---- + +The above command will open the current definition of system:discovery +ClusterRoleBinding in an editor as shown below: + +[source,yaml] +---- +# Please edit the object below. Lines beginning with a '#' will be ignored, +# and an empty file will abort the edit. If an error occurs while saving this file will be +# reopened with the relevant failures. +# +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: "2021-06-17T20:50:49Z" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:discovery + resourceVersion: "24502985" + selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery + uid: b7936268-5043-431a-a0e1-171a423abeb6 +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:discovery +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:unauthenticated +---- + +Delete the entry for system:unauthenticated group from the "`subjects`" +section in the above editor screen. + +Repeat the same steps for system:basic-user ClusterRoleBinding. + +==== Reuse AWS SDK sessions with IRSA + +When you use IRSA, applications written using the AWS SDK use the token +delivered to your pods to call `+sts:AssumeRoleWithWebIdentity+` to +generate temporary AWS credentials. This is different from other AWS +compute services, where the compute service delivers temporary AWS +credentials directly to the AWS compute resource, such as a lambda +function. This means that every time an AWS SDK session is initialized, +a call to AWS STS for `+AssumeRoleWithWebIdentity+` is made. If your +application scales rapidly and initializes many AWS SDK sessions, you +may experience throttling from AWS STS as your code will be making many +calls for `+AssumeRoleWithWebIdentity+`. + +To avoid this scenario, we recommend reusing AWS SDK sessions within +your application so that unnecessary calls to +`+AssumeRoleWithWebIdentity+` are not made. + +In the following example code, a session is created using the boto3 +python SDK, and that same session is used to create clients and interact +with both Amazon S3 and Amazon SQS. `+AssumeRoleWithWebIdentity+` is +only called once, and the AWS SDK will refresh the credentials of +`+my_session+` when they expire automatically. + +```py hl_lines="`4 7 8`" + +import boto3 + +== Create your own session + +my_session = boto3.session.Session() + +== Now we can create low-level clients from our session + +sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') + +s3response = s3.list_buckets() sqsresponse = sqs.list_queues() + +#print the response from the S3 and SQS APIs print("`s3 response:`") +print(s3response) print("`—`") print("`sqs response:`") +print(sqsresponse) ``` + +If you’re migrating an application from another AWS compute service, +such as EC2, to EKS with IRSA, this is a particularly important detail. +On other compute services initializing an AWS SDK session does not call +AWS STS unless you instruct it to. + +==== Alternative approaches + +While IRSA and EKS Pod Identities are the _preferred ways_ to assign an +AWS identity to a pod, they require that you include recent version of +the AWS SDKs in your application. For a complete listing of the SDKs +that currently support IRSA, see +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, +for EKS Pod Identities, see +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. +If you have an application that you can’t immediately update with a +compatible SDK, there are several community-built solutions available +for assigning IAM roles to Kubernetes pods, including +https://github.com/jtblin/kube2iam[kube2iam] and +https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse, +condone, nor support the use of these solutions, they are frequently +used by the community at large to achieve similar results as IRSA and +EKS Pod Identities. + +If you need to use one of these non-aws provided solutions, please +exercise due diligence and ensure you understand security implications +of doing so. + +=== Tools and Resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon +EKS Security Immersion Workshop - Identity and Access Management] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/fully-private-cluster[Terraform +EKS Blueprints Pattern - Fully Private Amazon EKS Cluster] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-iam-identity-center[Terraform +EKS Blueprints Pattern - IAM Identity Center Single Sign-On for Amazon +EKS Cluster] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-okta[Terraform +EKS Blueprints Pattern - Okta Single Sign-On for Amazon EKS Cluster] +* https://github.com/liggitt/audit2rbac[audit2rbac] +* https://github.com/mhausenblas/rbac.dev[rbac.dev] A list of additional +resources, including blogs and tools, for Kubernetes RBAC +* https://github.com/princespaghetti/actionhero[Action Hero] +* https://github.com/jtblin/kube2iam[kube2iam] +* https://github.com/uswitch/kiam[kiam] diff --git a/latest/bpg/security/image.adoc b/latest/bpg/security/image.adoc new file mode 100644 index 000000000..cbd675a6c --- /dev/null +++ b/latest/bpg/security/image.adoc @@ -0,0 +1,500 @@ +== Image security + +You should consider the container image as your first line of defense +against an attack. An insecure, poorly constructed image can allow an +attacker to escape the bounds of the container and gain access to the +host. Once on the host, an attacker can gain access to sensitive +information or move laterally within the cluster or with your AWS +account. The following best practices will help mitigate risk of this +happening. + +=== Recommendations + +==== Create minimal images + +Start by removing all extraneous binaries from the container image. If +you’re using an unfamiliar image from Dockerhub, inspect the image using +an application like https://github.com/wagoodman/dive[Dive] which can +show you the contents of each of the container’s layers. Remove all +binaries with the SETUID and SETGID bits as they can be used to escalate +privilege and consider removing all shells and utilities like nc and +curl that can be used for nefarious purposes. You can find the files +with SETUID and SETGID bits with the following command: + +[source,bash] +---- +find / -perm /6000 -type f -exec ls -ld {} \; +---- + +To remove the special permissions from these files, add the following +directive to your container image: + +[source,docker] +---- +RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true +---- + +Colloquially, this is known as de-fanging your image. + +==== Use multi-stage builds + +Using multi-stage builds is a way to create minimal images. Oftentimes, +multi-stage builds are used to automate parts of the Continuous +Integration cycle. For example, multi-stage builds can be used to lint +your source code or perform static code analysis. This affords +developers an opportunity to get near immediate feedback instead of +waiting for a pipeline to execute. Multi-stage builds are attractive +from a security standpoint because they allow you to minimize the size +of the final image pushed to your container registry. Container images +devoid of build tools and other extraneous binaries improves your +security posture by reducing the attack surface of the image. For +additional information about multi-stage builds, see +https://docs.docker.com/develop/develop-images/multistage-build/[Docker’s +multi-stage builds documentation]. + +==== Create Software Bill of Materials (SBOMs) for your container image + +A "`software bill of materials`" (SBOM) is a nested inventory of the +software artifacts that make up your container image. SBOM is a key +building block in software security and software supply chain risk +management. https://anchore.com/sbom/[Generating, storing SBOMS in a +central repository and scanning SBOMs for vulnerabilities] helps address +the following concerns: + +* *Visibility*: understand what components make up your container image. +Storing in a central repository allows SBOMs to be audited and scanned +anytime, even post deployment to detect and respond to new +vulnerabilities such as zero day vulnerabilities. +* *Provenance Verification*: assurance that existing assumptions of +where and how an artifact originates from are true and that the artifact +or its accompanying metadata have not been tampered with during the +build or delivery processes. +* *Trustworthiness*: assurance that a given artifact and its contents +can be trusted to do what it is purported to do, i.e. is suitable for a +purpose. This involves judgement on whether the code is safe to execute +and making informed decisions about the risks associated with executing +the code. Trustworthiness is assured by creating an attested pipeline +execution report along with attested SBOM and attested CVE scan report +to assure the consumers of the image that this image is in-fact created +through secure means (pipeline) with secure components. +* *Dependency Trust Verification*: recursive checking of an artifact’s +dependency tree for trustworthiness and provenance of the artifacts it +uses. Drift in SBOMs can help detect malicious activity including +unauthorized, untrusted dependencies, infiltration attempts. + +The following tools can be used to generate SBOM: + +* https://docs.aws.amazon.com/inspector[Amazon Inspector] can be used to +https://docs.aws.amazon.com/inspector/latest/user/sbom-export.html[create +and export SBOMs]. +* https://github.com/anchore/syft[Syft from Anchore] can also be used +for SBOM generation. For quicker vulnerability scans, the SBOM generated +for a container image can be used as an input to scan. The SBOM and scan +report are then +https://github.com/sigstore/cosign/blob/main/doc/cosign_attach_attestation.md[attested +and attached] to the image before pushing the image to a central OCI +repository such as Amazon ECR for review and audit purposes. + +Learn more about securing your software supply chain by reviewing +https://project.linuxfoundation.org/hubfs/CNCF_SSCP_v1.pdf[CNCF Software +Supply Chain Best Practices guide]. + +==== Scan images for vulnerabilities regularly + +Like their virtual machine counterparts, container images can contain +binaries and application libraries with vulnerabilities or develop +vulnerabilities over time. The best way to safeguard against exploits is +by regularly scanning your images with an image scanner. Images that are +stored in Amazon ECR can be scanned on push or on-demand (once during a +24 hour period). ECR currently supports +https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html[two +types of scanning - Basic and Enhanced]. Basic scanning leverages +https://github.com/quay/clair[Clair] an open source image scanning +solution for no cost. +https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html[Enhanced +scanning] uses Amazon Inspector to provide automatic continuous scans +for https://aws.amazon.com/inspector/pricing/[additional cost]. After an +image is scanned, the results are logged to the event stream for ECR in +EventBridge. You can also see the results of a scan from within the ECR +console. Images with a HIGH or CRITICAL vulnerability should be deleted +or rebuilt. If an image that has been deployed develops a vulnerability, +it should be replaced as soon as possible. + +Knowing where images with vulnerabilities have been deployed is +essential to keeping your environment secure. While you could +conceivably build an image tracking solution yourself, there are already +several commercial offerings that provide this and other advanced +capabilities out of the box, including: + +* https://github.com/anchore/grype[Grype] +* https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/tools/twistcli_scan_images[Palo +Alto - Prisma Cloud (twistcli)] +* https://www.aquasec.com/[Aqua] +* https://github.com/Portshift/kubei[Kubei] +* https://github.com/aquasecurity/trivy[Trivy] +* https://support.snyk.io/hc/en-us/articles/360003946917-Test-images-with-the-Snyk-Container-CLI[Snyk] + +A Kubernetes validation webhook could also be used to validate that +images are free of critical vulnerabilities. Validation webhooks are +invoked prior to the Kubernetes API. They are typically used to reject +requests that don’t comply with the validation criteria defined in the +webhook. +https://aws.amazon.com/blogs/containers/building-serverless-admission-webhooks-for-kubernetes-with-aws-sam/[This] +is an example of a serverless webhook that calls the ECR +describeImageScanFindings API to determine whether a pod is pulling an +image with critical vulnerabilities. If vulnerabilities are found, the +pod is rejected and a message with list of CVEs is returned as an Event. + +==== Use attestations to validate artifact integrity + +An attestation is a cryptographically signed "`statement`" that claims +something - a "`predicate`" e.g. a pipeline run or the SBOM or the +vulnerability scan report is true about another thing - a "`subject`" +i.e. the container image. + +Attestations help users to validate that an artifact comes from a +trusted source in the software supply chain. As an example, we may use a +container image without knowing all the software components or +dependencies that are included in that image. However, if we trust +whatever the producer of the container image says about what software is +present, we can use the producer’s attestation to rely on that artifact. +This means that we can proceed to use the artifact safely in our +workflow in place of having done the analysis ourself. + +* Attestations can be created using +https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS +Signer] or +https://github.com/sigstore/cosign/blob/main/doc/cosign_attest.md[Sigstore +cosign]. +* Kubernetes admission controllers such as https://kyverno.io/[Kyverno] +can be used to +https://kyverno.io/docs/writing-policies/verify-images/sigstore/[verify +attestations]. +* Refer to this +https://catalog.us-east-1.prod.workshops.aws/workshops/49343bb7-2cc5-4001-9d3b-f6a33b3c4442/en-US/0-introduction[workshop] +to learn more about software supply chain management best practices on +AWS using open source tools with topics including creating and attaching +attestations to a container image. + +==== Create IAM policies for ECR repositories + +Nowadays, it is not uncommon for an organization to have multiple +development teams operating independently within a shared AWS account. +If these teams don’t need to share assets, you may want to create a set +of IAM policies that restrict access to the repositories each team can +interact with. A good way to implement this is by using ECR +https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html#repository-concepts[namespaces]. +Namespaces are a way to group similar repositories together. For +example, all of the registries for team A can be prefaced with the +team-a/ while those for team B can use the team-b/ prefix. The policy to +restrict access might look like the following: + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "AllowPushPull", + "Effect": "Allow", + "Action": [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload" + ], + "Resource": [ + "arn:aws:ecr:::repository/team-a/*" + ] + } + ] +} +---- + +==== Consider using ECR private endpoints + +The ECR API has a public endpoint. Consequently, ECR registries can be +accessed from the Internet so long as the request has been authenticated +and authorized by IAM. For those who need to operate in a sandboxed +environment where the cluster VPC lacks an Internet Gateway (IGW), you +can configure a private endpoint for ECR. Creating a private endpoint +enables you to privately access the ECR API through a private IP address +instead of routing traffic across the Internet. For additional +information on this topic, see +https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html[Amazon +ECR interface VPC endpoints]. + +==== Implement endpoint policies for ECR + +The default endpoint policy for allows access to all ECR repositories +within a region. This might allow an attacker/insider to exfiltrate data +by packaging it as a container image and pushing it to a registry in +another AWS account. Mitigating this risk involves creating an endpoint +policy that limits API access to ECR repositories. For example, the +following policy allows all AWS principles in your account to perform +all actions against your and only your ECR repositories: + +[source,json] +---- +{ + "Statement": [ + { + "Sid": "LimitECRAccess", + "Principal": "*", + "Action": "*", + "Effect": "Allow", + "Resource": "arn:aws:ecr:::repository/*" + } + ] +} +---- + +You can enhance this further by setting a condition that uses the new +`+PrincipalOrgID+` attribute which will prevent pushing/pulling of +images by an IAM principle that is not part of your AWS Organization. +See, +https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid[aws:PrincipalOrgID] +for additional details. We recommended applying the same policy to both +the `+com.amazonaws..ecr.dkr+` and the +`+com.amazonaws..ecr.api+` endpoints. Since EKS pulls images for +kube-proxy, coredns, and aws-node from ECR, you will need to add the +account ID of the registry, +e.g. `+602401143452.dkr.ecr.us-west-2.amazonaws.com/*+` to the list of +resources in the endpoint policy or alter the policy to allow pulls from +“*” and restrict pushes to your account ID. The table below reveals the +mapping between the AWS accounts where EKS images are vended from and +cluster region. + +[cols=",",options="header",] +|=== +|Account Number |Region +|602401143452 |All commercial regions except for those listed below +|— |— +|800184023465 |ap-east-1 - Asia Pacific (Hong Kong) +|558608220178 |me-south-1 - Middle East (Bahrain) +|918309763551 |cn-north-1 - China (Beijing) +|961992271922 |cn-northwest-1 - China (Ningxia) +|=== + +For further information about using endpoint policies, see +https://aws.amazon.com/blogs/containers/using-vpc-endpoint-policies-to-control-amazon-ecr-access/[Using +VPC endpoint policies to control Amazon ECR access]. + +==== Implement lifecycle policies for ECR + +The +https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf[NIST +Application Container Security Guide] warns about the risk of "`stale +images in registries`", noting that over time old images with +vulnerable, out-of-date software packages should be removed to prevent +accidental deployment and exposure. Each ECR repository can have a +lifecycle policy that sets rules for when images expire. The +https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html[AWS +official documentation] describes how to set up test rules, evaluate +them and then apply them. There are several +https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html[lifecycle +policy examples] in the official docs that show different ways of +filtering the images in a repository: + +* Filtering by image age or count +* Filtering by tagged or untagged images +* Filtering by image tags, either in multiple rules or a single rule + +???+ warning If the image for long running application is purged from +ECR, it can cause an image pull errors when the application is +redeployed or scaled horizontally. When using image lifecycle policies, +be sure you have good CI/CD practices in place to keep deployments and +the images that they reference up to date and always create [image] +expiry rules that account for how often you do releases/deployments. + +==== Create a set of curated images + +Rather than allowing developers to create their own images, consider +creating a set of vetted images for the different application stacks in +your organization. By doing so, developers can forego learning how to +compose Dockerfiles and concentrate on writing code. As changes are +merged into Master, a CI/CD pipeline can automatically compile the +asset, store it in an artifact repository and copy the artifact into the +appropriate image before pushing it to a Docker registry like ECR. At +the very least you should create a set of base images from which +developers to create their own Dockerfiles. Ideally, you want to avoid +pulling images from Dockerhub because 1/ you don’t always know what is +in the image and 2/ about +https://www.kennasecurity.com/blog/one-fifth-of-the-most-used-docker-containers-have-at-least-one-critical-vulnerability/[a +fifth] of the top 1000 images have vulnerabilities. A list of those +images and their vulnerabilities can be found +https://vulnerablecontainers.org/[here]. + +==== Add the USER directive to your Dockerfiles to run as a non-root user + +As was mentioned in the pod security section, you should avoid running +container as root. While you can configure this as part of the podSpec, +it is a good habit to use the `+USER+` directive to your Dockerfiles. +The `+USER+` directive sets the UID to use when running `+RUN+`, +`+ENTRYPOINT+`, or `+CMD+` instruction that appears after the USER +directive. + +==== Lint your Dockerfiles + +Linting can be used to verify that your Dockerfiles are adhering to a +set of predefined guidelines, e.g. the inclusion of the `+USER+` +directive or the requirement that all images be tagged. +https://github.com/projectatomic/dockerfile_lint[dockerfile_lint] is an +open source project from RedHat that verifies common best practices and +includes a rule engine that you can use to build your own rules for +linting Dockerfiles. It can be incorporated into a CI pipeline, in that +builds with Dockerfiles that violate a rule will automatically fail. + +==== Build images from Scratch + +Reducing the attack surface of your container images should be primary +aim when building images. The ideal way to do this is by creating +minimal images that are devoid of binaries that can be used to exploit +vulnerabilities. Fortunately, Docker has a mechanism to create images +from +https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch[`+scratch+`]. +With languages like Go, you can create a static linked binary and +reference it in your Dockerfile as in this example: + +[source,docker] +---- +############################ +# STEP 1 build executable binary +############################ +FROM golang:alpine AS builder# Install git. +# Git is required for fetching the dependencies. +RUN apk update && apk add --no-cache gitWORKDIR $GOPATH/src/mypackage/myapp/COPY . . # Fetch dependencies. +# Using go get. +RUN go get -d -v# Build the binary. +RUN go build -o /go/bin/hello + +############################ +# STEP 2 build a small image +############################ +FROM scratch# Copy our static executable. +COPY --from=builder /go/bin/hello /go/bin/hello# Run the hello binary. +ENTRYPOINT ["/go/bin/hello"] +---- + +This creates a container image that consists of your application and +nothing else, making it extremely secure. + +==== Use immutable tags with ECR + +https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/[Immutable +tags] force you to update the image tag on each push to the image +repository. This can thwart an attacker from overwriting an image with a +malicious version without changing the image’s tags. Additionally, it +gives you a way to easily and uniquely identify an image. + +==== Sign your images, SBOMs, pipeline runs and vulnerability reports + +When Docker was first introduced, there was no cryptographic model for +verifying container images. With v2, Docker added digests to the image +manifest. This allowed an image’s configuration to be hashed and for the +hash to be used to generate an ID for the image. When image signing is +enabled, the Docker engine verifies the manifest’s signature, ensuring +that the content was produced from a trusted source and no tampering has +occurred. After each layer is downloaded, the engine verifies the digest +of the layer, ensuring that the content matches the content specified in +the manifest. Image signing effectively allows you to create a secure +supply chain, through the verification of digital signatures associated +with the image. + +We can use +https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS +Signer] or https://github.com/sigstore/cosign[Sigstore Cosign], to sign +container images, create attestations for SBOMs, vulnerability scan +reports and pipeline run reports. These attestations assure the +trustworthiness and integrity of the image, that it is in fact created +by the trusted pipeline without any interference or tampering, and that +it contains only the software components that are documented (in the +SBOM) that is verified and trusted by the image publisher. These +attestations can be attached to the container image and pushed to the +repository. + +In the next section we will see how to use the attested artifacts for +audits and admissions controller verification. + +==== Image integrity verification using Kubernetes admission controller + +We can verify image signatures, attested artifacts in an automated way +before deploying the image to target Kubernetes cluster using +https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/[dynamic +admission controller] and admit deployments only when the security +metadata of the artifacts comply with the admission controller policies. + +For example we can write a policy that cryptographically verifies the +signature of an image, an attested SBOM, attested pipeline run report, +or attested CVE scan report. We can write conditions in the policy to +check data in the report, e.g. a CVE scan should not have any critical +CVEs. Deployment is allowed only for images that satisfy these +conditions and all other deployments will be rejected by the admissions +controller. + +Examples of admission controller include: + +* https://kyverno.io/[Kyverno] +* https://github.com/open-policy-agent/gatekeeper[OPA Gatekeeper] +* https://github.com/IBM/portieris[Portieris] +* https://github.com/deislabs/ratify[Ratify] +* https://github.com/grafeas/kritis[Kritis] +* https://github.com/kelseyhightower/grafeas-tutorial[Grafeas tutorial] +* https://github.com/Shopify/voucher[Voucher] + +==== Update the packages in your container images + +You should include RUN `+apt-get update && apt-get upgrade+` in your +Dockerfiles to upgrade the packages in your images. Although upgrading +requires you to run as root, this occurs during image build phase. The +application doesn’t need to run as root. You can install the updates and +then switch to a different user with the USER directive. If your base +image runs as a non-root user, switch to root and back; don’t solely +rely on the maintainers of the base image to install the latest security +updates. + +Run `+apt-get clean+` to delete the installer files from +`+/var/cache/apt/archives/+`. You can also run +`+rm -rf /var/lib/apt/lists/*+` after installing packages. This removes +the index files or the lists of packages that are available to install. +Be aware that these commands may be different for each package manager. +For example: + +[source,docker] +---- +RUN apt-get update && apt-get install -y \ + curl \ + git \ + libsqlite3-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* +---- + +=== Tools and resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/12-image-security[Amazon +EKS Security Immersion Workshop - Image Security] +* https://github.com/docker-slim/docker-slim[docker-slim] Build secure +minimal images +* https://github.com/goodwithtech/dockle[dockle] Verifies that your +Dockerfile aligns with best practices for creating secure images +* https://github.com/projectatomic/dockerfile_lint[dockerfile-lint] Rule +based linter for Dockerfiles +* https://github.com/hadolint/hadolint[hadolint] A smart dockerfile +linter +* https://github.com/open-policy-agent/gatekeeper[Gatekeeper and OPA] A +policy based admission controller +* https://kyverno.io/[Kyverno] A Kubernetes-native policy engine +* https://in-toto.io/[in-toto] Allows the user to verify if a step in +the supply chain was intended to be performed, and if the step was +performed by the right actor +* https://github.com/theupdateframework/notary[Notary] A project for +signing container images +* https://github.com/notaryproject/nv2[Notary v2] +* https://grafeas.io/[Grafeas] An open artifact metadata API to audit +and govern your software supply chain +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides container, image and +registry scanning for vulnerabilities, secrets and compliance. diff --git a/latest/bpg/security/incidents.adoc b/latest/bpg/security/incidents.adoc new file mode 100644 index 000000000..a063a89fc --- /dev/null +++ b/latest/bpg/security/incidents.adoc @@ -0,0 +1,248 @@ +== Incident response and forensics + +Your ability to react quickly to an incident can help minimize damage +caused from a breach. Having a reliable alerting system that can warn +you of suspicious behavior is the first step in a good incident response +plan. When an incident does arise, you have to quickly decide whether to +destroy and replace the effected container, or isolate and inspect the +container. If you choose to isolate the container as part of a forensic +investigation and root cause analysis, then the following set of +activities should be followed: + +=== Sample incident response plan + +==== Identify the offending Pod and worker node + +Your first course of action should be to isolate the damage. Start by +identifying where the breach occurred and isolate that Pod and its node +from the rest of the infrastructure. + +==== Identify the offending Pods and worker nodes using workload name + +If you know the name and namespace of the offending pod, you can +identify the the worker node running the pod as follows: + +[source,bash] +---- +kubectl get pods --namespace -o=jsonpath='{.spec.nodeName}{"\n"}' +---- + +If a https://kubernetes.io/docs/concepts/workloads/controllers/[Workload +Resource] such as a Deployment has been compromised, it is likely that +all the pods that are part of the workload resource are compromised. Use +the following command to list all the pods of the Workload Resource and +the nodes they are running on: + +[source,bash] +---- +selector=$(kubectl get deployments \ + --namespace -o json | jq -j \ +'.spec.selector.matchLabels | to_entries | .[] | "\(.key)=\(.value)"') + +kubectl get pods --namespace --selector=$selector \ +-o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"' +---- + +The above command is for deployments. You can run the same command for +other workload resources such as replicasets,, statefulsets, etc. + +==== Identify the offending Pods and worker nodes using service account name + +In some cases, you may identify that a service account is compromised. +It is likely that pods using the identified service account are +compromised. You can identify all the pods using the service account and +nodes they are running on with the following command: + +[source,bash] +---- +kubectl get pods -o json --namespace | \ + jq -r '.items[] | + select(.spec.serviceAccount == "") | + "\(.metadata.name) \(.spec.nodeName)"' +---- + +==== Identify Pods with vulnerable or compromised images and worker nodes + +In some cases, you may discover that a container image being used in +pods on your cluster is malicious or compromised. A container image is +malicious or compromised, if it was found to contain malware, is a known +bad image or has a CVE that has been exploited. You should consider all +the pods using the container image compromised. You can identify the +pods using the image and nodes they are running on with the following +command: + +[source,bash] +---- +IMAGE= + +kubectl get pods -o json --all-namespaces | \ + jq -r --arg image "$IMAGE" '.items[] | + select(.spec.containers[] | .image == $image) | + "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"' +---- + +==== Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod + +A deny all traffic rule may help stop an attack that is already underway +by severing all connections to the pod. The following Network Policy +will apply to a pod with the label `+app=web+`. + +[source,yaml] +---- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny +spec: + podSelector: + matchLabels: + app: web + policyTypes: + - Ingress + - Egress +---- + +!!! attention A Network Policy may prove ineffective if an attacker has +gained access to underlying host. If you suspect that has happened, you +can use +https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS +Security Groups] to isolate a compromised host from other hosts. When +changing a host’s security group, be aware that it will impact all +containers running on that host. + +==== Revoke temporary security credentials assigned to the pod or worker node if necessary + +If the worker node has been assigned an IAM role that allows Pods to +gain access to other AWS resources, remove those roles from the instance +to prevent further damage from the attack. Similarly, if the Pod has +been assigned an IAM role, evaluate whether you can safely remove the +IAM policies from the role without impacting other workloads. + +==== Cordon the worker node + +By cordoning the impacted worker node, you’re informing the scheduler to +avoid scheduling pods onto the affected node. This will allow you to +remove the node for forensic study without disrupting other workloads. + +!!! info This guidance is not applicable to Fargate where each Fargate +pod run in its own sandboxed environment. Instead of cordoning, +sequester the affected Fargate pods by applying a network policy that +denies all ingress and egress traffic. + +==== Enable termination protection on impacted worker node + +An attacker may attempt to erase their misdeeds by terminating an +affected node. Enabling +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingDisableAPITermination[termination +protection] can prevent this from happening. +https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection[Instance +scale-in protection] will protect the node from a scale-in event. + +!!! warning You cannot enable termination protection on a Spot instance. + +==== Label the offending Pod/Node with a label indicating that it is part of an active investigation + +This will serve as a warning to cluster administrators not to tamper +with the affected Pods/Nodes until the investigation is complete. + +==== Capture volatile artifacts on the worker node + +* *Capture the operating system memory*. This will capture the Docker +daemon (or other container runtime) and its subprocesses per container. +This can be accomplished using tools like +https://github.com/504ensicsLabs/LiME[LiME] and +https://www.volatilityfoundation.org/[Volatility], or through +higher-level tools such as +https://aws.amazon.com/solutions/implementations/automated-forensics-orchestrator-for-amazon-ec2/[Automated +Forensics Orchestrator for Amazon EC2] that build on top of them. +* *Perform a netstat tree dump of the processes running and the open +ports*. This will capture the docker daemon and its subprocess per +container. +* *Run commands to save container-level state before evidence is +altered*. You can use capabilities of the container runtime to capture +information about currently running containers. For example, with +Docker, you could do the following: +** `+docker top CONTAINER+` for processes running. +** `+docker logs CONTAINER+` for daemon level held logs. +** `+docker inspect CONTAINER+` for various information about the +container. ++ +The same could be achieved with containerd using the +https://github.com/containerd/nerdctl[nerdctl] CLI, in place of +`+docker+` (e.g. `+nerdctl inspect+`). Some additional commands are +available depending on the container runtime. For example, Docker has +`+docker diff+` to see changes to the container filesystem or +`+docker checkpoint+` to save all container state including volatile +memory (RAM). See +https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/[this +Kubernetes blog post] for discussion of similar capabilities with +containerd or CRI-O runtimes. +* *Pause the container for forensic capture*. +* *Snapshot the instance’s EBS volumes*. + +==== Redeploy compromised Pod or Workload Resource + +Once you have gathered data for forensic analysis, you can redeploy the +compromised pod or workload resource. + +First roll out the fix for the vulnerability that was compromised and +start new replacement pods. Then delete the vulnerable pods. + +If the vulnerable pods are managed by a higher-level Kubernetes workload +resource (for example, a Deployment or DaemonSet), deleting them will +schedule new ones. So vulnerable pods will be launched again. In that +case you should deploy a new replacement workload resource after fixing +the vulnerability. Then you should delete the vulnerable workload. + +=== Recommendations + +==== Review the AWS Security Incident Response Whitepaper + +While this section gives a brief overview along with a few +recommendations for handling suspected security breaches, the topic is +exhaustively covered in the white paper, +https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/welcome.html[AWS +Security Incident Response]. + +==== Practice security game days + +Divide your security practitioners into 2 teams: red and blue. The red +team will be focused on probing different systems for vulnerabilities +while the blue team will be responsible for defending against them. If +you don’t have enough security practitioners to create separate teams, +consider hiring an outside entity that has knowledge of Kubernetes +exploits. + +https://github.com/cyberark/kubesploit[Kubesploit] is a penetration +testing framework from CyberArk that you can use to conduct game days. +Unlike other tools which scan your cluster for vulnerabilities, +kubesploit simulates a real-world attack. This gives your blue team an +opportunity to practice its response to an attack and gauge its +effectiveness. + +==== Run penetration tests against your cluster + +Periodically attacking your own cluster can help you discover +vulnerabilities and misconfigurations. Before getting started, follow +the https://aws.amazon.com/security/penetration-testing/[penetration +test guidelines] before conducting a test against your cluster. + +=== Tools and resources + +* https://github.com/aquasecurity/kube-hunter[kube-hunter], a +penetration testing tool for Kubernetes. +* https://www.gremlin.com/product/#kubernetes[Gremlin], a chaos +engineering toolkit that you can use to simulate attacks against your +applications and infrastructure. +* https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/AtredisPartners_Attacking_Kubernetes-v1.0.pdf[Attacking +and Defending Kubernetes Installations] +* https://www.cyberark.com/resources/threat-research-blog/kubesploit-a-new-offensive-tool-for-testing-containerized-environments[kubesploit] +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides vulnerability- and risk +reporting as well as security event notification +* https://www.youtube.com/watch?v=CH7S5rE3j8w[Advanced Persistent +Threats] +* https://www.youtube.com/watch?v=LtCx3zZpOfs[Kubernetes Practical +Attack and Defense] +* https://www.youtube.com/watch?v=1LMo0CftVC4[Compromising Kubernetes +Cluster by Exploiting RBAC Permissions] diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc new file mode 100644 index 000000000..a52a9c758 --- /dev/null +++ b/latest/bpg/security/index.adoc @@ -0,0 +1,127 @@ +== Amazon EKS Best Practices Guide for Security + +This guide provides advice about protecting information, systems, and +assets that are reliant on EKS while delivering business value through +risk assessments and mitigation strategies. The guidance herein is part +of a series of best practices guides that AWS is publishing to help +customers implement EKS in accordance with best practices. Guides for +Performance, Operational Excellence, Cost Optimization, and Reliability +will be available in the coming months. + +=== How to use this guide + +This guide is meant for security practitioners who are responsible for +implementing and monitoring the effectiveness of security controls for +EKS clusters and the workloads they support. The guide is organized into +different topic areas for easier consumption. Each topic starts with a +brief overview, followed by a list of recommendations and best practices +for securing your EKS clusters. The topics do not need to be read in a +particular order. + +=== Understanding the Shared Responsibility Model + +Security and compliance are considered shared responsibilities when +using a managed service like EKS. Generally speaking, AWS is responsible +for security "`of`" the cloud whereas you, the customer, are responsible +for security "`in`" the cloud. With EKS, AWS is responsible for managing +of the EKS managed Kubernetes control plane. This includes the +Kubernetes control plane nodes, the ETCD database, and other +infrastructure necessary for AWS to deliver a secure and reliable +service. As a consumer of EKS, you are largely responsible for the +topics in this guide, e.g. IAM, pod security, runtime security, network +security, and so forth. + +When it comes to infrastructure security, AWS will assume additional +responsibilities as you move from self-managed workers, to managed node +groups, to Fargate. For example, with Fargate, AWS becomes responsible +for securing the underlying instance/runtime used to run your Pods. + +.Shared Responsibility Model - Fargate +image::images/SRM-EKS.jpg[Shared Responsibility Model - Fargate] + +AWS will also assume responsibility of keeping the EKS optimized AMI up +to date with Kubernetes patch versions and security patches. Customers +using Managed Node Groups (MNG) are responsible for upgrading their +Nodegroups to the latest AMI via EKS API, CLI, Cloudformation or AWS +Console. Also unlike Fargate, MNGs will not automatically scale your +infrastructure/cluster. That can be handled by the +https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md[cluster-autoscaler] +or other technologies such as https://karpenter.sh/[Karpenter], native +AWS autoscaling, SpotInst’s +https://spot.io/solutions/kubernetes-2/[Ocean], or Atlassian’s +https://github.com/atlassian/escalator[Escalator]. + +.Shared Responsibility Model - MNG +image::./images/SRM-MNG.jpg[Shared Responsibility Model - MNG] + +Before designing your system, it is important to know where the line of +demarcation is between your responsibilities and the provider of the +service (AWS). + +For additional information about the shared responsibility model, see +https://aws.amazon.com/compliance/shared-responsibility-model/ + +=== Introduction + +There are several security best practice areas that are pertinent when +using a managed Kubernetes service like EKS: + +* Identity and Access Management +* Pod Security +* Runtime Security +* Network Security +* Multi-tenancy +* Multi Account for Multi-tenancy +* Detective Controls +* Infrastructure Security +* Data Encryption and Secrets Management +* Regulatory Compliance +* Incident Response and Forensics +* Image Security + +As part of designing any system, you need to think about its security +implications and the practices that can affect your security posture. +For example, you need to control who can perform actions against a set +of resources. You also need the ability to quickly identify security +incidents, protect your systems and services from unauthorized access, +and maintain the confidentiality and integrity of data through data +protection. Having a well-defined and rehearsed set of processes for +responding to security incidents will improve your security posture too. +These tools and techniques are important because they support objectives +such as preventing financial loss or complying with regulatory +obligations. + +AWS helps organizations achieve their security and compliance goals by +offering a rich set of security services that have evolved based on +feedback from a broad set of security conscious customers. By offering a +highly secure foundation, customers can spend less time on +"`undifferentiated heavy lifting`" and more time on achieving their +business objectives. + +=== Feedback + +This guide is being released on GitHub so as to collect direct feedback +and suggestions from the broader EKS/Kubernetes community. If you have a +best practice that you feel we ought to include in the guide, please +file an issue or submit a PR in the GitHub repository. Our intention is +to update the guide periodically as new features are added to the +service or when a new best practice evolves. + +=== Further Reading + +https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/Kubernetes%20White%20Paper.pdf[Kubernetes +Security Whitepaper], sponsored by the Security Audit Working Group, +this Whitepaper describes key aspects of the Kubernetes attack surface +and security architecture with the aim of helping security practitioners +make sound design and implementation decisions. + +The CNCF published also a +https://github.com/cncf/tag-security/blob/efb183dc4f19a1bf82f967586c9dfcb556d87534/security-whitepaper/v2/CNCF_cloud-native-security-whitepaper-May2022-v2.pdf[white +paper] on cloud native security. The paper examines how the technology +landscape has evolved and advocates for the adoption of security +practices that align with DevOps processes and agile methodologies. + +=== Tools and resources + +https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS +Security Immersion Workshop] diff --git a/latest/bpg/security/multiaccount.adoc b/latest/bpg/security/multiaccount.adoc new file mode 100644 index 000000000..448bddeb6 --- /dev/null +++ b/latest/bpg/security/multiaccount.adoc @@ -0,0 +1,422 @@ +== Multi Account Strategy + +AWS recommends using a +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi +account strategy] and AWS organizations to help isolate and manage your +business applications and data. There are +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html[many +benefits] to using a multi account strategy: + +* Increased AWS API service quotas. Quotas are applied to AWS accounts, +and using multiple accounts for your workloads increases the overall +quota available to your workloads. +* Simpler Identity and Access Management (IAM) policies. Granting +workloads and the operators that support them access to only their own +AWS accounts means less time crafting fine-grained IAM policies to +achieve the principle of least privilege. +* Improved Isolation of AWS resources. By design, all resources +provisioned within an account are logically isolated from resources +provisioned in other accounts. This isolation boundary provides you with +a way to limit the risks of an application-related issue, +misconfiguration, or malicious actions. If an issue occurs within one +account, impacts to workloads contained in other accounts can be either +reduced or eliminated. +* More benefits, as described in the +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html#group-workloads-based-on-business-purpose-and-ownership[AWS +Multi Account Strategy Whitepaper] + +The following sections will explain how to implement a multi account +strategy for your EKS workloads using either a centralized, or +de-centralized EKS cluster approach. + +=== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters + +In a multi account AWS strategy, resources that belong to a given +workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables +are all created in an AWS account that contains all the resources for +that workload. These are referred to as a workload account, and the EKS +cluster is deployed into an account referred to as the cluster account. +Cluster accounts will be explored in the next section. Deploying +resources into a dedicated workload account is similar to deploying +kubernetes resources into a dedicated namespace. + +Workload accounts can then be further broken down by software +development lifecycle or other requirements if appropriate. For example +a given workload can have a production account, a development account, +or accounts for hosting instances of that workload in a specific region. +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-workload-oriented-ous.html[More +information] is available in this AWS whitepaper. + +You can adopt the following approaches when implementing EKS Multi +account strategy: + +=== Centralized EKS Cluster + +In this approach, your EKS Cluster will be deployed in a single AWS +account called the `+Cluster Account+`. Using +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts (IRSA)] or +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] to deliver temporary AWS credentials and +https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to +simplify network access, you can adopt a multi account strategy for your +multi tenant EKS cluster. The cluster account will contain the VPC, +subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and +any additional networking configurations needed to run your EKS cluster. + +In a multi workload account strategy for multi tenant cluster, AWS +accounts typically align with +https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes +namespaces] as a mechanism for isolating groups of resources. +link:/security/docs/multitenancy/[Best practices for tenant isolation] +within an EKS cluster should still be followed when implementing a multi +account strategy for multi tenant EKS clusters. + +It is possible to have multiple `+Cluster Accounts+` in your AWS +organization, and it is a best practice to have multiple +`+Cluster Accounts+` that align with your software development lifecycle +needs. For workloads operating at a very large scale, you may require +multiple `+Cluster Accounts+` to ensure that there are enough kubernetes +and AWS service quotas available to all your workloads. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks.jpg[multi-account-eks] +|In the above diagram, AWS RAM is used to share subnets from a cluster +account into a workload account. Then workloads running in EKS pods use +IRSA or EKS Pod Identities and role chaining to assume a role in their +workload account and access their AWS resources. +|=== + +==== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster + +===== Sharing Subnets With AWS Resource Access Manager + +https://aws.amazon.com/ram/[AWS Resource Access Manager] (RAM) allows +you to share resources across AWS accounts. + +If +https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html#getting-started-sharing-orgs[RAM +is enabled for your AWS Organization], you can share the VPC Subnets +from the Cluster account to your workload accounts. This will allow AWS +resources owned by your workload accounts, such as +https://aws.amazon.com/elasticache/[Amazon ElastiCache] Clusters or +https://aws.amazon.com/rds/[Amazon Relational Database Service (RDS)] +Databases to be deployed into the same VPC as your EKS cluster, and be +consumable by the workloads running on your EKS cluster. + +To share a resource via RAM, open up RAM in the AWS console of the +cluster account and select "`Resource Shares`" and "`Create Resource +Share`". Name your Resource Share and Select the subnets you want to +share. Select Next again and enter the 12 digit account IDs for the +workload accounts you wish to share the subnets with, select next again, +and click Create resource share to finish. After this step, the workload +account can deploy resources into those subnets. + +RAM shares can also be created programmatically, or with infrastructure +as code. + +===== Choosing Between EKS Pod Identities and IRSA + +At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of +delivering temporary AWS credentials to your pods on EKS. Both IRSA and +EKS Pod Identities are valid methods for delivering temporary AWS +credentials to your EKS pods and will continue to be supported. You +should consider which method of delivering best meets your needs. + +When working with a EKS cluster and multiple AWS accounts, IRSA can +directly assume roles in AWS accounts other than the account the EKS +cluster is hosted in directly, while EKS Pod identities require you to +configure role chaining. Refer +https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html#service-accounts-iam[EKS +documentation] for an in-depth comparison. + +====== Accessing AWS API Resources with IAM Roles For Service Accounts + +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +Roles for Service Accounts (IRSA)] allows you to deliver temporary AWS +credentials to your workloads running on EKS. IRSA can be used to get +temporary credentials for IAM roles in the workload accounts from the +cluster account. This allows your workloads running on your EKS clusters +in the cluster account to consume AWS API resources, such as S3 buckets +hosted in the workload account seemlessly, and use IAM authentication +for resources like Amazon RDS Databases or Amazon EFS FileSystems. + +AWS API resources and other Resources that use IAM authentication in a +workload account can only be accessed by credentials for IAM roles in +that same workload account, except where cross account access is capable +and has been explicity enabled. + +======= Enabling IRSA for cross account access + +To enable IRSA for workloads in your Cluster Account to access resources +in your Workload accounts, you first must create an IAM OIDC identity +provider in your workload account. This can be done with the same +procedure for setting up +https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html[IRSA], +except the Identity Provider will be created in the workload account. + +Then when configuring IRSA for your workloads on EKS, you can +https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html[follow +the same steps as the documentation], but use the +https://docs.aws.amazon.com/eks/latest/userguide/cross-account-access.html[12 +digit account id of the workload account] as mentioned in the section +"`Example Create an identity provider from another account’s cluster`". + +After this is configured, your application running in EKS will be able +to directly use its service account to assume a role in the workload +account, and use resources within it. + +====== Accessing AWS API Resources with EKS Pod Identities + +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] is a new way of delivering AWS credentials to your +workloads running on EKS. EKS pod identities simplifies the +configuration of AWS resources as you no longer need to manage OIDC +configurations to deliver AWS credentials to your pods on EKS. + +======= Enabling EKS Pod Identities for cross account access + +Unlike IRSA, EKS Pod Identities can only be used to directly grant +access to a role in the same account as the EKS cluster. To access a +role in another AWS account, pods that use EKS Pod Identities must +perform +https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining[Role +Chaining]. + +Role chaining can be configured in an applications profile with their +aws configuration file using the +https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process +Credentials Provider] available in various AWS SDKs. +`+credential_process+` can be used as a credential source when +configuring a profile, such as: + +[source,bash] +---- +# Content of the AWS Config file +[profile account_b_role] +source_profile = account_a_role +role_arn = arn:aws:iam::444455556666:role/account-b-role + +[profile account_a_role] +credential_process = /eks-credential-processrole.sh +---- + +The source of the script called by credential_process: + +[source,bash] +---- +#!/bin/bash +# Content of the eks-credential-processrole.sh +# This will retreive the credential from the pod identities agent, +# and return it to the AWS SDK when referenced in a profile +curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}' +---- + +You can create an aws config file as shown above with both Account A and +B roles and specify the AWS_CONFIG_FILE and AWS_PROFILE env vars in your +pod spec. EKS Pod identity webhook does not override if the env vars +already exists in the pod spec. + +[source,yaml] +---- +# Snippet of the PodSpec +containers: + - name: container-name + image: container-image:version + env: + - name: AWS_CONFIG_FILE + value: path-to-customer-provided-aws-config-file + - name: AWS_PROFILE + value: account_b_role +---- + +When configuring role trust policies for role chaining with EKS pod +identities, you can reference +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html[EKS +specific attributes] as session tags and use attribute based access +control(ABAC) to limit access to your IAM roles to only specific EKS Pod +identity sessions, such as the Kubernetes Service Account a pod belongs +to. + +Please note that some of these attributes may not be universally unique, +for example two EKS clusters may have identical namespaces, and one +cluster may have identically named service accounts across namespaces. +So when granting access via EKS Pod Identities and ABAC, it is a best +practice to always consider the cluster arn and namespace when granting +access to a service account. + +======= ABAC and EKS Pod Identities for cross account access + +When using EKS Pod Identities to assume roles (role chaining) in other +accounts as part of a multi account strategy, you have the option to +assign a unique IAM role for each service account that needs to access +another account, or use a common IAM role across multiple service +accounts and use ABAC to control what accounts it can access. + +To use ABAC to control what service accounts can assume a role into +another account with role chaining, you create a role trust policy +statement that only allows a role to be assumed by a role session when +the expected values are present. The following role trust policy will +only let a role from the EKS cluster account (account ID 111122223333) +assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+` +and `+kubernetes-namespace+` tags all have the expected value. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111122223333:root" + }, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "aws:PrincipalTag/kubernetes-service-account": "PayrollApplication", + "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-east-1:111122223333:cluster/ProductionCluster", + "aws:PrincipalTag/kubernetes-namespace": "PayrollNamespace" + } + } + } + ] +} +---- + +When using this strategy it is a best practice to ensure that the common +IAM role only has `+sts:AssumeRole+` permissions and no other AWS +access. + +It is important when using ABAC that you control who has the ability to +tag IAM roles and users to only those who have a strict need to do so. +Someone with the ability to tag an IAM role or user would be able to set +tags on roles/users identical to what would be set by EKS Pod Identities +and may be able to escalate their privileges. You can restrict who has +the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role +and users using IAM policy, or Service Control Policy (SCP). + +=== De-centralized EKS Clusters + +In this approach, EKS clusters are deployed to respective workload AWS +Accounts and live along side with other AWS resources like Amazon S3 +buckets, VPCs, Amazon DynamoDB tables, etc., Each workload account is +independent, self-sufficient, and operated by respective Business +Unit/Application teams. This model allows the creation of reusuable +blueprints for various cluster capabilities (AI/ML cluster, Batch +processing, General purpose, etc.,) and vend the clusters based on the +application team requirements. Both application and platform teams +operate out of their respective +https://www.weave.works/technologies/gitops/[GitOps] repositories to +manage the deployments to the workload clusters. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks-decentralized.png[De-centralized EKS +Cluster Architecture] +|In the above diagram, Amazon EKS clusters and other AWS resources are +deployed to respective workload accounts. Then workloads running in EKS +pods use IRSA or EKS Pod Identities to access their AWS resources. +|=== + +GitOps is a way of managing application and infrastructure deployment so +that the whole system is described declaratively in a Git repository. +It’s an operational model that offers you the ability to manage the +state of multiple Kubernetes clusters using the best practices of +version control, immutable artifacts, and automation. In this multi +cluster model, each workload cluster is bootstrapped with multiple Git +repos, allowing each team (application, platform, security, etc.,) to +deploy their respective changes on the cluster. + +You would utilize +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts (IRSA)] or +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] in each account to allow your EKS workloads to get +temporary aws credentials to securely access other AWS resources. IAM +roles are created in respective workload AWS Accounts and map them to +k8s service accounts to provide temporary IAM access. So, no +cross-account access is required in this approach. Follow the +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts] documentation on how to setup in each +workload for IRSA, and +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] documentation on how to setup EKS pod identities in each +account. + +==== Centralized Networking + +You can also utilize AWS RAM to share the VPC Subnets to workload +accounts and launch Amazon EKS clusters and other AWS resources in them. +This enables centralized network managment/administration, simplified +network connectivity, and de-centralized EKS clusters. Refer this +https://aws.amazon.com/blogs/containers/use-shared-vpcs-in-amazon-eks/[AWS +blog] for a detailed walkthrough and considerations of this approach. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks-shared-subnets.png[De-centralized EKS +Cluster Architecture using VPC Shared Subnets] +|In the above diagram, AWS RAM is used to share subnets from a central +networking account into a workload account. Then EKS cluster and other +AWS resources are launched in those subnets in respective workload +accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS +resources. +|=== + +=== Centralized vs De-centralized EKS clusters + +The decision to run with a Centralized or De-centralized will depend on +your requirements. This table demonstrates the key differences with each +strategy. + +[width="100%",cols="<34%,<33%,<33%",options="header",] +|=== +|# |Centralized EKS cluster |De-centralized EKS clusters +|Cluster Management: |Managing a single EKS cluster is easier than +administrating multiple clusters |An Efficient cluster management +automation is necessary to reduce the operational overhead of managing +multiple EKS clusters + +|Cost Efficiency: |Allows reuse of EKS cluster and network resources, +which promotes cost efficiency |Requires networking and cluster setups +per workload, which requires additional resources + +|Resilience: |Multiple workloads on the centralized cluster may be +impacted if a cluster becomes impaired |If a cluster becomes impaired, +the damage is limited to only the workloads that run on that cluster. +All other workloads are unaffected + +|Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using +k8s native constructs like `+Namespaces+`. Workloads may share the +underlying resources like CPU, memory, etc. AWS resources are isolated +into their own workload accounts which by default are not accessible +from other AWS accounts. |Stronger isolation on compute resources as the +workloads run in individual clusters and nodes that don’t share any +resources. AWS resources are isolated into their own workload accounts +which by default are not accessible from other AWS accounts. + +|Performance & Scalabity: |As workloads grow to very large scales you +may encounter kubernetes and AWS service quotas in the cluster account. +You can deploy addtional cluster accounts to scale even further |As more +clusters and VPCs are present, each workload has more available k8s and +AWS service quota + +|Networking: |Single VPC is used per cluster, allowing for simpler +connectivity for applications on that cluster |Routing must be +established between the de-centralized EKS cluster VPCs + +|Kubernetes Access Management: |Need to maintain many different roles +and users in the cluster to provide access to all workload teams and +ensure kubernetes resources are properly segregated |Simplified access +management as each cluster is dedicated to a workload/team + +|AWS Access Management: |AWS resources are deployed into to their own +account which can only be accessed by default with IAM roles in the +workload account. IAM roles in the workload accounts are assumed cross +account either with IRSA or EKS Pod Identities. |AWS resources are +deployed into to their own account which can only be accessed by default +with IAM roles in the workload account. IAM roles in the workload +accounts are delivered directly to pods with IRSA or EKS Pod Identities +|=== diff --git a/latest/bpg/security/multitenancy.adoc b/latest/bpg/security/multitenancy.adoc new file mode 100644 index 000000000..30820dea0 --- /dev/null +++ b/latest/bpg/security/multitenancy.adoc @@ -0,0 +1,630 @@ +== Tenant Isolation + +When we think of multi-tenancy, we often want to isolate a user or +application from other users or applications running on a shared +infrastructure. + +Kubernetes is a _single tenant orchestrator_, i.e. a single instance of +the control plane is shared among all the tenants within a cluster. +There are, however, various Kubernetes objects that you can use to +create the semblance of multi-tenancy. For example, Namespaces and +Role-based access controls (RBAC) can be implemented to logically +isolate tenants from each other. Similarly, Quotas and Limit Ranges can +be used to control the amount of cluster resources each tenant can +consume. Nevertheless, the cluster is the only construct that provides a +strong security boundary. This is because an attacker that manages to +gain access to a host within the cluster can retrieve _all_ Secrets, +ConfigMaps, and Volumes, mounted on that host. They could also +impersonate the Kubelet which would allow them to manipulate the +attributes of the node and/or move laterally within the cluster. + +The following sections will explain how to implement tenant isolation +while mitigating the risks of using a single tenant orchestrator like +Kubernetes. + +=== Soft multi-tenancy + +With soft multi-tenancy, you use native Kubernetes constructs, +e.g. namespaces, roles and role bindings, and network policies, to +create logical separation between tenants. RBAC, for example, can +prevent tenants from accessing or manipulate each other’s resources. +Quotas and limit ranges control the amount of cluster resources each +tenant can consume while network policies can help prevent applications +deployed into different namespaces from communicating with each other. + +None of these controls, however, prevent pods from different tenants +from sharing a node. If stronger isolation is required, you can use a +node selector, anti-affinity rules, and/or taints and tolerations to +force pods from different tenants to be scheduled onto separate nodes; +often referred to as _sole tenant nodes_. This could get rather +complicated, and cost prohibitive, in an environment with many tenants. + +!!! attention Soft multi-tenancy implemented with Namespaces does not +allow you to provide tenants with a filtered list of Namespaces because +Namespaces are a globally scoped Type. If a tenant has the ability to +view a particular Namespace, it can view all Namespaces within the +cluster. + +!!! warning With soft-multi-tenancy, tenants retain the ability to query +CoreDNS for all services that run within the cluster by default. An +attacker could exploit this by running dig SRV `+*.*.svc.cluster.local+` +from any pod in the cluster. If you need to restrict access to DNS +records of services that run within your clusters, consider using the +Firewall or Policy plugins for CoreDNS. For additional information, see +https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy. + +https://github.com/kiosk-sh/kiosk[Kiosk] is an open source project that +can aid in the implementation of soft multi-tenancy. It is implemented +as a series of CRDs and controllers that provide the following +capabilities: + +* *Accounts & Account Users* to separate tenants in a shared Kubernetes +cluster +* *Self-Service Namespace Provisioning* for account users +* *Account Limits* to ensure quality of service and fairness when +sharing a cluster +* *Namespace Templates* for secure tenant isolation and self-service +namespace initialization + +https://loft.sh[Loft] is a commercial offering from the maintainers of +Kiosk and https://github.com/devspace-cloud/devspace[DevSpace] that adds +the following capabilities: + +* *Multi-cluster access* for granting access to spaces in different +clusters +* *Sleep mode* scales down deployments in a space during periods of +inactivity +* *Single sign-on* with OIDC authentication providers like GitHub + +There are three primary use cases that can be addressed by soft +multi-tenancy. + +==== Enterprise Setting + +The first is in an Enterprise setting where the "`tenants`" are +semi-trusted in that they are employees, contractors, or are otherwise +authorized by the organization. Each tenant will typically align to an +administrative division such as a department or team. + +In this type of setting, a cluster administrator will usually be +responsible for creating namespaces and managing policies. They may also +implement a delegated administration model where certain individuals are +given oversight of a namespace, allowing them to perform CRUD operations +for non-policy related objects like deployments, services, pods, jobs, +etc. + +The isolation provided by a container runtime may be acceptable within +this setting or it may need to be augmented with additional controls for +pod security. It may also be necessary to restrict communication between +services in different namespaces if stricter isolation is required. + +==== Kubernetes as a Service + +By contrast, soft multi-tenancy can be used in settings where you want +to offer Kubernetes as a service (KaaS). With KaaS, your application is +hosted in a shared cluster along with a collection of controllers and +CRDs that provide a set of PaaS services. Tenants interact directly with +the Kubernetes API server and are permitted to perform CRUD operations +on non-policy objects. There is also an element of self-service in that +tenants may be allowed to create and manage their own namespaces. In +this type of environment, tenants are assumed to be running untrusted +code. + +To isolate tenants in this type of environment, you will likely need to +implement strict network policies as well as _pod sandboxing_. +Sandboxing is where you run the containers of a pod inside a micro VM +like Firecracker or in a user-space kernel. Today, you can create +sandboxed pods with EKS Fargate. + +==== Software as a Service (SaaS) + +The final use case for soft multi-tenancy is in a Software-as-a-Service +(SaaS) setting. In this environment, each tenant is associated with a +particular _instance_ of an application that’s running within the +cluster. Each instance often has its own data and uses separate access +controls that are usually independent of Kubernetes RBAC. + +Unlike the other use cases, the tenant in a SaaS setting does not +directly interface with the Kubernetes API. Instead, the SaaS +application is responsible for interfacing with the Kubernetes API to +create the necessary objects to support each tenant. + +=== Kubernetes Constructs + +In each of these instances the following constructs are used to isolate +tenants from each other: + +==== Namespaces + +Namespaces are fundamental to implementing soft multi-tenancy. They +allow you to divide the cluster into logical partitions. Quotas, network +policies, service accounts, and other objects needed to implement +multi-tenancy are scoped to a namespace. + +==== Network policies + +By default, all pods in a Kubernetes cluster are allowed to communicate +with each other. This behavior can be altered using network policies. + +Network policies restrict communication between pods using labels or IP +address ranges. In a multi-tenant environment where strict network +isolation between tenants is required, we recommend starting with a +default rule that denies communication between pods, and another rule +that allows all pods to query the DNS server for name resolution. With +that in place, you can begin adding more permissive rules that allow for +communication within a namespace. This can be further refined as +required. + +!!! note Amazon +https://aws.amazon.com/blogs/containers/amazon-vpc-cni-now-supports-kubernetes-network-policies/[VPC +CNI now supports Kubernetes Network Policies] to create policies that +can isolate sensitive workloads and protect them from unauthorized +access when running Kubernetes on AWS. This means that you can use all +the capabilities of the Network Policy API within your Amazon EKS +cluster. This level of granular control enables you to implement the +principle of least privilege, which ensures that only authorized pods +are allowed to communicate with each other. + +!!! attention Network policies are necessary but not sufficient. The +enforcement of network policies requires a policy engine such as Calico +or Cilium. + +==== Role-based access control (RBAC) + +Roles and role bindings are the Kubernetes objects used to enforce +role-based access control (RBAC) in Kubernetes. *Roles* contain lists of +actions that can be performed against objects in your cluster. *Role +bindings* specify the individuals or groups to whom the roles apply. In +the enterprise and KaaS settings, RBAC can be used to permit +administration of objects by selected groups or individuals. + +==== Quotas + +Quotas are used to define limits on workloads hosted in your cluster. +With quotas, you can specify the maximum amount of CPU and memory that a +pod can consume, or you can limit the number of resources that can be +allocated in a cluster or namespace. *Limit ranges* allow you to declare +minimum, maximum, and default values for each limit. + +Overcommitting resources in a shared cluster is often beneficial because +it allows you maximize your resources. However, unbounded access to a +cluster can cause resource starvation, which can lead to performance +degradation and loss of application availability. If a pod’s requests +are set too low and the actual resource utilization exceeds the capacity +of the node, the node will begin to experience CPU or memory pressure. +When this happens, pods may be restarted and/or evicted from the node. + +To prevent this from happening, you should plan to impose quotas on +namespaces in a multi-tenant environment to force tenants to specify +requests and limits when scheduling their pods on the cluster. It will +also mitigate a potential denial of service by constraining the amount +of resources a pod can consume. + +You can also use quotas to apportion the cluster’s resources to align +with a tenant’s spend. This is particularly useful in the KaaS scenario. + +==== Pod priority and preemption + +Pod priority and preemption can be useful when you want to provide more +importance to a Pod relative to other Pods. For example, with pod +priority you can configure pods from customer A to run at a higher +priority than customer B. When there’s insufficient capacity available, +the scheduler will evict the lower-priority pods from customer B to +accommodate the higher-priority pods from customer A. This can be +especially handy in a SaaS environment where customers willing to pay a +premium receive a higher priority. + +!!! attention Pods priority can have an undesired effect on other Pods +with lower priority. For example, although the victim pods are +terminated gracefully but the PodDisruptionBudget is not guaranteed, +which could break a application with lower priority that relies on a +quorum of Pods, see +https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#limitations-of-preemption[Limitations +of preemption]. + +=== Mitigating controls + +Your chief concern as an administrator of a multi-tenant environment is +preventing an attacker from gaining access to the underlying host. The +following controls should be considered to mitigate this risk: + +==== Sandboxed execution environments for containers + +Sandboxing is a technique by which each container is run in its own +isolated virtual machine. Technologies that perform pod sandboxing +include https://firecracker-microvm.github.io/[Firecracker] and Weave’s +https://www.weave.works/blog/firekube-fast-and-secure-kubernetes-clusters-using-weave-ignite[Firekube]. + +For additional information about the effort to make Firecracker a +supported runtime for EKS, see +https://threadreaderapp.com/thread/1238496944684597248.html. + +==== Open Policy Agent (OPA) & Gatekeeper + +https://github.com/open-policy-agent/gatekeeper[Gatekeeper] is a +Kubernetes admission controller that enforces policies created with +https://www.openpolicyagent.org/[OPA]. With OPA you can create a policy +that runs pods from tenants on separate instances or at a higher +priority than other tenants. A collection of common OPA policies can be +found in the GitHub +https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository] +for this project. + +There is also an experimental https://github.com/coredns/coredns-opa[OPA +plugin for CoreDNS] that allows you to use OPA to filter/control the +records returned by CoreDNS. + +==== Kyverno + +https://kyverno.io[Kyverno] is a Kubernetes native policy engine that +can validate, mutate, and generate configurations with policies as +Kubernetes resources. Kyverno uses Kustomize-style overlays for +validation, supports JSON Patch and strategic merge patch for mutation, +and can clone resources across namespaces based on flexible triggers. + +You can use Kyverno to isolate namespaces, enforce pod security and +other best practices, and generate default configurations such as +network policies. Several examples are included in the GitHub +https://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno[repository] +for this project. Many others are included in the +https://kyverno.io/policies/[policy library] on the Kyverno website. + +==== Isolating tenant workloads to specific nodes + +Restricting tenant workloads to run on specific nodes can be used to +increase isolation in the soft multi-tenancy model. With this approach, +tenant-specific workloads are only run on nodes provisioned for the +respective tenants. To achieve this isolation, native Kubernetes +properties (node affinity, and taints and tolerations) are used to +target specific nodes for pod scheduling, and prevent pods, from other +tenants, from being scheduled on the tenant-specific nodes. + +===== Part 1 - Node affinity + +Kubernetes +https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity[node +affinity] is used to target nodes for scheduling, based on node +https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/[labels]. +With node affinity rules, the pods are attracted to specific nodes that +match the selector terms. In the below pod specification, the +`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity is +applied to the respective pod. The result is that the pod will target +nodes that are labeled with the following key/value: +`+node-restriction.kubernetes.io/tenant: tenants-x+`. + +[source,yaml] +---- +... +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-restriction.kubernetes.io/tenant + operator: In + values: + - tenants-x +... +---- + +With this node affinity, the label is required during scheduling, but +not during execution; if the underlying nodes’ labels change, the pods +will not be evicted due solely to that label change. However, future +scheduling could be impacted. + +!!! Warning The label prefix of `+node-restriction.kubernetes.io/+` has +special meaning in Kubernetes. +https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[NodeRestriction] +which is enabled for EKS clusters prevents `+kubelet+` from +adding/removing/updating labels with this prefix. Attackers aren’t able +to use the `+kubelet+`’s credentials to update the node object or modify +the system setup to pass these labels into `+kubelet+` as `+kubelet+` +isn’t allowed to modify these labels. If this prefix is used for all pod +to node scheduling, it prevents scenarios where an attacker may want to +attract a different set of workloads to a node by modifying the node +labels. + +!!! Info Instead of node affinity, we could have used the +https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector[node +selector]. However, node affinity is more expressive and allows for more +conditions to be considered during pod scheduling. For additional +information about the differences and more advanced scheduling choices, +please see this CNCF blog post on +https://www.cncf.io/blog/2021/07/27/advanced-kubernetes-pod-to-node-scheduling/[Advanced +Kubernetes pod to node scheduling]. + +===== Part 2 - Taints and tolerations + +Attracting pods to nodes is just the first part of this three-part +approach. For this approach to work, we must repel pods from scheduling +onto nodes for which the pods are not authorized. To repel unwanted or +unauthorized pods, Kubernetes uses node +https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[taints]. +Taints are used to place conditions on nodes that prevent pods from +being scheduled. The below taint uses a key-value pair of +`+tenant: tenants-x+`. + +[source,yaml] +---- +... + taints: + - key: tenant + value: tenants-x + effect: NoSchedule +... +---- + +Given the above node `+taint+`, only pods that _tolerate_ the taint will +be allowed to be scheduled on the node. To allow authorized pods to be +scheduled onto the node, the respective pod specifications must include +a `+toleration+` to the taint, as seen below. + +[source,yaml] +---- +... + tolerations: + - effect: NoSchedule + key: tenant + operator: Equal + value: tenants-x +... +---- + +Pods with the above `+toleration+` will not be stopped from scheduling +on the node, at least not because of that specific taint. Taints are +also used by Kubernetes to temporarily stop pod scheduling during +certain conditions, like node resource pressure. With node affinity, and +taints and tolerations, we can effectively attract the desired pods to +specific nodes and repel unwanted pods. + +!!! attention Certain Kubernetes pods are required to run on all nodes. +Examples of these pods are those started by the +https://github.com/containernetworking/cni[Container Network Interface +(CNI)] and +https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/[kube-proxy] +https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[daemonsets]. +To that end, the specifications for these pods contain very permissive +tolerations, to tolerate different taints. Care should be taken to not +change these tolerations. Changing these tolerations could result in +incorrect cluster operation. Additionally, policy-management tools, such +as https://github.com/open-policy-agent/gatekeeper[OPA/Gatekeeper] and +https://kyverno.io/[Kyverno] can be used to write validating policies +that prevent unauthorized pods from using these permissive tolerations. + +===== Part 3 - Policy-based management for node selection + +There are several tools that can be used to help manage the node +affinity and tolerations of pod specifications, including enforcement of +rules in CICD pipelines. However, enforcement of isolation should also +be done at the Kubernetes cluster level. For this purpose, +policy-management tools can be used to _mutate_ inbound Kubernetes API +server requests, based on request payloads, to apply the respective node +affinity rules and tolerations mentioned above. + +For example, pods destined for the _tenants-x_ namespace can be +_stamped_ with the correct node affinity and toleration to permit +scheduling on the _tenants-x_ nodes. Utilizing policy-management tools +configured using the Kubernetes +https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook[Mutating +Admission Webhook], policies can be used to mutate the inbound pod +specifications. The mutations add the needed elements to allow desired +scheduling. An example OPA/Gatekeeper policy that adds a node affinity +is seen below. + +[source,yaml] +---- +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: Assign +metadata: + name: mutator-add-nodeaffinity-pod + annotations: + aws-eks-best-practices/description: >- + Adds Node affinity - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +spec: + applyTo: + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + match: + namespaces: ["tenants-x"] + location: "spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms" + parameters: + assign: + value: + - matchExpressions: + - key: "tenant" + operator: In + values: + - "tenants-x" +---- + +The above policy is applied to a Kubernetes API server request, to apply +a pod to the _tenants-x_ namespace. The policy adds the +`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity rule, +so that pods are attracted to nodes with the `+tenant: tenants-x+` +label. + +A second policy, seen below, adds the toleration to the same pod +specification, using the same matching criteria of target namespace and +groups, kinds, and versions. + +[source,yaml] +---- +apiVersion: mutations.gatekeeper.sh/v1alpha1 +kind: Assign +metadata: + name: mutator-add-toleration-pod + annotations: + aws-eks-best-practices/description: >- + Adds toleration - https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ +spec: + applyTo: + - groups: [""] + kinds: ["Pod"] + versions: ["v1"] + match: + namespaces: ["tenants-x"] + location: "spec.tolerations" + parameters: + assign: + value: + - key: "tenant" + operator: "Equal" + value: "tenants-x" + effect: "NoSchedule" +---- + +The above policies are specific to pods; this is due to the paths to the +mutated elements in the policies’ `+location+` elements. Additional +policies could be written to handle resources that create pods, like +Deployment and Job resources. The listed policies and other examples can +been seen in the companion +https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa/gatekeeper/node-selector[GitHub +project] for this guide. + +The result of these two mutations is that pods are attracted to the +desired node, while at the same time, not repelled by the specific node +taint. To verify this, we can see the snippets of output from two +`+kubectl+` calls to get the nodes labeled with `+tenant=tenants-x+`, +and get the pods in the `+tenants-x+` namespace. + +[source,bash] +---- +kubectl get nodes -l tenant=tenants-x +NAME +ip-10-0-11-255... +ip-10-0-28-81... +ip-10-0-43-107... + +kubectl -n tenants-x get pods -owide +NAME READY STATUS RESTARTS AGE IP NODE +tenant-test-deploy-58b895ff87-2q7xw 1/1 Running 0 13s 10.0.42.143 ip-10-0-43-107... +tenant-test-deploy-58b895ff87-9b6hg 1/1 Running 0 13s 10.0.18.145 ip-10-0-28-81... +tenant-test-deploy-58b895ff87-nxvw5 1/1 Running 0 13s 10.0.30.117 ip-10-0-28-81... +tenant-test-deploy-58b895ff87-vw796 1/1 Running 0 13s 10.0.3.113 ip-10-0-11-255... +tenant-test-pod 1/1 Running 0 13s 10.0.35.83 ip-10-0-43-107... +---- + +As we can see from the above outputs, all the pods are scheduled on the +nodes labeled with `+tenant=tenants-x+`. Simply put, the pods will only +run on the desired nodes, and the other pods (without the required +affinity and tolerations) will not. The tenant workloads are effectively +isolated. + +An example mutated pod specification is seen below. + +[source,yaml] +---- +apiVersion: v1 +kind: Pod +metadata: + name: tenant-test-pod + namespace: tenants-x +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: tenant + operator: In + values: + - tenants-x +... + tolerations: + - effect: NoSchedule + key: tenant + operator: Equal + value: tenants-x +... +---- + +!!! attention Policy-management tools that are integrated to the +Kubernetes API server request flow, using mutating and validating +admission webhooks, are designed to respond to the API server’s request +within a specified timeframe. This is usually 3 seconds or less. If the +webhook call fails to return a response within the configured time, the +mutation and/or validation of the inbound API sever request may or may +not occur. This behavior is based on whether the admission webhook +configurations are set to +https://open-policy-agent.github.io/gatekeeper/website/docs/#admission-webhook-fail-open-by-default[Fail +Open or Fail Close]. + +In the above examples, we used policies written for OPA/Gatekeeper. +However, there are other policy management tools that handle our +node-selection use case as well. For example, this +https://kyverno.io/policies/other/add_node_affinity/add_node_affinity/[Kyverno +policy] could be used to handle the node affinity mutation. + +!!! tip If operating correctly, mutating policies will effect the +desired changes to inbound API server request payloads. However, +validating policies should also be included to verify that the desired +changes occur, before changes are allowed to persist. This is especially +important when using these policies for tenant-to-node isolation. It is +also a good idea to include _Audit_ policies to routinely check your +cluster for unwanted configurations. + +==== References + +* https://github.com/cruise-automation/k-rail[k-rail] Designed to help +you secure a multi-tenant environment through the enforcement of certain +policies. +* https://d1.awsstatic.com/whitepapers/security-practices-for-multi-tenant-saas-apps-using-eks.pdf[Security +Practices for MultiTenant SaaS Applications using Amazon EKS] + +=== Hard multi-tenancy + +Hard multi-tenancy can be implemented by provisioning separate clusters +for each tenant. While this provides very strong isolation between +tenants, it has several drawbacks. + +First, when you have many tenants, this approach can quickly become +expensive. Not only will you have to pay for the control plane costs for +each cluster, you will not be able to share compute resources between +clusters. This will eventually cause fragmentation where a subset of +your clusters are underutilized while others are overutilized. + +Second, you will likely need to buy or build special tooling to manage +all of these clusters. In time, managing hundreds or thousands of +clusters may simply become too unwieldy. + +Finally, creating a cluster per tenant will be slow relative to a +creating a namespace. Nevertheless, a hard-tenancy approach may be +necessary in highly-regulated industries or in SaaS environments where +strong isolation is required. + +=== Future directions + +The Kubernetes community has recognized the current shortcomings of soft +multi-tenancy and the challenges with hard multi-tenancy. The +https://github.com/kubernetes-sigs/multi-tenancy[Multi-Tenancy Special +Interest Group (SIG)] is attempting to address these shortcomings +through several incubation projects, including Hierarchical Namespace +Controller (HNC) and Virtual Cluster. + +The HNC proposal (KEP) describes a way to create parent-child +relationships between namespaces with [policy] object inheritance along +with an ability for tenant administrators to create sub-namespaces. + +The Virtual Cluster proposal describes a mechanism for creating separate +instances of the control plane services, including the API server, the +controller manager, and scheduler, for each tenant within the cluster +(also known as "`Kubernetes on Kubernetes`"). + +The +https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/README.md[Multi-Tenancy +Benchmarks] proposal provides guidelines for sharing clusters using +namespaces for isolation and segmentation, and a command line tool +https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/kubectl-mtb/README.md[kubectl-mtb] +to validate conformance to the guidelines. + +=== Multi-cluster management tools and resources + +* https://banzaicloud.com/[Banzai Cloud] +* https://d2iq.com/solutions/ksphere/kommander[Kommander] +* https://github.com/lensapp/lens[Lens] +* https://nirmata.com[Nirmata] +* https://rafay.co/[Rafay] +* https://rancher.com/products/rancher/[Rancher] +* https://www.weave.works/oss/flux/[Weave Flux] diff --git a/latest/bpg/security/network.adoc b/latest/bpg/security/network.adoc new file mode 100644 index 000000000..c5a0b1079 --- /dev/null +++ b/latest/bpg/security/network.adoc @@ -0,0 +1,971 @@ +== Network security + +Network security has several facets. The first involves the application +of rules which restrict the flow of network traffic between services. +The second involves the encryption of traffic while it is in transit. +The mechanisms to implement these security measures on EKS are varied +but often include the following items: + +=== Traffic control + +* Network Policies +* Security Groups + +=== Network encryption + +* Service Mesh +* Container Network Interfaces (CNIs) +* Ingress Controllers and Load Balancers +* Nitro Instances +* ACM Private CA with cert-manager + +=== Network policy + +Within a Kubernetes cluster, all Pod to Pod communication is allowed by +default. While this flexibility may help promote experimentation, it is +not considered secure. Kubernetes network policies give you a mechanism +to restrict network traffic between Pods (often referred to as East/West +traffic) as well as between Pods and external services. Kubernetes +network policies operate at layers 3 and 4 of the OSI model. Network +policies use pod, namespace selectors and labels to identify source and +destination pods, but can also include IP addresses, port numbers, +protocols, or a combination of these. Network Policies can be applied to +both Inbound or Outbound connections to the pod, often called Ingress +and Egress rules. + +With native network policy support of Amazon VPC CNI Plugin, you can +implement network policies to secure network traffic in kubernetes +clusters. This integrates with the upstream Kubernetes Network Policy +API, ensuring compatibility and adherence to Kubernetes standards. You +can define policies using different +https://kubernetes.io/docs/concepts/services-networking/network-policies/[identifiers] +supported by the upstream API. By default, all ingress and egress +traffic is allowed to a pod. When a network policy with a policyType +Ingress is specified, only allowed connections into the pod are those +from the pod’s node and those allowed by the ingress rules. Same applies +for egress rules. If multiple rules are defined, then union of all rules +are taken into account when making the decision. Thus, order of +evaluation does not affect the policy result. + +!!! attention When you first provision an EKS cluster, VPC CNI Network +Policy functionality is not enabled by default. Ensure you deployed +supported VPC CNI Add-on version and set `+ENABLE_NETWORK_POLICY+` flag +to `+true+` on the vpc-cni add-on to enable this. Refer +https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html[Amazon +EKS User guide] for detailed instructions. + +=== Recommendations + +==== Getting Started with Network Policies - Follow Principle of Least Privilege + +===== Create a default deny policy + +As with RBAC policies, it is recommended to follow least privileged +access principles with network policies. Start by creating a deny all +policy that restricts all inbound and outbound traffic with in a +namespace. + +[source,yaml] +---- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny + namespace: default +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +---- + +.default-deny +image::./images/default-deny.jpg[default-deny] + +!!! tip The image above was created by the network policy viewer from +https://orca.tufin.io/netpol/[Tufin]. + +===== Create a rule to allow DNS queries + +Once you have the default deny all rule in place, you can begin layering +on additional rules, such as a rule that allows pods to query CoreDNS +for name resolution. + +[source,yaml] +---- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-dns-access + namespace: default +spec: + podSelector: + matchLabels: {} + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - protocol: UDP + port: 53 +---- + +.allow-dns-access +image::./images/allow-dns-access.jpg[allow-dns-access] + +===== Incrementally add rules to selectively allow the flow of traffic between namespaces/pods + +Understand the application requirements and create fine-grained ingress +and egress rules as needed. Below example shows how to restrict ingress +traffic on port 80 to `+app-one+` from `+client-one+`. This helps +minimize the attack surface and reduces the risk of unauthorized access. + +[source,yaml] +---- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-ingress-app-one + namespace: default +spec: + podSelector: + matchLabels: + k8s-app: app-one + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + k8s-app: client-one + ports: + - protocol: TCP + port: 80 +---- + +.allow-ingress-app-one +image::./images/allow-ingress-app-one.png[allow-ingress-app-one] + +==== Monitoring network policy enforcement + +* *Use Network Policy editor* +** https://networkpolicy.io/[Network policy editor] helps with +visualizations, security score, autogenerates from network flow logs +** Build network policies in an interactive way +* *Audit Logs* +** Regularly review audit logs of your EKS cluster +** Audit logs provide wealth of information about what actions have been +performed on your cluster including changes to network policies +** Use this information to track changes to your network policies over +time and detect any unauthorized or unexpected changes +* *Automated testing* +** Implement automated testing by creating a test environment that +mirrors your production environment and periodically deploy workloads +that attempt to violate your network policies. +* *Monitoring metrics* +** Configure your observability agents to scrape the prometheus metrics +from the VPC CNI node agents, that allows to monitor the agent health, +and sdk errors. +* *Audit Network Policies regularly* +** Periodically audit your Network Policies to make sure that they meet +your current application requirements. As your application evolves, an +audit gives you the opportunity to remove redundant ingress, egress +rules and make sure that your applications don’t have excessive +permissions. +* *Ensure Network Policies exists using Open Policy Agent (OPA)* +** Use OPA Policy like shown below to ensure Network Policy always +exists before onboarding application pods. This policy denies onboarding +k8s pods with a label `+k8s-app: sample-app+` if corresponding network +policy does not exist. + +[source,javascript] +---- +package kubernetes.admission +import data.kubernetes.networkpolicies + +deny[msg] { + input.request.kind.kind == "Pod" + pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels} + contains_label(pod_label_value, "sample-app") + np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels} + not contains_label(np_label_value, "sample-app") + msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name]) +} +contains_label(arr, val) { + arr[_] == val +} +---- + +==== Troubleshooting + +===== Monitor the vpc-network-policy-controller, node-agent logs + +Enable the EKS Control plane controller manager logs to diagnose the +network policy functionality. You can stream the control plane logs to a +CloudWatch log group and use +https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html[CloudWatch +Log insights] to perform advanced queries. From the logs, you can view +what pod endpoint objects are resolved to a Network Policy, +reconcilation status of the policies, and debug if the policy is working +as expected. + +In addition, Amazon VPC CNI allows you to enable the collection and +export of policy enforcement logs to +https://aws.amazon.com/cloudwatch/[Amazon Cloudwatch] from the EKS +worker nodes. Once enabled, you can leverage +https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html[CloudWatch +Container Insights] to provide insights on your usage related to Network +Policies. + +Amazon VPC CNI also ships an SDK that provides an interface to interact +with eBPF programs on the node. The SDK is installed when the +`+aws-node+` is deployed onto the nodes. You can find the SDK binary +installed under `+/opt/cni/bin+` directory on the node. At launch, the +SDK provides support for fundamental functionalities such as inspecting +eBPF programs and maps. + +[source,shell] +---- +sudo /opt/cni/bin/aws-eks-na-cli ebpf progs +---- + +===== Log network traffic metadata + +https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html[AWS VPC +Flow Logs] captures metadata about the traffic flowing through a VPC, +such as source and destination IP address and port along with +accepted/dropped packets. This information could be analyzed to look for +suspicious or unusual activity between resources within the VPC, +including Pods. However, since the IP addresses of pods frequently +change as they are replaced, Flow Logs may not be sufficient on its own. +Calico Enterprise extends the Flow Logs with pod labels and other +metadata, making it easier to decipher the traffic flows between pods. + +=== Security groups + +EKS uses +https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS +VPC Security Groups] (SGs) to control the traffic between the Kubernetes +control plane and the cluster’s worker nodes. Security groups are also +used to control the traffic between worker nodes, and other VPC +resources, and external IP addresses. When you provision an EKS cluster +(with Kubernetes version 1.14-eks.3 or greater), a cluster security +group is automatically created for you. This security group allows +unfettered communication between the EKS control plane and the nodes +from managed node groups. For simplicity, it is recommended that you add +the cluster SG to all node groups, including unmanaged node groups. + +Prior to Kubernetes version 1.14 and EKS version eks.3, there were +separate security groups configured for the EKS control plane and node +groups. The minimum and suggested rules for the control plane and node +group security groups can be found at +https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html. +The minimum rules for the _control plane security group_ allows port 443 +inbound from the worker node SG. This rule is what allows the kubelets +to communicate with the Kubernetes API server. It also includes port +10250 for outbound traffic to the worker node SG; 10250 is the port that +the kubelets listen on. Similarly, the minimum _node group_ rules allow +port 10250 inbound from the control plane SG and 443 outbound to the +control plane SG. Finally there is a rule that allows unfettered +communication between nodes within a node group. + +If you need to control communication between services that run within +the cluster and service the run outside the cluster such as an RDS +database, consider +https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html[security +groups for pods]. With security groups for pods, you can assign an +*existing* security group to a collection of pods. + +!!! warning If you reference a security group that does not exist prior +to the creation of the pods, the pods will not get scheduled. + +You can control which pods are assigned to a security group by creating +a `+SecurityGroupPolicy+` object and specifying a `+PodSelector+` or a +`+ServiceAccountSelector+`. Setting the selectors to `+{}+` will assign +the SGs referenced in the `+SecurityGroupPolicy+` to all pods in a +namespace or all Service Accounts in a namespace. Be sure you’ve +familiarized yourself with all the +https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations[considerations] +before implementing security groups for pods. + +!!! important If you use SGs for pods you *must* create SGs that allow +port 53 outbound to the cluster security group. Similarly, you *must* +update the cluster security group to accept port 53 inbound traffic from +the pod security group. + +!!! important The +https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups[limits +for security groups] still apply when using security groups for pods so +use them judiciously. + +!!! important You *must* create rules for inbound traffic from the +cluster security group (kubelet) for all of the probes configured for +pod. + +!!! important Security groups for pods relies on a feature known as +https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html[ENI +trunking] which was created to increase the ENI density of an EC2 +instance. When a pod is assigned to an SG, a VPC controller associates a +branch ENI from the node group with the pod. If there aren’t enough +branch ENIs available in a node group at the time the pod is scheduled, +the pod will stay in pending state. The number of branch ENIs an +instance can support varies by instance type/family. See +https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types +for further details. + +While security groups for pods offers an AWS-native way to control +network traffic within and outside of your cluster without the overhead +of a policy daemon, other options are available. For example, the Cilium +policy engine allows you to reference a DNS name in a network policy. +Calico Enterprise includes an option for mapping network policies to AWS +security groups. If you’ve implemented a service mesh like Istio, you +can use an egress gateway to restrict network egress to specific, fully +qualified domains or IP addresses. For further information about this +option, read the three part series on +https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/[egress +traffic control in Istio]. + +=== When to use Network Policy vs Security Group for Pods? + +==== When to use Kubernetes network policy + +* *Controlling pod-to-pod traffic* +** Suitable for controlling network traffic between pods inside a +cluster (east-west traffic) +* *Control traffic at the IP address or port level (OSI layer 3 or 4)* + +==== When to use AWS Security groups for pods (SGP) + +* *Leverage existing AWS configurations* +** If you already have complex set of EC2 security groups that manage +access to AWS services and you are migrating applications from EC2 +instances to EKS, SGPs can be a very good choice allowing you to reuse +security group resources and apply them to your pods. +* *Control access to AWS services* +** Your applications running within an EKS cluster wants to communicate +with other AWS services (RDS database), use SGPs as an efficient +mechanism to control the traffic from the pods to AWS services. +* *Isolation of Pod & Node traffic* +** If you want to completely separate pod traffic from the rest of the +node traffic, use SGP in `+POD_SECURITY_GROUP_ENFORCING_MODE=strict+` +mode. + +==== Best practices using `+Security groups for pods+` and `+Network Policy+` + +* *Layered security* +** Use a combination of SGP and kubernetes network policy for a layered +security approach +** Use SGPs to limit network level access to AWS services that are not +part of a cluster, while kubernetes network policies can restrict +network traffic between pods inside the cluster +* *Principle of least privilege* +** Only allow necessary traffic between pods or namespaces +* *Segment your applications* +** Wherever possible, segment applications by the network policy to +reduce the blast radius if an application is compromised +* *Keep policies simple and clear* +** Kubernetes network policies can be quite granular and complex, its +best to keep them as simple as possible to reduce the risk of +misconfiguration and ease the management overhead +* *Reduce the attack surface* +** Minimize the attack surface by limiting the exposure of your +applications + +!!! attention Security Groups for pods provides two enforcing modes: +`+strict+` and `+standard+`. You must use `+standard+` mode when using +both Network Policy and Security Groups for pods features in an EKS +cluster. + +When it comes to network security, a layered approach is often the most +effective solution. Using kubernetes network policy and SGP in +combination can provide a robust defense-in-depth strategy for your +applications running in EKS. + +=== Service Mesh Policy Enforcement or Kubernetes network policy + +A `+service mesh+` is a dedicated infrastructure layer that you can add +to your applications. It allows you to transparently add capabilities +like observability, traffic management, and security, without adding +them to your own code. + +Service mesh enforces policies at Layer 7 (application) of OSI model +whereas kubernetes network policies operate at Layer 3 (network) and +Layer 4 (transport). There are many offerings in this space like AWS +AppMesh, Istio, Linkerd, etc., + +==== When to use Service mesh for policy enforcement + +* Have existing investment in a service mesh +* Need more advanced capabilities like traffic management, observability +& security +** Traffic control, load balancing, circuit breaking, rate limiting, +timeouts etc. +** Detailed insights into how your services are performing (latency, +error rates, requests per second, request volumes etc.) +** You want to implement and leverage service mesh for security features +like mTLS + +==== Choose Kubernetes network policy for simpler use cases + +* Limit which pods can communicate with each other +* Network policies require fewer resources than a service mesh making +them a good fit for simpler use cases or for smaller clusters where the +overhead of running and managing a service mesh might not be justified + +!!! tip Network policies and Service mesh can also be used together. Use +network policies to provide a baseline level of security and isolation +between your pods and then use a service mesh to add additional +capabilities like traffic management, observability and security. + +=== ThirdParty Network Policy Engines + +Consider a Third Party Network Policy Engine when you have advanced +policy requirements like Global Network Policies, support for DNS +Hostname based rules, Layer 7 rules, ServiceAccount based rules, and +explicit deny/log actions, etc., +https://docs.projectcalico.org/introduction/[Calico], is an open source +policy engine from https://tigera.io[Tigera] that works well with EKS. +In addition to implementing the full set of Kubernetes network policy +features, Calico supports extended network polices with a richer set of +features, including support for layer 7 rules, e.g. HTTP, when +integrated with Istio. Calico policies can be scoped to Namespaces, +Pods, service accounts, or globally. When policies are scoped to a +service account, it associates a set of ingress/egress rules with that +service account. With the proper RBAC rules in place, you can prevent +teams from overriding these rules, allowing IT security professionals to +safely delegate administration of namespaces. Isovalent, the maintainers +of https://cilium.readthedocs.io/en/stable/intro/[Cilium], have also +extended the network policies to include partial support for layer 7 +rules, e.g. HTTP. Cilium also has support for DNS hostnames which can be +useful for restricting traffic between Kubernetes Services/Pods and +resources that run within or outside of your VPC. By contrast, Calico +Enterprise includes a feature that allows you to map a Kubernetes +network policy to an AWS security group, as well as DNS hostnames. + +You can find a list of common Kubernetes network policies at +https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar +set of rules for Calico are available at +https://docs.projectcalico.org/security/calico-network-policy. + +==== Migration to Amazon VPC CNI Network Policy Engine + +To maintain consistency and avoid unexpected pod communication behavior, +it is recommended to deploy only one Network Policy Engine in your +cluster. If you want to migrate from 3P to VPC CNI Network Policy +Engine, we recommend converting your existing 3P NetworkPolicy CRDs to +the Kubernetes NetworkPolicy resources before enabling VPC CNI network +policy support. And, test the migrated policies in a separate test +cluster before applying them in you production environment. This allows +you to identify and address any potential issues or inconsistencies in +pod communication behavior. + +===== Migration Tool + +To assist in your migration process, we have developed a tool called +https://github.com/awslabs/k8s-network-policy-migrator[K8s Network +Policy Migrator] that converts your existing Calico/Cilium network +policy CRDs to Kubernetes native network policies. After conversion you +can directly test the converted network policies on your new clusters +running VPC CNI network policy controller. The tool is designed to help +you streamline the migration process and ensure a smooth transition. + +!!! Important Migration tool will only convert 3P policies that are +compatible with native kubernetes network policy api. If you are using +advanced network policy features offered by 3P plugins, Migration tool +will skip and report them. + +Please note that migration tool is currently not supported by AWS VPC +CNI Network policy engineering team, it is made available to customers +on a best-effort basis. We encourage you to utilize this tool to +facilitate your migration process. In the event that you encounter any +issues or bugs with the tool, we kindly ask you create a +https://github.com/awslabs/k8s-network-policy-migrator/issues[GitHub +issue]. Your feedback is invaluable to us and will assist in the +continuous improvement of our services. + +==== Additional Resources + +* https://youtu.be/lEY2WnRHYpg[Kubernetes & Tigera: Network +Policies, Security, and Audit] +* https://www.tigera.io/tigera-products/calico-enterprise/[Calico +Enterprise] +* https://cilium.readthedocs.io/en/stable/intro/[Cilium] +* https://cilium.io/blog/2021/02/10/network-policy-editor[NetworkPolicy +Editor] an interactive policy editor from Cilium +* https://www.inspektor-gadget.io/docs/latest/gadgets/advise/network-policy/[Inspektor +Gadget advise network-policy gadget] Suggests network policies based on +an analysis of network traffic + +=== Encryption in transit + +Applications that need to conform to PCI, HIPAA, or other regulations +may need to encrypt data while it is in transit. Nowadays TLS is the de +facto choice for encrypting traffic on the wire. TLS, like it’s +predecessor SSL, provides secure communications over a network using +cryptographic protocols. TLS uses symmetric encryption where the keys to +encrypt the data are generated based on a shared secret that is +negotiated at the beginning of the session. The following are a few ways +that you can encrypt data in a Kubernetes environment. + +==== Nitro Instances + +Traffic exchanged between the following Nitro instance types, e.g. C5n, +G4, I3en, M5dn, M5n, P3dn, R5dn, and R5n, is automatically encrypted by +default. When there’s an intermediate hop, like a transit gateway or a +load balancer, the traffic is not encrypted. See +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/data-protection.html#encryption-transit[Encryption +in transit] for further details on encryption in transit as well as the +complete list of instances types that support network encryption by +default. + +==== Container Network Interfaces (CNIs) + +https://www.weave.works/oss/net/[WeaveNet] can be configured to +automatically encrypt all traffic using NaCl encryption for sleeve +traffic, and IPsec ESP for fast datapath traffic. + +==== Service Mesh + +Encryption in transit can also be implemented with a service mesh like +App Mesh, Linkerd v2, and Istio. AppMesh supports +https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html[mTLS] +with X.509 certificates or Envoy’s Secret Discovery Service(SDS). +Linkerd and Istio both have support for mTLS. + +The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples] +GitHub repository provides walkthroughs for configuring mTLS using X.509 +certificates and SPIRE as SDS provider with your Envoy container: + +* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-file-based[Configuring +mTLS using X.509 certificates] +* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-sds-based[Configuring +TLS using SPIRE (SDS)] + +App Mesh also supports +https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html[TLS +encryption] with a private certificate issued by +https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS +Certificate Manager] (ACM) or a certificate stored on the local file +system of the virtual node. + +The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples] +GitHub repository provides walkthroughs for configuring TLS using +certificates issued by ACM and certificates that are packaged with your +Envoy container: + +* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/howto-tls-file-provided[Configuring +TLS with File Provided TLS Certificates] +* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm[Configuring +TLS with AWS Certificate Manager] + +==== Ingress Controllers and Load Balancers + +Ingress controllers are a way for you to intelligently route HTTP/S +traffic that emanates from outside the cluster to services running +inside the cluster. Oftentimes, these Ingresses are fronted by a layer 4 +load balancer, like the Classic Load Balancer or the Network Load +Balancer (NLB). Encrypted traffic can be terminated at different places +within the network, e.g. at the load balancer, at the ingress resource, +or the Pod. How and where you terminate your SSL connection will +ultimately be dictated by your organization’s network security policy. +For instance, if you have a policy that requires end-to-end encryption, +you will have to decrypt the traffic at the Pod. This will place +additional burden on your Pod as it will have to spend cycles +establishing the initial handshake. Overall SSL/TLS processing is very +CPU intensive. Consequently, if you have the flexibility, try performing +the SSL offload at the Ingress or the load balancer. + +===== Use encryption with AWS Elastic load balancers + +The +https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html[AWS +Application Load Balancer] (ALB) and +https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html[Network +Load Balancer] (NLB) both have support for transport encryption (SSL and +TLS). The `+alb.ingress.kubernetes.io/certificate-arn+` annotation for +the ALB lets you to specify which certificates to add to the ALB. If you +omit the annotation the controller will attempt to add certificates to +listeners that require it by matching the available +https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS +Certificate Manager (ACM)] certificates using the host field. Starting +with EKS v1.15 you can use the +`+service.beta.kubernetes.io/aws-load-balancer-ssl-cert+` annotation +with the NLB as shown in the example below. + +[source,yaml] +---- +apiVersion: v1 +kind: Service +metadata: + name: demo-app + namespace: default + labels: + app: demo-app + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: "nlb" + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" +spec: + type: LoadBalancer + ports: + - port: 443 + targetPort: 80 + protocol: TCP + selector: + app: demo-app +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: nginx + namespace: default + labels: + app: demo-app +spec: + replicas: 1 + selector: + matchLabels: + app: demo-app + template: + metadata: + labels: + app: demo-app + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 443 + protocol: TCP + - containerPort: 80 + protocol: TCP +---- + +Following are additional examples for SSL/TLS termination. + +* https://aws.amazon.com/blogs/containers/securing-eks-ingress-contour-lets-encrypt-gitops/[Securing +EKS Ingress With Contour And Let’s Encrypt The GitOps Way] +* https://aws.amazon.com/premiumsupport/knowledge-center/terminate-https-traffic-eks-acm/[How +do I terminate HTTPS traffic on Amazon EKS workloads with ACM?] + +!!! attention Some Ingresses, like the AWS LB controller, implement the +SSL/TLS using Annotations instead of as part of the Ingress Spec. + +==== ACM Private CA with cert-manager + +You can enable TLS and mTLS to secure your EKS application workloads at +the ingress, on the pod, and between pods using ACM Private Certificate +Authority (CA) and https://cert-manager.io/[cert-manager], a popular +Kubernetes add-on to distribute, renew, and revoke certificates. ACM +Private CA is a highly-available, secure, managed CA without the upfront +and maintenance costs of managing your own CA. If you are using the +default Kubernetes certificate authority, there is an opportunity to +improve your security and meet compliance requirements with ACM Private +CA. ACM Private CA secures private keys in FIPS 140-2 Level 3 hardware +security modules (very secure), compared with the default CA storing +keys encoded in memory (less secure). A centralized CA also gives you +more control and improved auditability for private certificates both +inside and outside of a Kubernetes environment. + +===== Short-Lived CA Mode for Mutual TLS Between Workloads + +When using ACM Private CA for mTLS in EKS, it is recommended that you +use short lived certificates with _short-lived CA mode_. Although it is +possible to issue out short-lived certificates in the general-purpose CA +mode, using short-lived CA mode works out more cost-effective (~75% +cheaper than general mode) for use cases where new certificates need to +be issued frequently. In addition to this, you should try to align the +validity period of the private certificates with the lifetime of the +pods in your EKS cluster. +https://aws.amazon.com/certificate-manager/private-certificate-authority/[Learn +more about ACM Private CA and its benefits here]. + +===== ACM Setup Instructions + +Start by creating a Private CA by following procedures provided in the +https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html[ACM +Private CA tech docs]. Once you have a Private CA, install cert-manager +using https://cert-manager.io/docs/installation/[regular installation +instructions]. After installing cert-manager, install the Private CA +Kubernetes cert-manager plugin by following the +https://github.com/cert-manager/aws-privateca-issuer#setup[setup +instructions in GitHub]. The plugin lets cert-manager request private +certificates from ACM Private CA. + +Now that you have a Private CA and an EKS cluster with cert-manager and +the plugin installed, it’s time to set permissions and create the +issuer. Update IAM permissions of the EKS node role to allow access to +ACM Private CA. Replace the `++` with the value from your +Private CA: + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "awspcaissuer", + "Action": [ + "acm-pca:DescribeCertificateAuthority", + "acm-pca:GetCertificate", + "acm-pca:IssueCertificate" + ], + "Effect": "Allow", + "Resource": "" + } + ] +} +---- + +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[Service +Roles for IAM Accounts, or IRSA] can also be used. Please see the +Additional Resources section below for complete examples. + +Create an Issuer in Amazon EKS by creating a Custom Resource Definition +file named cluster-issuer.yaml with the following text in it, replacing +`++` and `++` information with your Private CA. + +[source,yaml] +---- +apiVersion: awspca.cert-manager.io/v1beta1 +kind: AWSPCAClusterIssuer +metadata: + name: demo-test-root-ca +spec: + arn: + region: +---- + +Deploy the Issuer you created. + +[source,bash] +---- +kubectl apply -f cluster-issuer.yaml +---- + +Your EKS cluster is configured to request certificates from Private CA. +You can now use cert-manager’s `+Certificate+` resource to issue +certificates by changing the `+issuerRef+` field’s values to the Private +CA Issuer you created above. For more details on how to specify and +request Certificate resources, please check cert-manager’s +https://cert-manager.io/docs/usage/certificate/[Certificate Resources +guide]. +https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/[See +examples here]. + +==== ACM Private CA with Istio and cert-manager + +If you are running Istio in your EKS cluster, you can disable the Istio +control plane (specifically `+istiod+`) from functioning as the root +Certificate Authority (CA), and configure ACM Private CA as the root CA +for mTLS between workloads. If you’re going with this approach, consider +using the _short-lived CA mode_ in ACM Private CA. Refer to the +link:#short-lived-ca-mode-for-mutual-tls-between-workloads[previous +section] and this +https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[blog +post] for more details. + +===== How Certificate Signing Works in Istio (Default) + +Workloads in Kubernetes are identified using service accounts. If you +don’t specify a service account, Kubernetes will automatically assign +one to your workload. Also, service accounts automatically mount an +associated token. This token is used by the service account for +workloads to authenticate against the Kubernetes API. The service +account may be sufficient as an identity for Kubernetes but Istio has +its own identity management system and CA. When a workload starts up +with its envoy sidecar proxy, it needs an identity assigned from Istio +in order for it to be deemed as trustworthy and allowed to communicate +with other services in the mesh. + +To get this identity from Istio, the `+istio-agent+` sends a request +known as a certificate signing request (or CSR) to the Istio control +plane. This CSR contains the service account token so that the +workload’s identity can be verified before being processed. This +verification process is handled by `+istiod+`, which acts as both the +Registration Authority (or RA) and the CA. The RA serves as a gatekeeper +that makes sure only verified CSR makes it through to the CA. Once the +CSR is verified, it will be forwarded to the CA which will then issue a +certificate containing a https://spiffe.io/[SPIFFE] identity with the +service account. This certificate is called a SPIFFE verifiable identity +document (or SVID). The SVID is assigned to the requesting service for +identification purposes and to encrypt the traffic in transit between +the communicating services. + +.Default flow for Istio Certificate Signing Requests +image::./images/default-istio-csr-flow.png[Default flow for Istio +Certificate Signing Requests] + +===== How Certificate Signing Works in Istio with ACM Private CA + +You can use a cert-manager add-on called the Istio Certificate Signing +Request agent +(https://cert-manager.io/docs/projects/istio-csr/[istio-csr]) to +integrate Istio with ACM Private CA. This agent allows Istio workloads +and control plane components to be secured with cert manager issuers, in +this case ACM Private CA. The _istio-csr_ agent exposes the same service +that _istiod_ serves in the default config of validating incoming CSRs. +Except, after verification, it will convert the requests into resources +that cert manager supports (i.e. integrations with external CA issuers). + +Whenever there’s a CSR from a workload, it will be forwarded to +_istio-csr_, which will request certificates from ACM Private CA. This +communication between _istio-csr_ and ACM Private CA is enabled by the +https://github.com/cert-manager/aws-privateca-issuer[AWS Private CA +issuer plugin]. Cert manager uses this plugin to request TLS +certificates from ACM Private CA. The issuer plugin will communicate +with the ACM Private CA service to request a signed certificate for the +workload. Once the certificate has been signed, it will be returned to +_istio-csr_, which will read the signed request, and return it to the +workload that initiated the CSR. + +.Flow for Istio Certificate Signing Requests with istio-csr +image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio +Certificate Signing Requests with istio-csr] + +===== Istio with Private CA Setup Instructions + +[arabic] +. Start by following the same +link:#acm-private-ca-with-cert-manager[setup instructions in this +section] to complete the following: +. Create a Private CA +. Install cert-manager +. Install the issuer plugin +. Set permissions and create an issuer. The issuer represents the CA and +is used to sign `+istiod+` and mesh workload certificates. It will +communicate with ACM Private CA. +. Create an `+istio-system+` namespace. This is where the +`+istiod certificate+` and other Istio resources will be deployed. +. Install Istio CSR configured with AWS Private CA Issuer Plugin. You +can preserve the certificate signing requests for workloads to verify +that they get approved and signed +(`+preserveCertificateRequests=true+`). ++ +[source,bash] +---- +helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \ +--set "app.certmanager.issuer.group=awspca.cert-manager.io" \ +--set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \ +--set "app.certmanager.issuer.name=" \ +--set "app.certmanager.preserveCertificateRequests=true" \ +--set "app.server.maxCertificateDuration=48h" \ +--set "app.tls.certificateDuration=24h" \ +--set "app.tls.istiodCertificateDuration=24h" \ +--set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \ +--set "volumeMounts[0].name=root-ca" \ +--set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ +--set "volumes[0].name=root-ca" \ +--set "volumes[0].secret.secretName=istio-root-ca" +---- +. Install Istio with custom configurations to replace `+istiod+` with +`+cert-manager istio-csr+` as the certificate provider for the mesh. +This process can be carried out using the +https://tetrate.io/blog/what-is-istio-operator/[Istio Operator]. ++ +[source,yaml] +---- +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +metadata: + name: istio + namespace: istio-system +spec: + profile: "demo" + hub: gcr.io/istio-release + values: + global: + # Change certificate provider to cert-manager istio agent for istio agent + caAddress: cert-manager-istio-csr.cert-manager.svc:443 + components: + pilot: + k8s: + env: + # Disable istiod CA Sever functionality + - name: ENABLE_CA_SERVER + value: "false" + overlays: + - apiVersion: apps/v1 + kind: Deployment + name: istiod + patches: + + # Mount istiod serving and webhook certificate from Secret mount + - path: spec.template.spec.containers.[name:discovery].args[7] + value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt" + - path: spec.template.spec.containers.[name:discovery].args[8] + value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key" + - path: spec.template.spec.containers.[name:discovery].args[9] + value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem" + + - path: spec.template.spec.containers.[name:discovery].volumeMounts[6] + value: + name: cert-manager + mountPath: "/etc/cert-manager/tls" + readOnly: true + - path: spec.template.spec.containers.[name:discovery].volumeMounts[7] + value: + name: ca-root-cert + mountPath: "/etc/cert-manager/ca" + readOnly: true + + - path: spec.template.spec.volumes[6] + value: + name: cert-manager + secret: + secretName: istiod-tls + - path: spec.template.spec.volumes[7] + value: + name: ca-root-cert + configMap: + defaultMode: 420 + name: istio-ca-root-cert +---- +. Deploy the above custom resource you created. ++ +[source,bash] +---- +istioctl operator init +kubectl apply -f istio-custom-config.yaml +---- +. Now you can deploy a workload to the mesh in your EKS cluster and +https://istio.io/latest/docs/reference/config/security/peer_authentication/[enforce +mTLS]. + +.Istio certificate signing requests +image::./images/istio-csr-requests.png[Istio certificate signing +requests] + +=== Tools and resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/6-network-security[Amazon +EKS Security Immersion Workshop - Network security] +* https://aws.amazon.com/blogs/security/tls-enabled-kubernetes-clusters-with-acm-private-ca-and-amazon-eks-2/[How +to implement cert-manager and the ACM Private CA plugin to enable TLS in +EKS]. +* https://aws.amazon.com/blogs/containers/setting-up-end-to-end-tls-encryption-on-amazon-eks-with-the-new-aws-load-balancer-controller/[Setting +up end-to-end TLS encryption on Amazon EKS with the new AWS Load +Balancer Controller and ACM Private CA]. +* https://github.com/cert-manager/aws-privateca-issuer[Private CA +Kubernetes cert-manager plugin on GitHub]. +* https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaKubernetes.html[Private +CA Kubernetes cert-manager plugin user guide]. +* https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[How +to use AWS Private Certificate Authority short-lived certificate mode] +* https://itnext.io/verifying-service-mesh-tls-in-kubernetes-using-ksniff-and-wireshark-2e993b26bf95[Verifying +Service Mesh TLS in Kubernetes, Using ksniff and Wireshark] +* https://github.com/eldadru/ksniff[ksniff] +* https://github.com/monzo/egress-operator[egress-operator] An operator +and DNS plugin to control egress traffic from your cluster without +protocol inspection +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides policy network rules, +data loss prevention (DLP), web application firewall (WAF) and network +threat signatures. diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc new file mode 100644 index 000000000..48f9a2de0 --- /dev/null +++ b/latest/bpg/security/pods.adoc @@ -0,0 +1,828 @@ +== Pod Security + +The pod specification includes a variety of different attributes that +can strengthen or weaken your overall security posture. As a Kubernetes +practitioner your chief concern should be preventing a process that’s +running in a container from escaping the isolation boundaries of the +container runtime and gaining access to the underlying host. + +=== Linux Capabilities + +The processes that run within a container run under the context of the +[Linux] root user by default. Although the actions of root within a +container are partially constrained by the set of Linux capabilities +that the container runtime assigns to the containers, these default +privileges could allow an attacker to escalate their privileges and/or +gain access to sensitive information bound to the host, including +Secrets and ConfigMaps. Below is a list of the default capabilities +assigned to containers. For additional information about each +capability, see +http://man7.org/linux/man-pages/man7/capabilities.7.html. + +`+CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT+` + +!!! Info + +EC2 and Fargate pods are assigned the aforementioned capabilities by +default. Additionally, Linux capabilities can only be dropped from +Fargate pods. + +Pods that are run as privileged, inherit _all_ of the Linux capabilities +associated with root on the host. This should be avoided if possible. + +==== Node Authorization + +All Kubernetes worker nodes use an authorization mode called +https://kubernetes.io/docs/reference/access-authn-authz/node/[Node +Authorization]. Node Authorization authorizes all API requests that +originate from the kubelet and allows nodes to perform the following +actions: + +Read operations: + +* services +* endpoints +* nodes +* pods +* secrets, configmaps, persistent volume claims and persistent volumes +related to pods bound to the kubelet’s node + +Write operations: + +* nodes and node status (enable the `+NodeRestriction+` admission plugin +to limit a kubelet to modify its own node) +* pods and pod status (enable the `+NodeRestriction+` admission plugin +to limit a kubelet to modify pods bound to itself) +* events + +Auth-related operations: + +* Read/write access to the CertificateSigningRequest (CSR) API for TLS +bootstrapping +* the ability to create TokenReview and SubjectAccessReview for +delegated authentication/authorization checks + +EKS uses the +https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[node +restriction admission controller] which only allows the node to modify a +limited set of node attributes and pod objects that are bound to the +node. Nevertheless, an attacker who manages to get access to the host +will still be able to glean sensitive information about the environment +from the Kubernetes API that could allow them to move laterally within +the cluster. + +=== Pod Security Solutions + +==== Pod Security Policy (PSP) + +In the past, +https://kubernetes.io/docs/concepts/policy/pod-security-policy/[Pod +Security Policy (PSP)] resources were used to specify a set of +requirements that pods had to meet before they could be created. As of +Kubernetes version 1.21, PSP have been deprecated. They are scheduled +for removal in Kubernetes version 1.25. + +!!! Attention + +https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/[PSPs +are deprecated] in Kubernetes version 1.21. You will have until version +1.25 or roughly 2 years to transition to an alternative. This +https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation[document] +explains the motivation for this deprecation. + +==== Migrating to a new pod security solution + +Since PSPs have been removed as of Kubernetes v1.25, cluster +administrators and operators must replace those security controls. Two +solutions can fill this need: + +* Policy-as-code (PAC) solutions from the Kubernetes ecosystem +* Kubernetes +https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod +Security Standards (PSS)] + +Both the PAC and PSS solutions can coexist with PSP; they can be used in +clusters before PSP is removed. This eases adoption when migrating from +PSP. Please see this +https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/[document] +when considering migrating from PSP to PSS. + +Kyverno, one of the PAC solutions outlined below, has specific guidance +outlined in a +https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/[blog +post] when migrating from PSPs to its solution including analogous +policies, feature comparisons, and a migration procedure. Additional +information and guidance on migration to Kyverno with respect to Pod +Security Admission (PSA) has been published on the AWS blog +https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/[here]. + +==== Policy-as-code (PAC) + +Policy-as-code (PAC) solutions provide guardrails to guide cluster +users, and prevent unwanted behaviors, through prescribed and automated +controls. PAC uses +https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/[Kubernetes +Dynamic Admission Controllers] to intercept the Kubernetes API server +request flow, via a webhook call, and mutate and validate request +payloads, based on policies written and stored as code. Mutation and +validation happens before the API server request results in a change to +the cluster. PAC solutions use policies to match and act on API server +request payloads, based on taxonomy and values. + +There are several open source PAC solutions available for Kubernetes. +These solutions are not part of the Kubernetes project; they are sourced +from the Kubernetes ecosystem. Some PAC solutions are listed below. + +* https://open-policy-agent.github.io/gatekeeper/website/docs/[OPA/Gatekeeper] +* https://www.openpolicyagent.org/[Open Policy Agent (OPA)] +* https://kyverno.io/[Kyverno] +* https://www.kubewarden.io/[Kubewarden] +* https://www.jspolicy.com/[jsPolicy] + +For further information about PAC solutions and how to help you select +the appropriate solution for your needs, see the links below. + +* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy-based +countermeasures for Kubernetes – Part 1] +* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy-based +countermeasures for Kubernetes – Part 2] + +==== Pod Security Standards (PSS) and Pod Security Admission (PSA) + +In response to the PSP deprecation and the ongoing need to control pod +security out-of-the-box, with a built-in Kubernetes solution, the +Kubernetes +https://github.com/kubernetes/community/tree/master/sig-auth[Auth +Special Interest Group] created the +https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod +Security Standards (PSS)] and +https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod +Security Admission (PSA)]. The PSA effort includes an +https://github.com/kubernetes/pod-security-admission#pod-security-admission[admission +controller webhook project] that implements the controls defined in the +PSS. This admission controller approach resembles that used in the PAC +solutions. + +According to the Kubernetes documentation, the PSS _"`define three +different policies to broadly cover the security spectrum. These +policies are cumulative and range from highly-permissive to +highly-restrictive.`"_ + +These policies are defined as: + +* *Privileged:* Unrestricted (unsecure) policy, providing the widest +possible level of permissions. This policy allows for known privilege +escalations. It is the absence of a policy. This is good for +applications such as logging agents, CNIs, storage drivers, and other +system wide applications that need privileged access. +* *Baseline:* Minimally restrictive policy which prevents known +privilege escalations. Allows the default (minimally specified) Pod +configuration. The baseline policy prohibits use of hostNetwork, +hostPID, hostIPC, hostPath, hostPort, the inability to add Linux +capabilities, along with several other restrictions. +* *Restricted:* Heavily restricted policy, following current Pod +hardening best practices. This policy inherits from the baseline and +adds further restrictions such as the inability to run as root or a +root-group. Restricted policies may impact an application’s ability to +function. They are primarily targeted at running security critical +applications. + +These policies define +https://kubernetes.io/docs/concepts/security/pod-security-standards/#profile-details[profiles +for pod execution], arranged into three levels of privileged +vs. restricted access. + +To implement the controls defined by the PSS, PSA operates in three +modes: + +* *enforce:* Policy violations will cause the pod to be rejected. +* *audit:* Policy violations will trigger the addition of an audit +annotation to the event recorded in the audit log, but are otherwise +allowed. +* *warn:* Policy violations will trigger a user-facing warning, but are +otherwise allowed. + +These modes and the profile (restriction) levels are configured at the +Kubernetes Namespace level, using labels, as seen in the below example. + +[source,yaml] +---- +apiVersion: v1 +kind: Namespace +metadata: + name: policy-test + labels: + pod-security.kubernetes.io/enforce: restricted +---- + +When used independently, these operational modes have different +responses that result in different user experiences. The _enforce_ mode +will prevent pods from being created if respective podSpecs violate the +configured restriction level. However, in this mode, non-pod Kubernetes +objects that create pods, such as Deployments, will not be prevented +from being applied to the cluster, even if the podSpec therein violates +the applied PSS. In this case the Deployment will be applied, while the +pod(s) will be prevented from being applied. + +This is a difficult user experience, as there is no immediate indication +that the successfully applied Deployment object belies failed pod +creation. The offending podSpecs will not create pods. Inspecting the +Deployment resource with `+kubectl get deploy -oyaml+` +will expose the message from the failed pod(s) `+.status.conditions+` +element, as seen below. + +[source,yaml] +---- +... +status: + conditions: + - lastTransitionTime: "2022-01-20T01:02:08Z" + lastUpdateTime: "2022-01-20T01:02:08Z" + message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest": + allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), + unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), + runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), + seccompProfile (pod or container "test" must set securityContext.seccompProfile.type + to "RuntimeDefault" or "Localhost")' + reason: FailedCreate + status: "True" + type: ReplicaFailure +... +---- + +In both the _audit_ and _warn_ modes, the pod restrictions do not +prevent violating pods from being created and started. However, in these +modes audit annotations on API server audit log events and warnings to +API server clients, such as _kubectl_, are triggered, respectively, when +pods, as well as objects that create pods, contain podSpecs with +violations. A `+kubectl+` _Warning_ message is seen below. + +[source,bash] +---- +Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") +deployment.apps/test created +---- + +The PSA _audit_ and _warn_ modes are useful when introducing the PSS +without negatively impacting cluster operations. + +The PSA operational modes are not mutually exclusive, and can be used in +a cumulative manner. As seen below, the multiple modes can be configured +in a single namespace. + +[source,yaml] +---- +apiVersion: v1 +kind: Namespace +metadata: + name: policy-test + labels: + pod-security.kubernetes.io/audit: restricted + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/warn: restricted +---- + +In the above example, the user-friendly warnings and audit annotations +are provided when applying Deployments, while the enforce of violations +are also provided at the pod level. In fact multiple PSA labels can use +different profile levels, as seen below. + +[source,yaml] +---- +apiVersion: v1 +kind: Namespace +metadata: + name: policy-test + labels: + pod-security.kubernetes.io/enforce: baseline + pod-security.kubernetes.io/warn: restricted +---- + +In the above example, PSA is configured to allow the creation of all +pods that satisfy the _baseline_ profile level, and then _warn_ on pods +(and objects that create pods) that violate the _restricted_ profile +level. This is a useful approach to determine the possible impacts when +changing from the _baseline_ to _restricted_ profiles. + +===== Existing Pods + +If a namespace with existing pods is modified to use a more restrictive +PSS profile, the _audit_ and _warn_ modes will produce appropriate +messages; however, _enforce_ mode will not delete the pods. The warning +messages are seen below. + +[source,bash] +---- +Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest" +Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile +namespace/policy-test configured +---- + +===== Exemptions + +PSA uses _Exemptions_ to exclude enforcement of violations against pods +that would have otherwise been applied. These exemptions are listed +below. + +* *Usernames:* requests from users with an exempt authenticated (or +impersonated) username are ignored. +* *RuntimeClassNames:* pods and workload resources specifying an exempt +runtime class name are ignored. +* *Namespaces:* pods and workload resources in an exempt namespace are +ignored. + +These exemptions are applied statically in the +https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller[PSA +admission controller configuration] as part of the API server +configuration. + +In the _Validating Webhook_ implementation the exemptions can be +configured within a Kubernetes +https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/20-configmap.yaml[ConfigMap] +resource that gets mounted as a volume into the +https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/50-deployment.yaml[pod-security-webhook] +container. + +[source,yaml] +---- +apiVersion: v1 +kind: ConfigMap +metadata: + name: pod-security-webhook + namespace: pod-security-webhook +data: + podsecurityconfiguration.yaml: | + apiVersion: pod-security.admission.config.k8s.io/v1 + kind: PodSecurityConfiguration + defaults: + enforce: "restricted" + enforce-version: "latest" + audit: "restricted" + audit-version: "latest" + warn: "restricted" + warn-version: "latest" + exemptions: + # Array of authenticated usernames to exempt. + usernames: [] + # Array of runtime class names to exempt. + runtimeClasses: [] + # Array of namespaces to exempt. + namespaces: ["kube-system","policy-test1"] +---- + +As seen in the above ConfigMap YAML the cluster-wide default PSS level +has been set to _restricted_ for all PSA modes, _audit_, _enforce_, and +_warn_. This affects all namespaces, except those exempted: +`+namespaces: ["kube-system","policy-test1"]+`. Additionally, in the +_ValidatingWebhookConfiguration_ resource, seen below, the +_pod-security-webhook_ namespace is also exempted from configured PSS. + +[source,yaml] +---- +... +webhooks: + # Audit annotations will be prefixed with this name + - name: "pod-security-webhook.kubernetes.io" + # Fail-closed admission webhooks can present operational challenges. + # You may want to consider using a failure policy of Ignore, but should + # consider the security tradeoffs. + failurePolicy: Fail + namespaceSelector: + # Exempt the webhook itself to avoid a circular dependency. + matchExpressions: + - key: kubernetes.io/metadata.name + operator: NotIn + values: ["pod-security-webhook"] +... +---- + +!!! Attention + +Pod Security Admissions graduated to stable in Kubernetes v1.25. If you +wanted to use the Pod Security Admission feature prior to it being +enabled by default, you needed to install the dynamic admission +controller (mutating webhook). The instructions for installing and +configuring the webhook can be found +https://github.com/kubernetes/pod-security-admission/tree/master/webhook[here]. + +==== Choosing between policy-as-code and Pod Security Standards + +The Pod Security Standards (PSS) were developed to replace the Pod +Security Policy (PSP), by providing a solution that was built-in to +Kubernetes and did not require solutions from the Kubernetes ecosystem. +That being said, policy-as-code (PAC) solutions are considerably more +flexible. + +The following list of Pros and Cons is designed help you make a more +informed decision about your pod security solution. + +===== Policy-as-code (as compared to Pod Security Standards) + +Pros: + +* More flexible and more granular (down to attributes of resources if +need be) +* Not just focused on pods, can be used against different resources and +actions +* Not just applied at the namespace level +* More mature than the Pod Security Standards +* Decisions can be based on anything in the API server request payload, +as well as existing cluster resources and external data (solution +dependent) +* Supports mutating API server requests before validation (solution +dependent) +* Can generate complementary policies and Kubernetes resources (solution +dependent - From pod policies, Kyverno can +https://kyverno.io/docs/writing-policies/autogen/[auto-gen] policies for +higher-level controllers, such as Deployments. Kyverno can also generate +additional Kubernetes resources _"`when a new resource is created or +when the source is updated`"_ by using +https://kyverno.io/docs/writing-policies/generate/[Generate Rules].) +* Can be used to shift left, into CICD pipelines, before making calls to +the Kubernetes API server (solution dependent) +* Can be used to implement behaviors that are not necessarily security +related, such as best practices, organizational standards, etc. +* Can be used in non-Kubernetes use cases (solution dependent) +* Because of flexibility, the user experience can be tuned to users’ +needs + +Cons: + +* Not built into Kubernetes +* More complex to learn, configure, and support +* Policy authoring may require new skills/languages/capabilities + +===== Pod Security Admission (as compared to policy-as-code) + +Pros: + +* Built into Kubernetes +* Simpler to configure +* No new languages to use or policies to author +* If the cluster default admission level is configured to _privileged_, +namespace labels can be used to opt namespaces into the pod security +profiles. + +Cons: + +* Not as flexible or granular as policy-as-code +* Only 3 levels of restrictions +* Primarily focused on pods + +===== Summary + +If you currently do not have a pod security solution, beyond PSP, and +your required pod security posture fits the model defined in the Pod +Security Standards (PSS), then an easier path may be to adopt the PSS, +in lieu of a policy-as-code solution. However, if your pod security +posture does not fit the PSS model, or you envision adding additional +controls, beyond that defined by PSS, then a policy-as-code solution +would seem a better fit. + +=== Recommendations + +==== Use multiple Pod Security Admission (PSA) modes for a better user experience + +As mentioned earlier, PSA _enforce_ mode prevents pods with PSS +violations from being applied, but does not stop higher-level +controllers, such as Deployments. In fact, the Deployment will be +applied successfully without any indication that the pods failed to be +applied. While you can use _kubectl_ to inspect the Deployment object, +and discover the failed pods message from the PSA, the user experience +could be better. To make the user experience better, multiple PSA modes +(audit, enforce, warn) should be used. + +[source,yaml] +---- +apiVersion: v1 +kind: Namespace +metadata: + name: policy-test + labels: + pod-security.kubernetes.io/audit: restricted + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/warn: restricted +---- + +In the above example, with _enforce_ mode defined, when a Deployment +manifest with PSS violations in the respective podSpec is attempted to +be applied to the Kubernetes API server, the Deployment will be +successfully applied, but the pods will not. And, since the _audit_ and +_warn_ modes are also enabled, the API server client will receive a +warning message and the API server audit log event will be annotated +with a message as well. + +==== Restrict the containers that can run as privileged + +As mentioned, containers that run as privileged inherit all of the Linux +capabilities assigned to root on the host. Seldom do containers need +these types of privileges to function properly. There are multiple +methods that can be used to restrict the permissions and capabilities of +containers. + +!!! Attention + +Fargate is a launch type that enables you to run "`serverless`" +container(s) where the containers of a pod are run on infrastructure +that AWS manages. With Fargate, you cannot run a privileged container or +configure your pod to use hostNetwork or hostPort. + +==== Do not run processes in containers as root + +All containers run as root by default. This could be problematic if an +attacker is able to exploit a vulnerability in the application and get +shell access to the running container. You can mitigate this risk a +variety of ways. First, by removing the shell from the container image. +Second, adding the USER directive to your Dockerfile or running the +containers in the pod as a non-root user. The Kubernetes podSpec +includes a set of fields, under `+spec.securityContext+`, that let you +specify the user and/or group under which to run your application. These +fields are `+runAsUser+` and `+runAsGroup+` respectively. + +To enforce the use of the `+spec.securityContext+`, and its associated +elements, within the Kubernetes podSpec, policy-as-code or Pod Security +Standards can be added to clusters. These solutions allow you to write +and/or use policies or profiles that can validate inbound Kubernetes API +server request payloads, before they are persisted into etcd. +Furthermore, policy-as-code solutions can mutate inbound requests, and +in some cases, generate new requests. + +==== Never run Docker in Docker or mount the socket in the container + +While this conveniently lets you to build/run images in Docker +containers, you’re basically relinquishing complete control of the node +to the process running in the container. If you need to build container +images on Kubernetes use +https://github.com/GoogleContainerTools/kaniko[Kaniko], +https://github.com/containers/buildah[buildah], or a build service like +https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html[CodeBuild] +instead. + +!!! Tip + +Kubernetes clusters used for CICD processing, such as building container +images, should be isolated from clusters running more generalized +workloads. + +==== Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only + +`+hostPath+` is a volume that mounts a directory from the host directly +to the container. Rarely will pods need this type of access, but if they +do, you need to be aware of the risks. By default pods that run as root +will have write access to the file system exposed by hostPath. This +could allow an attacker to modify the kubelet settings, create symbolic +links to directories or files not directly exposed by the hostPath, +e.g. /etc/shadow, install ssh keys, read secrets mounted to the host, +and other malicious things. To mitigate the risks from hostPath, +configure the `+spec.containers.volumeMounts+` as `+readOnly+`, for +example: + +[source,yaml] +---- +volumeMounts: +- name: hostPath-volume + readOnly: true + mountPath: /host-path +---- + +You should also use policy-as-code solutions to restrict the directories +that can be used by `+hostPath+` volumes, or prevent `+hostPath+` usage +altogether. You can use the Pod Security Standards _Baseline_ or +_Restricted_ policies to prevent the use of `+hostPath+`. + +For further information about the dangers of privileged escalation, read +Seth Art’s blog +https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation[Bad +Pods: Kubernetes Pod Privilege Escalation]. + +==== Set requests and limits for each container to avoid resource contention and DoS attacks + +A pod without requests or limits can theoretically consume all of the +resources available on a host. As additional pods are scheduled onto a +node, the node may experience CPU or memory pressure which can cause the +Kubelet to terminate or evict pods from the node. While you can’t +prevent this from happening all together, setting requests and limits +will help minimize resource contention and mitigate the risk from poorly +written applications that consume an excessive amount of resources. + +The `+podSpec+` allows you to specify requests and limits for CPU and +memory. CPU is considered a compressible resource because it can be +oversubscribed. Memory is incompressible, i.e. it cannot be shared among +multiple containers. + +When you specify _requests_ for CPU or memory, you’re essentially +designating the amount of _memory_ that containers are guaranteed to +get. Kubernetes aggregates the requests of all the containers in a pod +to determine which node to schedule the pod onto. If a container exceeds +the requested amount of memory it may be subject to termination if +there’s memory pressure on the node. + +_Limits_ are the maximum amount of CPU and memory resources that a +container is allowed to consume and directly corresponds to the +`+memory.limit_in_bytes+` value of the cgroup created for the container. +A container that exceeds the memory limit will be OOM killed. If a +container exceeds its CPU limit, it will be throttled. + +!!! Tip + +When using container `+resources.limits+` it is strongly recommended +that container resource usage (a.k.a. Resource Footprints) be +data-driven and accurate, based on load testing. Absent an accurate and +trusted resource footprint, container `+resources.limits+` can be +padded. For example, `+resources.limits.memory+` could be padded 20-30% +higher than observable maximums, to account for potential memory +resource limit inaccuracies. + +Kubernetes uses three Quality of Service (QoS) classes to prioritize the +workloads running on a node. These include: + +* guaranteed +* burstable +* best-effort + +If limits and requests are not set, the pod is configured as +_best-effort_ (lowest priority). Best-effort pods are the first to get +killed when there is insufficient memory. If limits are set on _all_ +containers within the pod, or if the requests and limits are set to the +same values and not equal to 0, the pod is configured as _guaranteed_ +(highest priority). Guaranteed pods will not be killed unless they +exceed their configured memory limits. If the limits and requests are +configured with different values and not equal to 0, or one container +within the pod sets limits and the others don’t or have limits set for +different resources, the pods are configured as _burstable_ (medium +priority). These pods have some resource guarantees, but can be killed +once they exceed their requested memory. + +!!! Attention + +Requests don’t affect the `+memory_limit_in_bytes+` value of the +container’s cgroup; the cgroup limit is set to the amount of memory +available on the host. Nevertheless, setting the requests value too low +could cause the pod to be targeted for termination by the kubelet if the +node undergoes memory pressure. + +[width="100%",cols="<25%,<25%,<25%,<25%",options="header",] +|=== +|Class |Priority |Condition |Kill Condition +|Guaranteed |highest |limit = request != 0 |Only exceed memory limits + +|Burstable |medium |limit != request != 0 |Can be killed if exceed +request memory + +|Best-Effort |lowest |limit & request Not Set |First to get killed when +there’s insufficient memory +|=== + +For additional information about resource QoS, please refer to the +https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/[Kubernetes +documentation]. + +You can force the use of requests and limits by setting a +https://kubernetes.io/docs/concepts/policy/resource-quotas/[resource +quota] on a namespace or by creating a +https://kubernetes.io/docs/concepts/policy/limit-range/[limit range]. A +resource quota allows you to specify the total amount of resources, +e.g. CPU and RAM, allocated to a namespace. When it’s applied to a +namespace, it forces you to specify requests and limits for all +containers deployed into that namespace. By contrast, limit ranges give +you more granular control of the allocation of resources. With limit +ranges you can min/max for CPU and memory resources per pod or per +container within a namespace. You can also use them to set default +request/limit values if none are provided. + +Policy-as-code solutions can be used enforce requests and limits. or to +even create the resource quotas and limit ranges when namespaces are +created. + +==== Do not allow privileged escalation + +Privileged escalation allows a process to change the security context +under which its running. Sudo is a good example of this as are binaries +with the SUID or SGID bit. Privileged escalation is basically a way for +users to execute a file with the permissions of another user or group. +You can prevent a container from using privileged escalation by +implementing a policy-as-code mutating policy that sets +`+allowPrivilegeEscalation+` to `+false+` or by setting +`+securityContext.allowPrivilegeEscalation+` in the `+podSpec+`. +Policy-as-code policies can also be used to prevent API server requests +from succeeding if incorrect settings are detected. Pod Security +Standards can also be used to prevent pods from using privilege +escalation. + +==== Disable ServiceAccount token mounts + +For pods that do not need to access the Kubernetes API, you can disable +the automatic mounting of a ServiceAccount token on a pod spec, or for +all pods that use a particular ServiceAccount. + +!!! Attention + +Disabling ServiceAccount mounting does not prevent a pod from having +network access to the Kubernetes API. To prevent a pod from having any +network access to the Kubernetes API, you will need to modify the +https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS +cluster endpoint access] and use a +link:../network/#network-policy[NetworkPolicy] to block pod access. + +[source,yaml] +---- +apiVersion: v1 +kind: Pod +metadata: + name: pod-no-automount +spec: + automountServiceAccountToken: false +---- + +[source,yaml] +---- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: sa-no-automount +automountServiceAccountToken: false +---- + +==== Disable service discovery + +For pods that do not need to lookup or call in-cluster services, you can +reduce the amount of information given to a pod. You can set the Pod’s +DNS policy to not use CoreDNS, and not expose services in the pod’s +namespace as environment variables. See the +https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables[Kubernetes +docs on environment variables] for more information on service links. +The default value for a pod’s DNS policy is "`ClusterFirst`" which uses +in-cluster DNS, while the non-default value "`Default`" uses the +underlying node’s DNS resolution. See the +https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy[Kubernetes +docs on Pod DNS policy] for more information. + +!!! Attention + +Disabling service links and changing the pod’s DNS policy does not +prevent a pod from having network access to the in-cluster DNS service. +An attacker can still enumerate services in a cluster by reaching the +in-cluster DNS service. (ex: +`+dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP+`) To prevent +in-cluster service discovery, use a +link:../network/#network-policy[NetworkPolicy] to block pod access + +[source,yaml] +---- +apiVersion: v1 +kind: Pod +metadata: + name: pod-no-service-info +spec: + dnsPolicy: Default # "Default" is not the true default value + enableServiceLinks: false +---- + +==== Configure your images with read-only root file system + +Configuring your images with a read-only root file system prevents an +attacker from overwriting a binary on the file system that your +application uses. If your application has to write to the file system, +consider writing to a temporary directory or attach and mount a volume. +You can enforce this by setting the pod’s SecurityContext as follows: + +[source,yaml] +---- +... +securityContext: + readOnlyRootFilesystem: true +... +---- + +Policy-as-code and Pod Security Standards can be used to enforce this +behavior. + +!!! Info + +As per https://kubernetes.io/docs/concepts/windows/intro/[Windows +containers in Kubernetes] `+securityContext.readOnlyRootFilesystem+` +cannot be set to `+true+` for a container running on Windows as write +access is required for registry and system processes to run inside the +container. + +=== Tools and resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/3-pod-security[Amazon +EKS Security Immersion Workshop - Pod Security] +* https://github.com/open-policy-agent/gatekeeper-library[open-policy-agent/gatekeeper-library: +The OPA Gatekeeper policy library] a library of OPA/Gatekeeper policies +that you can use as a substitute for PSPs. +* https://kyverno.io/policies/[Kyverno Policy Library] +* A collection of common OPA and Kyverno +https://github.com/aws/aws-eks-best-practices/tree/master/policies[policies] +for EKS. +* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy +based countermeasures: part 1] +* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy +based countermeasures: part 2] +* https://appvia.github.io/psp-migration/[Pod Security Policy Migrator] +a tool that converts PSPs to OPA/Gatekeeper, KubeWarden, or Kyverno +policies +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides process and filesystem +policies as well as admission control rules. diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc new file mode 100644 index 000000000..44abaa2c8 --- /dev/null +++ b/latest/bpg/security/runtime.adoc @@ -0,0 +1,216 @@ +== Runtime security + +Runtime security provides active protection for your containers while +they’re running. The idea is to detect and/or prevent malicious activity +from occurring inside the container. This can be achieved with a number +of mechanisms in the Linux kernel or kernel extensions that are +integrated with Kubernetes, such as Linux capabilities, secure computing +(seccomp), AppArmor, or SELinux. There are also options like Amazon +GuardDuty and third party tools that can assist with establishing +baselines and detecting anomalous activity with less manual +configuration of Linux kernel mechanisms. + +!!! attention Kubernetes does not currently provide any native +mechanisms for loading seccomp, AppArmor, or SELinux profiles onto +Nodes. They either have to be loaded manually or installed onto Nodes +when they are bootstrapped. This has to be done prior to referencing +them in your Pods because the scheduler is unaware of which nodes have +profiles. See below how tools like Security Profiles Operator can help +automate provisioning of profiles onto nodes. + +=== Security contexts and built-in Kubernetes controls + +Many Linux runtime security mechanisms are tightly integrated with +Kubernetes and can be configured through Kubernetes +https://kubernetes.io/docs/tasks/configure-pod-container/security-context/[security +contexts]. One such option is the `+privileged+` flag, which is +`+false+` by default and if enabled is essentially equivalent to root on +the host. It is nearly always inappropriate to enable privileged mode in +production workloads, but there are many more controls that can provide +more granular privileges to containers as appropriate. + +==== Linux capabilities + +Linux capabilities allow you to grant certain capabilities to a Pod or +container without providing all the abilities of the root user. Examples +include `+CAP_NET_ADMIN+`, which allows configuring network interfaces +or firewalls, or `+CAP_SYS_TIME+`, which allows manipulation of the +system clock. + +==== Seccomp + +With secure computing (seccomp) you can prevent a containerized +application from making certain syscalls to the underlying host +operating system’s kernel. While the Linux operating system has a few +hundred system calls, the lion’s share of them are not necessary for +running containers. By restricting what syscalls can be made by a +container, you can effectively decrease your application’s attack +surface. + +Seccomp works by intercepting syscalls and only allowing those that have +been allowlisted to pass through. Docker has a +https://github.com/moby/moby/blob/master/profiles/seccomp/default.json[default] +seccomp profile which is suitable for a majority of general purpose +workloads, and other container runtimes like containerd provide +comparable defaults. You can configure your container or Pod to use the +container runtime’s default seccomp profile by adding the following to +the `+securityContext+` section of the Pod spec: + +[source,yaml] +---- +securityContext: + seccompProfile: + type: RuntimeDefault +---- + +As of 1.22 (in alpha, stable as of 1.27), the above `+RuntimeDefault+` +can be used for all Pods on a Node using a +https://kubernetes.io/docs/tutorials/security/seccomp/#enable-the-use-of-runtimedefault-as-the-default-seccomp-profile-for-all-workloads[single +kubelet flag], `+--seccomp-default+`. Then the profile specified in +`+securityContext+` is only needed for other profiles. + +It’s also possible to create your own profiles for things that require +additional privileges. This can be very tedious to do manually, but +there are tools like +https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget] +(also recommended in the link:../network/[network security section] for +generating network policies) and +https://github.com/inspektor-gadget/inspektor-gadget[Security Profiles +Operator] that support using tools like eBPF or logs to record baseline +privilege requirements as seccomp profiles. Security Profiles Operator +further allows automating the deployment of recorded profiles to nodes +for use by Pods and containers. + +==== AppArmor and SELinux + +AppArmor and SELinux are known as +https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access +control or MAC systems]. They are similar in concept to seccomp but with +different APIs and abilities, allowing access control for e.g. specific +filesystem paths or network ports. Support for these tools depends on +the Linux distribution, with Debian/Ubuntu supporting AppArmor and +RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see +the link:../hosts/#run-selinux[infrastructure security section] for +further discussion of SELinux. + +Both AppArmor and SELinux are integrated with Kubernetes, but as of +Kubernetes 1.28 AppArmor profiles must be specified via +https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod[annotations] +while SELinux labels can be set through the +https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#selinuxoptions-v1-core[SELinuxOptions] +field on the security context directly. + +As with seccomp profiles, the Security Profiles Operator mentioned above +can assist with deploying profiles onto nodes in the cluster. (In the +future, the project also aims to generate profiles for AppArmor and +SELinux as it does for seccomp.) + +=== Recommendations + +==== Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments + +If you do not currently have a solution for continuously monitoring EKS +runtimes and analyzing EKS audit logs, and scanning for malware and +other suspicious activity, Amazon strongly recommends the use of +https://aws.amazon.com/guardduty/[Amazon GuardDuty] for customers who +want a simple, fast, secure, scalable, and cost-effective one-click way +to protect their AWS environments. Amazon GuardDuty is a security +monitoring service that analyzes and processes foundational data +sources, such as AWS CloudTrail management events, AWS CloudTrail event +logs, VPC flow logs (from Amazon EC2 instances), Kubernetes audit logs, +and DNS logs. It also includes EKS runtime monitoring. It uses +continuously updated threat intelligence feeds, such as lists of +malicious IP addresses and domains, and machine learning to identify +unexpected, potentially unauthorized, and malicious activity within your +AWS environment. This can include issues like escalation of privileges, +use of exposed credentials, or communication with malicious IP +addresses, domains, presence of malware on your Amazon EC2 instances and +EKS container workloads, or discovery of suspicious API activity. +GuardDuty informs you of the status of your AWS environment by producing +security findings that you can view in the GuardDuty console or through +Amazon EventBridge. GuardDuty also provides support for you to export +your findings to an Amazon Simple Storage Service (S3) bucket, and +integrate with other services such as AWS Security Hub and Detective. + +Watch this AWS Online Tech Talk +https://www.youtube.com/watch?v=oNHGRRroJuE["`Enhanced threat detection +for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks`"] to see +how to enable these additional EKS security features step-by-step in +minutes. + +==== Optionally: Use a 3rd party solution for runtime monitoring + +Creating and managing seccomp and Apparmor profiles can be difficult if +you’re not familiar with Linux security. If you don’t have the time to +become proficient, consider using a 3rd party commercial solution. A lot +of them have moved beyond static profiles like Apparmor and seccomp and +have begun using machine learning to block or alert on suspicious +activity. A handful of these solutions can be found below in the +link:#tools-and-resources[tools] section. Additional options can be +found on the https://aws.amazon.com/marketplace/features/containers[AWS +Marketplace for Containers]. + +==== Consider add/dropping Linux capabilities before writing seccomp policies + +Capabilities involve various checks in kernel functions reachable by +syscalls. If the check fails, the syscall typically returns an error. +The check can be done either right at the beginning of a specific +syscall, or deeper in the kernel in areas that might be reachable +through multiple different syscalls (such as writing to a specific +privileged file). Seccomp, on the other hand, is a syscall filter which +is applied to all syscalls before they are run. A process can set up a +filter which allows them to revoke their right to run certain syscalls, +or specific arguments for certain syscalls. + +Before using seccomp, consider whether adding/removing Linux +capabilities gives you the control you need. See +https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container[Setting +capabilities for- containers] for further information. + +==== See whether you can accomplish your aims by using Pod Security Policies (PSPs) + +Pod Security Policies offer a lot of different ways to improve your +security posture without introducing undue complexity. Explore the +options available in PSPs before venturing into building seccomp and +Apparmor profiles. + +!!! warning As of Kubernetes 1.25, PSPs have been removed and replaced +with the +https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod +Security Admission] controller. Third-party alternatives which exist +include OPA/Gatekeeper and Kyverno. A collection of Gatekeeper +constraints and constraint templates for implementing policies commonly +found in PSPs can be pulled from the +https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy[Gatekeeper +library] repository on GitHub. And many replacements for PSPs can be +found in the https://main.kyverno.io/policies/[Kyverno policy library] +including the full collection of +https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod +Security Standards]. + +=== Tools and Resources + +* https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6[7 +things you should know before you start] +* https://github.com/kubernetes/kubernetes/tree/master/test/images/apparmor-loader[AppArmor +Loader] +* https://kubernetes.io/docs/tutorials/clusters/apparmor/#setting-up-nodes-with-profiles[Setting +up nodes with profiles] +* https://github.com/kubernetes-sigs/security-profiles-operator[Security +Profiles Operator] is a Kubernetes enhancement which aims to make it +easier for users to use SELinux, seccomp and AppArmor in Kubernetes +clusters. It provides capabilities for both generating profiles from +running workloads and loading profiles onto Kubernetes nodes for use in +Pods. +* https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget] +allows inspecting, tracing, and profiling many aspects of runtime +behavior on Kubernetes, including assisting in the generation of seccomp +profiles. +* https://www.aquasec.com/products/aqua-cloud-native-security-platform/[Aqua] +* https://www.qualys.com/apps/container-security/[Qualys] +* https://www.stackrox.com/use-cases/threat-detection/[Stackrox] +* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] +* https://docs.paloaltonetworks.com/cn-series[Prisma] +* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +zero-trust container security platform, provides process profile rules +and file access rules. From adec638a860142c3b241b2d8ce5da5fb32449870 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 26 Jun 2024 22:19:11 +0000 Subject: [PATCH 08/56] fixup --- latest/bpg/security/compliance.adoc | 10 +- latest/bpg/security/data.adoc | 26 +- latest/bpg/security/detective.adoc | 20 +- latest/bpg/security/hosts.adoc | 26 +- latest/bpg/security/iam.adoc | 82 +- latest/bpg/security/image.adoc | 40 +- latest/bpg/security/incidents.adoc | 36 +- latest/bpg/security/index.adoc | 43 +- latest/bpg/security/index.html | 7334 +++++++++++++++++++++++++ latest/bpg/security/multiaccount.adoc | 28 +- latest/bpg/security/multitenancy.adoc | 46 +- latest/bpg/security/network.adoc | 78 +- latest/bpg/security/pods.adoc | 52 +- latest/bpg/security/process_adoc.sh | 30 + latest/bpg/security/runtime.adoc | 22 +- 15 files changed, 7634 insertions(+), 239 deletions(-) create mode 100644 latest/bpg/security/index.html create mode 100755 latest/bpg/security/process_adoc.sh diff --git a/latest/bpg/security/compliance.adoc b/latest/bpg/security/compliance.adoc index e5a51188f..a3dbd4819 100644 --- a/latest/bpg/security/compliance.adoc +++ b/latest/bpg/security/compliance.adoc @@ -1,4 +1,4 @@ -== Compliance += Compliance Compliance is a shared responsibility between AWS and the consumers of its services. Generally speaking, AWS is responsible for "`security of @@ -68,7 +68,7 @@ practices, see the AWS whitepaper, https://d1.awsstatic.com/whitepapers/accreditation-models-for-secure-cloud-adoption.pdf[Accreditation Models for Secure Cloud Adoption] -=== Shifting Left +== Shifting Left The concept of shifting left involves catching policy violations and errors earlier in the software development lifecycle. From a security @@ -77,7 +77,7 @@ fix issues with their configuration before their application is deployed to the cluster. Catching mistakes like this earlier will help prevent configurations that violate your policies from being deployed. -==== Policy as Code +=== Policy as Code Policy can be thought of as a set of rules for governing behaviors, i.e. behaviors that are allowed or those that are prohibited. For @@ -95,7 +95,7 @@ Kubernetes clusters. Please refer to https://aws.github.io/aws-eks-best-practices/security/docs/pods/#pod-security[Pod Security] for information about PaC options and the future of PSPs. -==== Use policy-as-code tools in pipelines to detect violations before deployment +=== Use policy-as-code tools in pipelines to detect violations before deployment * https://www.openpolicyagent.org/[OPA] is an open source policy engine that’s part of the CNCF. It’s used for making policy decisions and can @@ -127,7 +127,7 @@ https://kyverno.io/policies/[Kyverno website], and for examples using the Kyverno CLI to write tests in pipelines, see the https://github.com/kyverno/policies[policies repository]. -=== Tools and resources +== Tools and resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/10-regulatory-compliance[Amazon EKS Security Immersion Workshop - Regulatory Compliance] diff --git a/latest/bpg/security/data.adoc b/latest/bpg/security/data.adoc index 10002f6d8..19e30b243 100644 --- a/latest/bpg/security/data.adoc +++ b/latest/bpg/security/data.adoc @@ -1,6 +1,6 @@ -== Data encryption and secrets management += Data encryption and secrets management -=== Encryption at rest +== Encryption at rest There are three different AWS-native storage options you can use with Kubernetes: @@ -72,12 +72,12 @@ industry-standard AES-256 cryptographic algorithm. No modifications to your application are necessary as encryption and decryption are handled seamlessly by the service. -==== Encrypt data at rest +=== Encrypt data at rest Encrypting data at rest is considered a best practice. If you’re unsure whether encryption is necessary, encrypt your data. -==== Rotate your CMKs periodically +=== Rotate your CMKs periodically Configure KMS to automatically rotate your CMKs. This will rotate your keys once a year while saving old keys indefinitely so that your data @@ -85,7 +85,7 @@ can still be decrypted. For additional information see https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html[Rotating customer master keys] -==== Use EFS access points to simplify access to shared datasets +=== Use EFS access points to simplify access to shared datasets If you have shared datasets with different POSIX file permissions or want to restrict access to part of the shared file system by creating @@ -103,7 +103,7 @@ system can have up to 120 PVs. See https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/[Introducing Amazon EFS CSI dynamic provisioning] for additional information. -=== Secrets management +== Secrets management Kubernetes secrets are used to store sensitive information, such as user certificates, passwords, or API keys. They are persisted in etcd as @@ -122,7 +122,7 @@ pods in the secret’s namespace. !!! caution The node authorizer allows the Kubelet to read all of the secrets mounted to the node. -==== Use AWS KMS for envelope encryption of Kubernetes secrets +=== Use AWS KMS for envelope encryption of Kubernetes secrets This allows you to encrypt your secrets with a unique data encryption key (DEK). The DEK is then encrypted using a key encryption key (KEK) @@ -133,7 +133,7 @@ the Kubernetes API server. For additional details, see https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/[using EKS encryption provider support for defense in depth] -==== Audit the use of Kubernetes Secrets +=== Audit the use of Kubernetes Secrets On EKS, turn on audit logging and create a CloudWatch metrics filter and alarm to alert you when a secret is used (optional). The following is an @@ -166,25 +166,25 @@ This query will display the secret, along with the namespace and username of the user who attempted to access the secret and the response code. -==== Rotate your secrets periodically +=== Rotate your secrets periodically Kubernetes doesn’t automatically rotate secrets. If you have to rotate secrets, consider using an external secret store, e.g. Vault or AWS Secrets Manager. -==== Use separate namespaces as a way to isolate secrets from different applications +=== Use separate namespaces as a way to isolate secrets from different applications If you have secrets that cannot be shared between applications in a namespace, create a separate namespace for those applications. -==== Use volume mounts instead of environment variables +=== Use volume mounts instead of environment variables The values of environment variables can unintentionally appear in logs. Secrets mounted as volumes are instantiated as tmpfs volumes (a RAM backed file system) that are automatically removed from the node when the pod is deleted. -==== Use an external secrets provider +=== Use an external secrets provider There are several viable alternatives to using Kubernetes secrets, including https://aws.amazon.com/secrets-manager/[AWS Secrets Manager] @@ -239,7 +239,7 @@ copies secrets from these backends to Kubernetes as Secrets. This lets you manage secrets using your preferred secret store and interact with secrets in a Kubernetes-native way. -=== Tools and resources +== Tools and resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/13-data-encryption-and-secret-management[Amazon EKS Security Immersion Workshop - Data Encryption and Secrets diff --git a/latest/bpg/security/detective.adoc b/latest/bpg/security/detective.adoc index be54a3515..734bb9988 100644 --- a/latest/bpg/security/detective.adoc +++ b/latest/bpg/security/detective.adoc @@ -1,4 +1,4 @@ -== Auditing and logging += Auditing and logging Collecting and analyzing [audit] logs is useful for a variety of different reasons. Logs can help with root cause analysis and @@ -158,9 +158,9 @@ rules: - "RequestReceived" ---- -=== Recommendations +== Recommendations -==== Enable audit logs +=== Enable audit logs The audit logs are part of the EKS managed Kubernetes control plane logs that are managed by EKS. Instructions for enabling/disabling the control @@ -183,21 +183,21 @@ whereas the maximum Kubernetes API request size is 1.5MiB. Log entries greater than 256KB will either be truncated or only include the request metadata. -==== Utilize audit metadata +=== Utilize audit metadata Kubernetes audit logs include two annotations that indicate whether or not a request was authorized `+authorization.k8s.io/decision+` and the reason for the decision `+authorization.k8s.io/reason+`. Use these attributes to ascertain why a particular API call was allowed. -==== Create alarms for suspicious events +=== Create alarms for suspicious events Create an alarm to automatically alert you where there is an increase in 403 Forbidden and 401 Unauthorized responses, and then use attributes like `+host+`, `+sourceIPs+`, and `+k8s_user.username+` to find out where those requests are coming from. -==== Analyze logs with Log Insights +=== Analyze logs with Log Insights Use CloudWatch Log Insights to monitor changes to RBAC objects, e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few @@ -286,7 +286,7 @@ fields @timestamp, @message, sourceIPs.0 | filter user.username="system:anonymous" and responseStatus.code in ["401", "403"] ---- -==== Audit your CloudTrail logs +=== Audit your CloudTrail logs AWS APIs called by pods that are utilizing IAM Roles for Service Accounts (IRSA) are automatically logged to CloudTrail along with the @@ -296,7 +296,7 @@ be an indication that the IAM role’s trust policy was misconfigured. Generally speaking, Cloudtrail is a great way to ascribe AWS API calls to specific IAM principals. -==== Use CloudTrail Insights to unearth suspicious activity +=== Use CloudTrail Insights to unearth suspicious activity CloudTrail insights automatically analyzes write management events from CloudTrail trails and alerts you of unusual activity. This can help you @@ -307,7 +307,7 @@ https://aws.amazon.com/blogs/aws/announcing-cloudtrail-insights-identify-and-res CloudTrail Insights: Identify and Response to Unusual API Activity] for further information. -==== Additional resources +=== Additional resources As the volume of logs increases, parsing and filtering them with Log Insights or another log analysis tool may become ineffective. As an @@ -326,7 +326,7 @@ https://docs.aws.amazon.com/sagemaker/latest/dg/randomcutforest.html[Random Cut Forest] algorithm to anomalous behaviors that warrant further investigation. -=== Tools and resources +== Tools and resources The following commercial and open source projects can be used to assess your cluster’s alignment with established best practices: diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index 7d617094f..d2f09e394 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -1,4 +1,4 @@ -== Protecting the infrastructure (hosts) += Protecting the infrastructure (hosts) Inasmuch as it’s important to secure your container images, it’s equally important to safeguard the infrastructure that runs them. This section @@ -6,9 +6,9 @@ explores different ways to mitigate risks from attacks launched directly against the host. These guidelines should be used in conjunction with those outlined in the link:runtime.md[Runtime Security] section. -=== Recommendations +== Recommendations -==== Use an OS optimized for running containers +=== Use an OS optimized for running containers Consider using Flatcar Linux, Project Atomic, RancherOS, and https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a @@ -28,7 +28,7 @@ which can be used for building a custom Amazon EKS AMI running on Red Hat Enterprise Linux using Hashicorp Packer. This script can be further leveraged to build STIG compliant EKS custom AMIs. -==== Keep your worker node OS updated +=== Keep your worker node OS updated Regardless of whether you use a container-optimized host OS like Bottlerocket or a larger, but still minimalist, Amazon Machine Image @@ -41,7 +41,7 @@ and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes channel] and automate the rollout of updated worker node images into your cluster. -==== Treat your infrastructure as immutable and automate the replacement of your worker nodes +=== Treat your infrastructure as immutable and automate the replacement of your worker nodes Rather than performing in-place upgrades, replace your workers when a new patch or update becomes available. This can be approached a couple @@ -68,7 +68,7 @@ seamlessly, but there may be times when an update will cause your pod to be rescheduled. Hence, we recommend that you create deployments with multiple replicas when running your application as a Fargate pod. -==== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] +=== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] kube-bench is an open source project from Aqua that evaluates your cluster against the CIS benchmarks for Kubernetes. The benchmark @@ -88,7 +88,7 @@ instructions] from Aqua Security. For further information see https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing The CIS Amazon EKS Benchmark]. -==== Minimize access to worker nodes +=== Minimize access to worker nodes Instead of enabling SSH access, use https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM @@ -105,7 +105,7 @@ the SSM agent with a DaemonSet as in https://github.com/aws-samples/ssm-agent-daemonset-installer[this example]. -===== Minimal IAM policy for SSM based SSH Access +==== Minimal IAM policy for SSM based SSH Access The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a number of permissions that are not required for SSM Session Manager / @@ -167,7 +167,7 @@ to access the node. https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable Session Manager logging]. -==== Deploy workers onto private subnets +=== Deploy workers onto private subnets By deploying workers onto private subnets, you minimize their exposure to the Internet where attacks often originate. Beginning April 22, 2020, @@ -177,7 +177,7 @@ nodes in a Managed Node Group were automatically assigned a public IP. If you choose to deploy your worker nodes on to public subnets, implement restrictive AWS security group rules to limit their exposure. -==== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices +=== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices You can use https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon @@ -200,9 +200,9 @@ Amazon EC2 instances]. !!! attention Inspector cannot be run on the infrastructure used to run Fargate pods. -=== Alternatives +== Alternatives -==== Run SELinux +=== Run SELinux !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, Bottlerocket, and Amazon Linux 2023 @@ -334,7 +334,7 @@ requirements of highly regulated customers, such as STIG, CJIS, and C2S. !!! caution SELinux will ignore containers where the type is unconfined. -=== Tools and resources +== Tools and resources * https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux Kubernetes RBAC and Shipping Security Policies for On-prem Applications] diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index 21c652bd8..34794e471 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -1,4 +1,4 @@ -== Identity and Access Management += Identity and Access Management https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html[Identity and Access Management] (IAM) is an AWS service that performs two @@ -16,7 +16,7 @@ are expressed as https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html[IAM policies]. -=== Controlling Access to EKS Clusters +== Controlling Access to EKS Clusters The Kubernetes project supports a variety of different strategies to authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, @@ -111,7 +111,7 @@ ClusterRoleBindings. They are similar to IAM Roles in that they define a set of actions (verbs) that can be performed against a collection of Kubernetes resources (objects). -==== Cluster Access Manager +=== Cluster Access Manager Cluster Access Manager, now the preferred way to manage access of AWS IAM principals to Amazon EKS clusters, is a functionality of the AWS API @@ -240,7 +240,7 @@ cluster creator admin permission, which is the only entry created by default. ____ -==== The `+aws-auth+` ConfigMap _(deprecated)_ +=== The `+aws-auth+` ConfigMap _(deprecated)_ One way Kubernetes integration with AWS authentication can be done is via the `+aws-auth+` ConfigMap, which resides in the `+kube-system+` @@ -310,9 +310,9 @@ Check the subsection https://aws.github.io/aws-eks-best-practices/security/docs/iam/#use-tools-to-make-changes-to-the-aws-auth-configmap[Use tools to make changes to the aws-auth ConfigMap] below for more details. -=== Cluster Access Recommendations +== Cluster Access Recommendations -==== Make the EKS Cluster Endpoint private +=== Make the EKS Cluster Endpoint private By default when you provision an EKS cluster, the API cluster endpoint is set to public, i.e. it can be accessed from the Internet. Despite @@ -337,7 +337,7 @@ the kubelets (workers) and the Kubernetes API through the cross-account ENIs that get provisioned into the cluster VPC when the control plane is provisioned. -==== Don’t use a service account token for authentication +=== Don’t use a service account token for authentication A service account token is a long-lived, static credential. If it is compromised, lost, or stolen, an attacker may be able to perform all the @@ -348,14 +348,14 @@ pipeline application. If such applications run on AWS infrastructure, like EC2 instances, consider using an instance profile and mapping that to a Kubernetes RBAC role. -==== Employ least privileged access to AWS Resources +=== Employ least privileged access to AWS Resources An IAM User does not need to be assigned privileges to AWS resources to access the Kubernetes API. If you need to grant an IAM user access to an EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user that maps to a specific Kubernetes RBAC group. -==== Remove the cluster-admin permissions from the cluster creator principal +=== Remove the cluster-admin permissions from the cluster creator principal By default Amazon EKS clusters are created with a permanent `+cluster-admin+` permission bound to the cluster creator principal. @@ -411,7 +411,7 @@ break glass scenario, or where the `+aws-auth+` ConfigMap is corrupted and the cluster is otherwise inaccessible. This can be particularly useful in production clusters. -==== Use IAM Roles when multiple users need identical access to the cluster +=== Use IAM Roles when multiple users need identical access to the cluster Rather than creating an entry for each individual IAM User, allow those users to assume an IAM Role and map that role to a Kubernetes RBAC @@ -442,7 +442,7 @@ In Kubernetes 1.20 and above, this change is no longer required, since `+user.extra.sessionName.0+` was added to the Kubernetes audit log. ____ -==== Employ least privileged access when creating RoleBindings and ClusterRoleBindings +=== Employ least privileged access when creating RoleBindings and ClusterRoleBindings Like the earlier point about granting access to AWS Resources, RoleBindings and ClusterRoleBindings should only include the set of @@ -453,7 +453,7 @@ tool like https://github.com/liggitt/audit2rbac[audit2rbac] to automatically generate Roles and binding based on the observed API calls in the Kubernetes Audit Log. -==== Create cluster using an automated process +=== Create cluster using an automated process As seen in earlier steps, when creating an Amazon EKS cluster, if not using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, @@ -474,7 +474,7 @@ should not be used to perform routine actions on the cluster, and be exclusively used to cluster level actions triggered by the pipeline, via SCM code changes for example. -==== Create the cluster with a dedicated IAM role +=== Create the cluster with a dedicated IAM role When you create an Amazon EKS cluster, the IAM entity user or role, such as a federated user that creates the cluster, is automatically @@ -491,7 +491,7 @@ scenarios where the cluster is otherwise inaccessible. This can be particularly useful in clusters which do not have direct user access configured. -==== Regularly audit access to the cluster +=== Regularly audit access to the cluster Who requires access is likely to change over time. Plan to periodically audit the `+aws-auth+` ConfigMap to see who has been granted access and @@ -504,7 +504,7 @@ link:detective.md[auditing]. Additional ideas can be found in this https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] from NCC Group. -==== If relying on `+aws-auth+` configMap use tools to make changes +=== If relying on `+aws-auth+` configMap use tools to make changes An improperly formatted aws-auth ConfigMap may cause you to lose access to the cluster. If you need to make changes to the ConfigMap, use a @@ -586,7 +586,7 @@ $ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil- ... ---- -==== Alternative Approaches to Authentication and Access Management +=== Alternative Approaches to Authentication and Access Management While IAM is the preferred way to authenticate users who need access to an EKS cluster, it is possible to use an OIDC identity provider such as @@ -621,7 +621,7 @@ current CLI session and assume an IAM role. Know that you must assume a role _prior_ to running `+kubectl+` as the IAM role is used to determine the user’s Kubernetes RBAC group. -=== Identities and Credentials for EKS pods +== Identities and Credentials for EKS pods Certain applications that run within a Kubernetes cluster need permission to call the Kubernetes API to function properly. For example, @@ -631,7 +631,7 @@ Endpoints. The controller also needs to be able to invoke AWS APIs to provision and configure an ALB. In this section we will explore the best practices for assigning rights and privileges to Pods. -==== Kubernetes Service Accounts +=== Kubernetes Service Accounts A service account is a special type of object that allows you to assign a Kubernetes RBAC role to a pod. A default service account is created @@ -715,7 +715,7 @@ references the service account such as `+metadata.annotations.kubernetes.io/service-account.name: +`. Secrets created in this way do not expire. -==== IAM Roles for Service Accounts (IRSA) +=== IAM Roles for Service Accounts (IRSA) IRSA is a feature that allows you to assign an IAM role to a Kubernetes service account. It works by leveraging a Kubernetes feature known as @@ -802,7 +802,7 @@ responsible for reloading the token when it rotates. For further information about IRSA, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html. -==== EKS Pod Identities +=== EKS Pod Identities https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS Pod Identities] is a feature launched at re:Invent 2023 that allows you @@ -837,7 +837,7 @@ https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html[cr provider chain]. Like IRSA, EKS pod identities sets variables within your pods to direct them how to find AWS credentials. -===== Working with IAM roles for EKS Pod Identities +==== Working with IAM roles for EKS Pod Identities * EKS Pod Identities can only directly assume an IAM role that belongs to the same AWS account as the EKS cluster. To access an IAM role in @@ -890,7 +890,7 @@ Organization ID of the AWS Organization that the AWS account belongs to. EKS will pass in a value for `+aws:SourceOrgId+` equal to that when assuming a role with EKS Pod Identities. -===== ABAC and EKS Pod Identities +==== ABAC and EKS Pod Identities When EKS Pod Identities assumes an IAM role, it sets the following session tags: @@ -970,7 +970,7 @@ values, where the EKS cluster is hosted in the AWS account } ---- -==== EKS Pod Identities compared to IRSA +=== EKS Pod Identities compared to IRSA Both EKS Pod Identities and IRSA are preferred ways to deliver temporary AWS credentials to your EKS pods. Unless you have specific usecases for @@ -999,9 +999,9 @@ with sts:AssumeRoleWithWebIdentity |Requires Pod Identity Agent Daemonset on nodes? |Yes |No |=== -=== Identities and Credentials for EKS pods Recommendations +== Identities and Credentials for EKS pods Recommendations -==== Update the aws-node daemonset to use IRSA +=== Update the aws-node daemonset to use IRSA At present, the aws-node daemonset is configured to use a role assigned to the EC2 instances to assign IPs to pods. This role includes several @@ -1016,7 +1016,7 @@ for this guide. The aws-node daemonset does not support EKS Pod Identities at this time. -==== Restrict access to the instance profile assigned to the worker node +=== Restrict access to the instance profile assigned to the worker node When you use IRSA or EKS Pod Identities, it updates the credential chain of the pod to use IRSA or EKS Pod Identities first, however, the pod @@ -1059,7 +1059,7 @@ If you have an application that is using an older version of the AWS SDK that doesn’t support IRSA or EKS Pod Identities, you should update the SDK version. -==== Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster +=== Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster The trust policy can be scoped to a Namespace or a specific service account within a Namespace. When using IRSA it’s best to make the role @@ -1088,7 +1088,7 @@ a given namespace from your cluster can assume that role: } ---- -==== Use one IAM role per application +=== Use one IAM role per application With both IRSA and EKS Pod Identity, it is a best practice to give each application its own IAM role. This gives you improved isolation as you @@ -1101,7 +1101,7 @@ across multiple service accounts and rely on their session attributes for access control. This is especially useful when operating at scale, as ABAC allows you to operate with fewer IAM roles. -==== When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2 +=== When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[IMDSv2] requires you use a PUT request to get a session token. The initial PUT @@ -1115,7 +1115,7 @@ IMDSv1 data flow. EKS adds support IMDSv2 by _enabling_ both v1 and v2 and changing the hop limit to 2 on nodes provisioned by eksctl or with the official CloudFormation templates. -==== Disable auto-mounting of service account tokens +=== Disable auto-mounting of service account tokens If your application doesn’t need to call the Kubernetes API set the `+automountServiceAccountToken+` attribute to `+false+` in the PodSpec @@ -1128,7 +1128,7 @@ example: kubectl patch serviceaccount default -p $'automountServiceAccountToken: false' ---- -==== Use dedicated service accounts for each application +=== Use dedicated service accounts for each application Each application should have its own dedicated service account. This applies to service accounts for the Kubernetes API as well as IRSA and @@ -1146,7 +1146,7 @@ Identity, you would create pod identity associations between the IAM roles and service accounts in the new cluster. And update the IAM role trust policy if you have a `+sourceArn+` condition. -==== Run the application as a non-root user +=== Run the application as a non-root user Containers run as root by default. While this allows them to read the web identity token file, running a container as root is not considered a @@ -1190,7 +1190,7 @@ In Kubernetes 1.19 and above, this change is no longer required and applications can read the IRSA service account token without adding them to the Nobody group. -==== Grant least privileged access to applications +=== Grant least privileged access to applications https://github.com/princespaghetti/actionhero[Action Hero] is a utility that you can run alongside your application to identify the AWS API @@ -1212,7 +1212,7 @@ permissions boundary policy, please see this https://github.com/aws-samples/example-permissions-boundary[github repo]. -==== Review and revoke unnecessary anonymous access to your EKS cluster +=== Review and revoke unnecessary anonymous access to your EKS cluster Ideally anonymous access should be disabled for all API actions. Anonymous access is granted by creating a RoleBinding or @@ -1349,7 +1349,7 @@ section in the above editor screen. Repeat the same steps for system:basic-user ClusterRoleBinding. -==== Reuse AWS SDK sessions with IRSA +=== Reuse AWS SDK sessions with IRSA When you use IRSA, applications written using the AWS SDK use the token delivered to your pods to call `+sts:AssumeRoleWithWebIdentity+` to @@ -1372,14 +1372,14 @@ with both Amazon S3 and Amazon SQS. `+AssumeRoleWithWebIdentity+` is only called once, and the AWS SDK will refresh the credentials of `+my_session+` when they expire automatically. -```py hl_lines="`4 7 8`" + +```python import boto3 -== Create your own session += Create your own session my_session = boto3.session.Session() -== Now we can create low-level clients from our session += Now we can create low-level clients from our session sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') @@ -1388,13 +1388,15 @@ s3response = s3.list_buckets() sqsresponse = sqs.list_queues() #print the response from the S3 and SQS APIs print("`s3 response:`") print(s3response) print("`—`") print("`sqs response:`") print(sqsresponse) ``` +``` + If you’re migrating an application from another AWS compute service, such as EC2, to EKS with IRSA, this is a particularly important detail. On other compute services initializing an AWS SDK session does not call AWS STS unless you instruct it to. -==== Alternative approaches +=== Alternative approaches While IRSA and EKS Pod Identities are the _preferred ways_ to assign an AWS identity to a pod, they require that you include recent version of @@ -1416,7 +1418,7 @@ If you need to use one of these non-aws provided solutions, please exercise due diligence and ensure you understand security implications of doing so. -=== Tools and Resources +== Tools and Resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon EKS Security Immersion Workshop - Identity and Access Management] diff --git a/latest/bpg/security/image.adoc b/latest/bpg/security/image.adoc index cbd675a6c..683266c84 100644 --- a/latest/bpg/security/image.adoc +++ b/latest/bpg/security/image.adoc @@ -1,4 +1,4 @@ -== Image security += Image security You should consider the container image as your first line of defense against an attack. An insecure, poorly constructed image can allow an @@ -8,9 +8,9 @@ information or move laterally within the cluster or with your AWS account. The following best practices will help mitigate risk of this happening. -=== Recommendations +== Recommendations -==== Create minimal images +=== Create minimal images Start by removing all extraneous binaries from the container image. If you’re using an unfamiliar image from Dockerhub, inspect the image using @@ -36,7 +36,7 @@ RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true Colloquially, this is known as de-fanging your image. -==== Use multi-stage builds +=== Use multi-stage builds Using multi-stage builds is a way to create minimal images. Oftentimes, multi-stage builds are used to automate parts of the Continuous @@ -52,7 +52,7 @@ additional information about multi-stage builds, see https://docs.docker.com/develop/develop-images/multistage-build/[Docker’s multi-stage builds documentation]. -==== Create Software Bill of Materials (SBOMs) for your container image +=== Create Software Bill of Materials (SBOMs) for your container image A "`software bill of materials`" (SBOM) is a nested inventory of the software artifacts that make up your container image. SBOM is a key @@ -99,7 +99,7 @@ Learn more about securing your software supply chain by reviewing https://project.linuxfoundation.org/hubfs/CNCF_SSCP_v1.pdf[CNCF Software Supply Chain Best Practices guide]. -==== Scan images for vulnerabilities regularly +=== Scan images for vulnerabilities regularly Like their virtual machine counterparts, container images can contain binaries and application libraries with vulnerabilities or develop @@ -145,7 +145,7 @@ describeImageScanFindings API to determine whether a pod is pulling an image with critical vulnerabilities. If vulnerabilities are found, the pod is rejected and a message with list of CVEs is returned as an Event. -==== Use attestations to validate artifact integrity +=== Use attestations to validate artifact integrity An attestation is a cryptographically signed "`statement`" that claims something - a "`predicate`" e.g. a pipeline run or the SBOM or the @@ -176,7 +176,7 @@ to learn more about software supply chain management best practices on AWS using open source tools with topics including creating and attaching attestations to a container image. -==== Create IAM policies for ECR repositories +=== Create IAM policies for ECR repositories Nowadays, it is not uncommon for an organization to have multiple development teams operating independently within a shared AWS account. @@ -214,7 +214,7 @@ restrict access might look like the following: } ---- -==== Consider using ECR private endpoints +=== Consider using ECR private endpoints The ECR API has a public endpoint. Consequently, ECR registries can be accessed from the Internet so long as the request has been authenticated @@ -227,7 +227,7 @@ information on this topic, see https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html[Amazon ECR interface VPC endpoints]. -==== Implement endpoint policies for ECR +=== Implement endpoint policies for ECR The default endpoint policy for allows access to all ECR repositories within a region. This might allow an attacker/insider to exfiltrate data @@ -283,7 +283,7 @@ For further information about using endpoint policies, see https://aws.amazon.com/blogs/containers/using-vpc-endpoint-policies-to-control-amazon-ecr-access/[Using VPC endpoint policies to control Amazon ECR access]. -==== Implement lifecycle policies for ECR +=== Implement lifecycle policies for ECR The https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf[NIST @@ -310,7 +310,7 @@ be sure you have good CI/CD practices in place to keep deployments and the images that they reference up to date and always create [image] expiry rules that account for how often you do releases/deployments. -==== Create a set of curated images +=== Create a set of curated images Rather than allowing developers to create their own images, consider creating a set of vetted images for the different application stacks in @@ -328,7 +328,7 @@ fifth] of the top 1000 images have vulnerabilities. A list of those images and their vulnerabilities can be found https://vulnerablecontainers.org/[here]. -==== Add the USER directive to your Dockerfiles to run as a non-root user +=== Add the USER directive to your Dockerfiles to run as a non-root user As was mentioned in the pod security section, you should avoid running container as root. While you can configure this as part of the podSpec, @@ -337,7 +337,7 @@ The `+USER+` directive sets the UID to use when running `+RUN+`, `+ENTRYPOINT+`, or `+CMD+` instruction that appears after the USER directive. -==== Lint your Dockerfiles +=== Lint your Dockerfiles Linting can be used to verify that your Dockerfiles are adhering to a set of predefined guidelines, e.g. the inclusion of the `+USER+` @@ -348,7 +348,7 @@ includes a rule engine that you can use to build your own rules for linting Dockerfiles. It can be incorporated into a CI pipeline, in that builds with Dockerfiles that violate a rule will automatically fail. -==== Build images from Scratch +=== Build images from Scratch Reducing the attack surface of your container images should be primary aim when building images. The ideal way to do this is by creating @@ -382,7 +382,7 @@ ENTRYPOINT ["/go/bin/hello"] This creates a container image that consists of your application and nothing else, making it extremely secure. -==== Use immutable tags with ECR +=== Use immutable tags with ECR https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/[Immutable tags] force you to update the image tag on each push to the image @@ -390,7 +390,7 @@ repository. This can thwart an attacker from overwriting an image with a malicious version without changing the image’s tags. Additionally, it gives you a way to easily and uniquely identify an image. -==== Sign your images, SBOMs, pipeline runs and vulnerability reports +=== Sign your images, SBOMs, pipeline runs and vulnerability reports When Docker was first introduced, there was no cryptographic model for verifying container images. With v2, Docker added digests to the image @@ -419,7 +419,7 @@ repository. In the next section we will see how to use the attested artifacts for audits and admissions controller verification. -==== Image integrity verification using Kubernetes admission controller +=== Image integrity verification using Kubernetes admission controller We can verify image signatures, attested artifacts in an automated way before deploying the image to target Kubernetes cluster using @@ -445,7 +445,7 @@ Examples of admission controller include: * https://github.com/kelseyhightower/grafeas-tutorial[Grafeas tutorial] * https://github.com/Shopify/voucher[Voucher] -==== Update the packages in your container images +=== Update the packages in your container images You should include RUN `+apt-get update && apt-get upgrade+` in your Dockerfiles to upgrade the packages in your images. Although upgrading @@ -472,7 +472,7 @@ RUN apt-get update && apt-get install -y \ && apt-get clean && rm -rf /var/lib/apt/lists/* ---- -=== Tools and resources +== Tools and resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/12-image-security[Amazon EKS Security Immersion Workshop - Image Security] diff --git a/latest/bpg/security/incidents.adoc b/latest/bpg/security/incidents.adoc index a063a89fc..c4ba64154 100644 --- a/latest/bpg/security/incidents.adoc +++ b/latest/bpg/security/incidents.adoc @@ -1,4 +1,4 @@ -== Incident response and forensics += Incident response and forensics Your ability to react quickly to an incident can help minimize damage caused from a breach. Having a reliable alerting system that can warn @@ -9,15 +9,15 @@ container. If you choose to isolate the container as part of a forensic investigation and root cause analysis, then the following set of activities should be followed: -=== Sample incident response plan +== Sample incident response plan -==== Identify the offending Pod and worker node +=== Identify the offending Pod and worker node Your first course of action should be to isolate the damage. Start by identifying where the breach occurred and isolate that Pod and its node from the rest of the infrastructure. -==== Identify the offending Pods and worker nodes using workload name +=== Identify the offending Pods and worker nodes using workload name If you know the name and namespace of the offending pod, you can identify the the worker node running the pod as follows: @@ -46,7 +46,7 @@ kubectl get pods --namespace --selector=$selector \ The above command is for deployments. You can run the same command for other workload resources such as replicasets,, statefulsets, etc. -==== Identify the offending Pods and worker nodes using service account name +=== Identify the offending Pods and worker nodes using service account name In some cases, you may identify that a service account is compromised. It is likely that pods using the identified service account are @@ -61,7 +61,7 @@ kubectl get pods -o json --namespace | \ "\(.metadata.name) \(.spec.nodeName)"' ---- -==== Identify Pods with vulnerable or compromised images and worker nodes +=== Identify Pods with vulnerable or compromised images and worker nodes In some cases, you may discover that a container image being used in pods on your cluster is malicious or compromised. A container image is @@ -81,7 +81,7 @@ kubectl get pods -o json --all-namespaces | \ "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"' ---- -==== Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod +=== Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod A deny all traffic rule may help stop an attack that is already underway by severing all connections to the pod. The following Network Policy @@ -110,7 +110,7 @@ Security Groups] to isolate a compromised host from other hosts. When changing a host’s security group, be aware that it will impact all containers running on that host. -==== Revoke temporary security credentials assigned to the pod or worker node if necessary +=== Revoke temporary security credentials assigned to the pod or worker node if necessary If the worker node has been assigned an IAM role that allows Pods to gain access to other AWS resources, remove those roles from the instance @@ -118,7 +118,7 @@ to prevent further damage from the attack. Similarly, if the Pod has been assigned an IAM role, evaluate whether you can safely remove the IAM policies from the role without impacting other workloads. -==== Cordon the worker node +=== Cordon the worker node By cordoning the impacted worker node, you’re informing the scheduler to avoid scheduling pods onto the affected node. This will allow you to @@ -129,7 +129,7 @@ pod run in its own sandboxed environment. Instead of cordoning, sequester the affected Fargate pods by applying a network policy that denies all ingress and egress traffic. -==== Enable termination protection on impacted worker node +=== Enable termination protection on impacted worker node An attacker may attempt to erase their misdeeds by terminating an affected node. Enabling @@ -140,12 +140,12 @@ scale-in protection] will protect the node from a scale-in event. !!! warning You cannot enable termination protection on a Spot instance. -==== Label the offending Pod/Node with a label indicating that it is part of an active investigation +=== Label the offending Pod/Node with a label indicating that it is part of an active investigation This will serve as a warning to cluster administrators not to tamper with the affected Pods/Nodes until the investigation is complete. -==== Capture volatile artifacts on the worker node +=== Capture volatile artifacts on the worker node * *Capture the operating system memory*. This will capture the Docker daemon (or other container runtime) and its subprocesses per container. @@ -180,7 +180,7 @@ containerd or CRI-O runtimes. * *Pause the container for forensic capture*. * *Snapshot the instance’s EBS volumes*. -==== Redeploy compromised Pod or Workload Resource +=== Redeploy compromised Pod or Workload Resource Once you have gathered data for forensic analysis, you can redeploy the compromised pod or workload resource. @@ -194,9 +194,9 @@ schedule new ones. So vulnerable pods will be launched again. In that case you should deploy a new replacement workload resource after fixing the vulnerability. Then you should delete the vulnerable workload. -=== Recommendations +== Recommendations -==== Review the AWS Security Incident Response Whitepaper +=== Review the AWS Security Incident Response Whitepaper While this section gives a brief overview along with a few recommendations for handling suspected security breaches, the topic is @@ -204,7 +204,7 @@ exhaustively covered in the white paper, https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/welcome.html[AWS Security Incident Response]. -==== Practice security game days +=== Practice security game days Divide your security practitioners into 2 teams: red and blue. The red team will be focused on probing different systems for vulnerabilities @@ -220,14 +220,14 @@ kubesploit simulates a real-world attack. This gives your blue team an opportunity to practice its response to an attack and gauge its effectiveness. -==== Run penetration tests against your cluster +=== Run penetration tests against your cluster Periodically attacking your own cluster can help you discover vulnerabilities and misconfigurations. Before getting started, follow the https://aws.amazon.com/security/penetration-testing/[penetration test guidelines] before conducting a test against your cluster. -=== Tools and resources +== Tools and resources * https://github.com/aquasecurity/kube-hunter[kube-hunter], a penetration testing tool for Kubernetes. diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index a52a9c758..420a3fb8f 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -1,4 +1,19 @@ -== Amazon EKS Best Practices Guide for Security +//!!NODE_ROOT +[[security,security.title]] += Amazon EKS Best Practices Guide for Security +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Best Practices for Security +:info_abstract: Best Practices for Security +:info_titleabbrev: Security +:imagesdir: images/ This guide provides advice about protecting information, systems, and assets that are reliant on EKS while delivering business value through @@ -8,7 +23,7 @@ customers implement EKS in accordance with best practices. Guides for Performance, Operational Excellence, Cost Optimization, and Reliability will be available in the coming months. -=== How to use this guide +== How to use this guide This guide is meant for security practitioners who are responsible for implementing and monitoring the effectiveness of security controls for @@ -18,7 +33,7 @@ brief overview, followed by a list of recommendations and best practices for securing your EKS clusters. The topics do not need to be read in a particular order. -=== Understanding the Shared Responsibility Model +== Understanding the Shared Responsibility Model Security and compliance are considered shared responsibilities when using a managed service like EKS. Generally speaking, AWS is responsible @@ -61,7 +76,7 @@ service (AWS). For additional information about the shared responsibility model, see https://aws.amazon.com/compliance/shared-responsibility-model/ -=== Introduction +== Introduction There are several security best practice areas that are pertinent when using a managed Kubernetes service like EKS: @@ -98,7 +113,7 @@ highly secure foundation, customers can spend less time on "`undifferentiated heavy lifting`" and more time on achieving their business objectives. -=== Feedback +== Feedback This guide is being released on GitHub so as to collect direct feedback and suggestions from the broader EKS/Kubernetes community. If you have a @@ -107,7 +122,7 @@ file an issue or submit a PR in the GitHub repository. Our intention is to update the guide periodically as new features are added to the service or when a new best practice evolves. -=== Further Reading +== Further Reading https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/Kubernetes%20White%20Paper.pdf[Kubernetes Security Whitepaper], sponsored by the Security Audit Working Group, @@ -121,7 +136,21 @@ paper] on cloud native security. The paper examines how the technology landscape has evolved and advocates for the adoption of security practices that align with DevOps processes and agile methodologies. -=== Tools and resources +== Tools and resources https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] + +include::iam.adoc[leveloffset=+1] +include::pods.adoc[leveloffset=+1] +include::multitenancy.adoc[leveloffset=+1] +include::detective.adoc[leveloffset=+1] +include::network.adoc[leveloffset=+1] +include::data.adoc[leveloffset=+1] +include::runtime.adoc[leveloffset=+1] +include::hosts.adoc[leveloffset=+1] +include::compliance.adoc[leveloffset=+1] +include::incidents.adoc[leveloffset=+1] +include::image.adoc[leveloffset=+1] +include::multiaccount.adoc[leveloffset=+1] + diff --git a/latest/bpg/security/index.html b/latest/bpg/security/index.html new file mode 100644 index 000000000..afb0606c0 --- /dev/null +++ b/latest/bpg/security/index.html @@ -0,0 +1,7334 @@ + + + + + + + +Amazon EKS Best Practices Guide for Security + + + + + +
+
+
+
+

This guide provides advice about protecting information, systems, and +assets that are reliant on EKS while delivering business value through +risk assessments and mitigation strategies. The guidance herein is part +of a series of best practices guides that AWS is publishing to help +customers implement EKS in accordance with best practices. Guides for +Performance, Operational Excellence, Cost Optimization, and Reliability +will be available in the coming months.

+
+
+
+
+

How to use this guide

+
+
+

This guide is meant for security practitioners who are responsible for +implementing and monitoring the effectiveness of security controls for +EKS clusters and the workloads they support. The guide is organized into +different topic areas for easier consumption. Each topic starts with a +brief overview, followed by a list of recommendations and best practices +for securing your EKS clusters. The topics do not need to be read in a +particular order.

+
+
+
+
+

Understanding the Shared Responsibility Model

+
+
+

Security and compliance are considered shared responsibilities when +using a managed service like EKS. Generally speaking, AWS is responsible +for security “of” the cloud whereas you, the customer, are responsible +for security “in” the cloud. With EKS, AWS is responsible for managing +of the EKS managed Kubernetes control plane. This includes the +Kubernetes control plane nodes, the ETCD database, and other +infrastructure necessary for AWS to deliver a secure and reliable +service. As a consumer of EKS, you are largely responsible for the +topics in this guide, e.g. IAM, pod security, runtime security, network +security, and so forth.

+
+
+

When it comes to infrastructure security, AWS will assume additional +responsibilities as you move from self-managed workers, to managed node +groups, to Fargate. For example, with Fargate, AWS becomes responsible +for securing the underlying instance/runtime used to run your Pods.

+
+
+
+Shared Responsibility Model - Fargate +
+
Figure 1. Shared Responsibility Model - Fargate
+
+
+
+
+Shared Responsibility Model - MNG +
+
Figure 2. Shared Responsibility Model - MNG
+
+
+

Before designing your system, it is important to know where the line of +demarcation is between your responsibilities and the provider of the +service (AWS).

+
+
+

For additional information about the shared responsibility model, see +https://aws.amazon.com/compliance/shared-responsibility-model/

+
+
+
+
+

Introduction

+
+
+

There are several security best practice areas that are pertinent when +using a managed Kubernetes service like EKS:

+
+
+
    +
  • +

    Identity and Access Management

    +
  • +
  • +

    Pod Security

    +
  • +
  • +

    Runtime Security

    +
  • +
  • +

    Network Security

    +
  • +
  • +

    Multi-tenancy

    +
  • +
  • +

    Multi Account for Multi-tenancy

    +
  • +
  • +

    Detective Controls

    +
  • +
  • +

    Infrastructure Security

    +
  • +
  • +

    Data Encryption and Secrets Management

    +
  • +
  • +

    Regulatory Compliance

    +
  • +
  • +

    Incident Response and Forensics

    +
  • +
  • +

    Image Security

    +
  • +
+
+
+

As part of designing any system, you need to think about its security +implications and the practices that can affect your security posture. +For example, you need to control who can perform actions against a set +of resources. You also need the ability to quickly identify security +incidents, protect your systems and services from unauthorized access, +and maintain the confidentiality and integrity of data through data +protection. Having a well-defined and rehearsed set of processes for +responding to security incidents will improve your security posture too. +These tools and techniques are important because they support objectives +such as preventing financial loss or complying with regulatory +obligations.

+
+
+

AWS helps organizations achieve their security and compliance goals by +offering a rich set of security services that have evolved based on +feedback from a broad set of security conscious customers. By offering a +highly secure foundation, customers can spend less time on +“undifferentiated heavy lifting” and more time on achieving their +business objectives.

+
+
+
+
+

Feedback

+
+
+

This guide is being released on GitHub so as to collect direct feedback +and suggestions from the broader EKS/Kubernetes community. If you have a +best practice that you feel we ought to include in the guide, please +file an issue or submit a PR in the GitHub repository. Our intention is +to update the guide periodically as new features are added to the +service or when a new best practice evolves.

+
+
+
+
+

Further Reading

+
+
+

Kubernetes +Security Whitepaper, sponsored by the Security Audit Working Group, +this Whitepaper describes key aspects of the Kubernetes attack surface +and security architecture with the aim of helping security practitioners +make sound design and implementation decisions.

+
+
+

The CNCF published also a +white +paper on cloud native security. The paper examines how the technology +landscape has evolved and advocates for the adoption of security +practices that align with DevOps processes and agile methodologies.

+
+
+
+
+

Tools and resources

+ +
+
+

Identity and Access Management

+
+
+

Identity +and Access Management (IAM) is an AWS service that performs two +essential functions: Authentication and Authorization. Authentication +involves the verification of a identity whereas authorization governs +the actions that can be performed by AWS resources. Within AWS, a +resource can be another AWS service, e.g. EC2, or an AWS +principal +such as an +IAM +User or +Role. +The rules governing the actions that a resource is allowed to perform +are expressed as +IAM +policies.

+
+
+

Controlling Access to EKS Clusters

+
+

The Kubernetes project supports a variety of different strategies to +authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, +X.509 certificates, OIDC, etc. EKS currently has native support for +webhook +token authentication, +service +account tokens, and as of February 21, 2021, OIDC authentication.

+
+
+

The webhook authentication strategy calls a webhook that verifies bearer +tokens. On EKS, these bearer tokens are generated by the AWS CLI or the +aws-iam-authenticator +client when you run kubectl commands. As you execute commands, the +token is passed to the kube-apiserver which forwards it to the +authentication webhook. If the request is well-formed, the webhook calls +a pre-signed URL embedded in the token’s body. This URL validates the +request’s signature and returns information about the user, e.g. the +user’s account, Arn, and UserId to the kube-apiserver.

+
+
+

To manually generate a authentication token, type the following command +in a terminal window:

+
+
+
+
aws eks get-token --cluster-name <cluster_name>
+
+
+
+

You can also get a token programmatically. Below is an example written +in Go:

+
+
+
+
package main
+
+import (
+  "fmt"
+  "log"
+  "sigs.k8s.io/aws-iam-authenticator/pkg/token"
+)
+
+func main()  {
+  g, _ := token.NewGenerator(false, false)
+  tk, err := g.Get("<cluster_name>")
+  if err != nil {
+    log.Fatal(err)
+  }
+  fmt.Println(tk)
+}
+
+
+
+

The output should resemble this:

+
+
+
+
{
+  "kind": "ExecCredential",
+  "apiVersion": "client.authentication.k8s.io/v1alpha1",
+  "spec": {},
+  "status": {
+    "expirationTimestamp": "2020-02-19T16:08:27Z",
+    "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz"
+  }
+}
+
+
+
+

Each token starts with k8s-aws-v1. followed by a base64 encoded +string. The string, when decoded, should resemble to something similar +to this:

+
+
+
+
https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393
+
+
+
+

The token consists of a pre-signed URL that includes an Amazon +credential and signature. For additional details see +https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html.

+
+
+

The token has a time to live (TTL) of 15 minutes after which a new token +will need to be generated. This is handled automatically when you use a +client like kubectl, however, if you’re using the Kubernetes +dashboard, you will need to generate a new token and re-authenticate +each time the token expires.

+
+
+

Once the user’s identity has been authenticated by the AWS IAM service, +the kube-apiserver reads the aws-auth ConfigMap in the +kube-system Namespace to determine the RBAC group to associate with +the user. The aws-auth ConfigMap is used to create a static mapping +between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC +groups. RBAC groups can be referenced in Kubernetes RoleBindings or +ClusterRoleBindings. They are similar to IAM Roles in that they define a +set of actions (verbs) that can be performed against a collection of +Kubernetes resources (objects).

+
+
+

Cluster Access Manager

+
+

Cluster Access Manager, now the preferred way to manage access of AWS +IAM principals to Amazon EKS clusters, is a functionality of the AWS API +and is an opt-in feature for EKS v1.23 and later clusters (new or +existing). It simplifies identity mapping between AWS IAM and Kubernetes +RBACs, eliminating the need to switch between AWS and Kubernetes APIs or +editing the aws-auth ConfigMap for access management, reducing +operational overhead, and helping address misconfigurations. The tool +also enables cluster administrators to revoke or refine +cluster-admin permissions automatically granted to the AWS IAM +principal used to create the cluster.

+
+
+

This API relies on two concepts:

+
+
+
    +
  • +

    Access Entries: A cluster identity directly linked to an AWS IAM +principal (user or role) allowed to authenticate to an Amazon EKS +cluster.

    +
  • +
  • +

    Access Policies: Are Amazon EKS specific policies that provides the +authorization for an Access Entry to perform actions in the Amazon EKS +cluster.

    +
  • +
+
+
+
+
+

At launch Amazon EKS supports only predefined and AWS managed policies. +Access policies are not IAM entities and are defined and managed by +Amazon EKS.

+
+
+
+
+

Cluster Access Manager allows the combination of upstream RBAC with +Access Policies supporting allow and pass (but not deny) on Kubernetes +AuthZ decisions regarding API server requests. A deny decision will +happen when both, the upstream RBAC and Amazon EKS authorizers can’t +determine the outcome of a request evaluation.

+
+
+

With this feature, Amazon EKS supports three modes of authentication:

+
+
+
    +
  1. +

    CONFIG_MAP to continue using aws-auth configMap exclusively.

    +
  2. +
  3. +

    API_AND_CONFIG_MAP to source authenticated IAM principals from +both EKS Access Entry APIs and the aws-auth configMap, prioritizing +the Access Entries. Ideal to migrate existing aws-auth permissions +to Access Entries.

    +
  4. +
  5. +

    API to exclusively rely on EKS Access Entry APIs. This is the new +recommended approach.

    +
  6. +
+
+
+

To get started, cluster administrators can create or update Amazon EKS +clusters, setting the preferred authentication to API_AND_CONFIG_MAP +or API method and define Access Entries to grant access the desired +AWS IAM principals.

+
+
+
+
$ aws eks create-cluster \
+    --name <CLUSTER_NAME> \
+    --role-arn <CLUSTER_ROLE_ARN> \
+    --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \
+    --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \
+    --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false
+
+
+
+

The above command is an example to create an Amazon EKS cluster already +without the admin permissions of the cluster creator.

+
+
+

It is possible to update Amazon EKS clusters configuration to enable +API authenticationMode using the update-cluster-config command, +to do that on existing clusters using CONFIG_MAP you will have to +first update to API_AND_CONFIG_MAP and then to API. These +operations cannot be reverted, meaning that’s not possible to switch +from API to API_AND_CONFIG_MAP or CONFIG_MAP, and also from +API_AND_CONFIG_MAP to CONFIG_MAP.

+
+
+
+
$ aws eks update-cluster-config \
+    --name <CLUSTER_NAME> \
+    --access-config authenticationMode=API
+
+
+
+

The API support commands to add and revoke access to the cluster, as +well as validate the existing Access Policies and Access Entries for the +specified cluster. The default policies are created to match Kubernetes +RBACs as follows.

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
EKS Access PolicyKubernetes RBAC

AmazonEKSClusterAdminPolicy

cluster-admin

AmazonEKSAdminPolicy

admin

AmazonEKSEditPolicy

edit

AmazonEKSViewPolicy

view

+
+
+
$ aws eks list-access-policies
+{
+    "accessPolicies": [
+        {
+            "name": "AmazonEKSAdminPolicy",
+            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy"
+        },
+        {
+            "name": "AmazonEKSClusterAdminPolicy",
+            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
+        },
+        {
+            "name": "AmazonEKSEditPolicy",
+            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy"
+        },
+        {
+            "name": "AmazonEKSViewPolicy",
+            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
+        }
+    ]
+}
+
+$ aws eks list-access-entries --cluster-name <CLUSTER_NAME>
+
+{
+    "accessEntries": []
+}
+
+
+
+
+
+

No Access Entries are available when the cluster is created without the +cluster creator admin permission, which is the only entry created by +default.

+
+
+
+
+
+

The aws-auth ConfigMap (deprecated)

+
+

One way Kubernetes integration with AWS authentication can be done is +via the aws-auth ConfigMap, which resides in the kube-system +Namespace. It is responsible for mapping the AWS IAM Identities (Users, +Groups, and Roles) authentication, to Kubernetes role-based access +control (RBAC) authorization. The aws-auth ConfigMap is +automatically created in your Amazon EKS cluster during its provisioning +phase. It was initially created to allow nodes to join your cluster, but +as mentioned you can also use this ConfigMap to add RBACs access to IAM +principals.

+
+
+

To check your cluster’s aws-auth ConfigMap, you can use the +following command.

+
+
+
+
kubectl -n kube-system get configmap aws-auth -o yaml
+
+
+
+

This is a sample of a default configuration of the aws-auth +ConfigMap.

+
+
+
+
apiVersion: v1
+data:
+  mapRoles: |
+    - groups:
+      - system:bootstrappers
+      - system:nodes
+      - system:node-proxier
+      rolearn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/kube-system-<SELF_GENERATED_UUID>
+      username: system:node:{{SessionName}}
+kind: ConfigMap
+metadata:
+  creationTimestamp: "2023-10-22T18:19:30Z"
+  name: aws-auth
+  namespace: kube-system
+
+
+
+

The main session of this ConfigMap, is under data in the +mapRoles block, which is basically composed by 3 parameters.

+
+
+
    +
  • +

    groups: The Kubernetes group(s) to map the IAM Role to. This can be +a default group, or a custom group specified in a clusterrolebinding +or rolebinding. In the above example we have just system groups +declared.

    +
  • +
  • +

    rolearn: The ARN of the AWS IAM Role be mapped to the Kubernetes +group(s) add, using the following format +arn:<PARTITION>:iam::<AWS_ACCOUNT_ID>:role/role-name.

    +
  • +
  • +

    username: The username within Kubernetes to map to the AWS IAM role. +This can be any custom name.

    +
  • +
+
+
+
+
+

It is also possible to map permissions for AWS IAM Users, defining a new +configuration block for mapUsers, under data in the aws-auth +ConfigMap, replacing the rolearn parameter for userarn, however as a +Best Practice it’s always recommended to user mapRoles instead.

+
+
+
+
+

To manage permissions, you can edit the aws-auth ConfigMap adding or +removing access to your Amazon EKS cluster. Although it’s possible to +edit the aws-auth ConfigMap manually, it’s recommended using tools +like eksctl, since this is a very senstitive configuration, and an +inaccurate configuration can lock you outside your Amazon EKS Cluster. +Check the subsection +Use +tools to make changes to the aws-auth ConfigMap below for more details.

+
+
+
+
+

Cluster Access Recommendations

+
+

Make the EKS Cluster Endpoint private

+
+

By default when you provision an EKS cluster, the API cluster endpoint +is set to public, i.e. it can be accessed from the Internet. Despite +being accessible from the Internet, the endpoint is still considered +secure because it requires all API requests to be authenticated by IAM +and then authorized by Kubernetes RBAC. That said, if your corporate +security policy mandates that you restrict access to the API from the +Internet or prevents you from routing traffic outside the cluster VPC, +you can:

+
+
+
    +
  • +

    Configure the EKS cluster endpoint to be private. See +Modifying +Cluster Endpoint Access for further information on this topic.

    +
  • +
  • +

    Leave the cluster endpoint public and specify which CIDR blocks can +communicate with the cluster endpoint. The blocks are effectively a +whitelisted set of public IP addresses that are allowed to access the +cluster endpoint.

    +
  • +
  • +

    Configure public access with a set of whitelisted CIDR blocks and set +private endpoint access to enabled. This will allow public access from a +specific range of public IPs while forcing all network traffic between +the kubelets (workers) and the Kubernetes API through the cross-account +ENIs that get provisioned into the cluster VPC when the control plane is +provisioned.

    +
  • +
+
+
+
+

Don’t use a service account token for authentication

+
+

A service account token is a long-lived, static credential. If it is +compromised, lost, or stolen, an attacker may be able to perform all the +actions associated with that token until the service account is deleted. +At times, you may need to grant an exception for applications that have +to consume the Kubernetes API from outside the cluster, e.g. a CI/CD +pipeline application. If such applications run on AWS infrastructure, +like EC2 instances, consider using an instance profile and mapping that +to a Kubernetes RBAC role.

+
+
+
+

Employ least privileged access to AWS Resources

+
+

An IAM User does not need to be assigned privileges to AWS resources to +access the Kubernetes API. If you need to grant an IAM user access to an +EKS cluster, create an entry in the aws-auth ConfigMap for that user +that maps to a specific Kubernetes RBAC group.

+
+
+
+

Remove the cluster-admin permissions from the cluster creator principal

+
+

By default Amazon EKS clusters are created with a permanent +cluster-admin permission bound to the cluster creator principal. +With the Cluster Access Manager API, it’s possible to create clusters +without this permission setting the +--access-config bootstrapClusterCreatorAdminPermissions to +false, when using API_AND_CONFIG_MAP or API authentication +mode. Revoke this access considered a best practice to avoid any +unwanted changes to the cluster configuration. The process to revoke +this access, follows the same process to revoke any other access to the +cluster.

+
+
+

The API gives you flexibility to only disassociate an IAM principal from +an Access Policy, in this case the AmazonEKSClusterAdminPolicy.

+
+
+
+
$ aws eks list-associated-access-policies \
+    --cluster-name <CLUSTER_NAME> \
+    --principal-arn <IAM_PRINCIPAL_ARN>
+
+$ aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \
+    --principal-arn <IAM_PRINCIPAL_ARN. \
+    --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
+
+
+
+

Or completely removing the Access Entry associated with the +cluster-admin permission.

+
+
+
+
$ aws eks list-access-entries --cluster-name <CLUSTER_NAME>
+
+{
+    "accessEntries": []
+}
+
+$ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \
+  --principal-arn <IAM_PRINCIPAL_ARN>
+
+
+
+
+
+

This access can be granted again if needed during an incident, emergency +or break glass scenario where the cluster is otherwise inaccessible.

+
+
+
+
+

If the cluster still configured with the CONFIG_MAP authentication +method, all additional users should be granted access to the cluster +through the aws-auth ConfigMap, and after aws-auth ConfigMap is +configured, the role assigned to the entity that created the cluster, +can be deleted and only recreated in case of an incident, emergency or +break glass scenario, or where the aws-auth ConfigMap is corrupted +and the cluster is otherwise inaccessible. This can be particularly +useful in production clusters.

+
+
+
+

Use IAM Roles when multiple users need identical access to the cluster

+
+

Rather than creating an entry for each individual IAM User, allow those +users to assume an IAM Role and map that role to a Kubernetes RBAC +group. This will be easier to maintain, especially as the number of +users that require access grows.

+
+
+

!!! attention When accessing the EKS cluster with the IAM entity mapped +by aws-auth ConfigMap, the username described is recorded in the +user field of the Kubernetes audit log. If you’re using an IAM role, the +actual users who assume that role aren’t recorded and can’t be audited.

+
+
+

If still using the aws-auth configMap as the authentication method, +when assigning K8s RBAC permissions to an IAM role, you should include +\{{SessionName}} in your username. That way, the audit log will record +the session name so you can track who the actual user assume this role +along with the CloudTrail log.

+
+
+
+
- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole
+  username: testRole:{{SessionName}}
+  groups:
+    - system:masters
+
+
+
+
+
+

In Kubernetes 1.20 and above, this change is no longer required, since +user.extra.sessionName.0 was added to the Kubernetes audit log.

+
+
+
+
+
+

Employ least privileged access when creating RoleBindings and ClusterRoleBindings

+
+

Like the earlier point about granting access to AWS Resources, +RoleBindings and ClusterRoleBindings should only include the set of +permissions necessary to perform a specific function. Avoid using +["*"] in your Roles and ClusterRoles unless it’s absolutely +necessary. If you’re unsure what permissions to assign, consider using a +tool like audit2rbac to +automatically generate Roles and binding based on the observed API calls +in the Kubernetes Audit Log.

+
+
+
+

Create cluster using an automated process

+
+

As seen in earlier steps, when creating an Amazon EKS cluster, if not +using the using API_AND_CONFIG_MAP or API authentication mode, +and not opting out to delegate cluster-admin permissions to the +cluster creator, the IAM entity user or role, such as a federated +user that creates the cluster, is automatically +granted system:masters permissions in the cluster’s RBAC +configuration. Even being a best practice to remove this permission, as +described +here +if using the CONFIG_MAP authentication method, relying on +aws-auth ConfigMap, this access cannot be revoked. Therefore it is a +good idea to create the cluster with an infrastructure automation +pipeline tied to dedicated IAM role, with no permissions to be assumed +by other users or entities and regularly audit this role’s permissions, +policies, and who has access to trigger the pipeline. Also, this role +should not be used to perform routine actions on the cluster, and be +exclusively used to cluster level actions triggered by the pipeline, via +SCM code changes for example.

+
+
+
+

Create the cluster with a dedicated IAM role

+
+

When you create an Amazon EKS cluster, the IAM entity user or role, such +as a federated user that creates the cluster, is automatically +granted system:masters permissions in the cluster’s RBAC +configuration. This access cannot be removed and is not managed through +the aws-auth ConfigMap. Therefore it is a good idea to create the +cluster with a dedicated IAM role and regularly audit who can assume +this role. This role should not be used to perform routine actions on +the cluster, and instead additional users should be granted access to +the cluster through the aws-auth ConfigMap for this purpose. After +the aws-auth ConfigMap is configured, the role should be secured and +only used in temporary elevated privilege mode / break glass for +scenarios where the cluster is otherwise inaccessible. This can be +particularly useful in clusters which do not have direct user access +configured.

+
+
+
+

Regularly audit access to the cluster

+
+

Who requires access is likely to change over time. Plan to periodically +audit the aws-auth ConfigMap to see who has been granted access and +the rights they’ve been assigned. You can also use open source tooling +like kubectl-who-can, +or rbac-lookup to examine +the roles bound to a particular service account, user, or group. We’ll +explore this topic further when we get to the section on +auditing. Additional ideas can be found in this +article +from NCC Group.

+
+
+
+

If relying on aws-auth configMap use tools to make changes

+
+

An improperly formatted aws-auth ConfigMap may cause you to lose access +to the cluster. If you need to make changes to the ConfigMap, use a +tool.

+
+
+

eksctl The eksctl CLI includes a command for adding identity +mappings to the aws-auth ConfigMap.

+
+
+

View CLI Help:

+
+
+
+
$ eksctl create iamidentitymapping --help
+...
+
+
+
+

Check the identities mapped to your Amazon EKS Cluster.

+
+
+
+
$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION
+ARN                                                                   USERNAME                        GROUPS                                                  ACCOUNT
+arn:aws:iam::788355785855:role/kube-system-<SELF_GENERATED_UUID>      system:node:{{SessionName}}     system:bootstrappers,system:nodes,system:node-proxier
+
+
+
+

Make an IAM Role a Cluster Admin:

+
+
+
+
$ eksctl create iamidentitymapping --cluster  <CLUSTER_NAME> --region=<region> --arn arn:aws:iam::123456:role/testing --group system:masters --username admin
+...
+
+
+
+

For more information, review +eksctl docs

+
+
+

aws-auth by keikoproj

+
+
+

aws-auth by keikoproj includes both a cli and a go library.

+
+
+

Download and view help CLI help:

+
+
+
+
$ go get github.com/keikoproj/aws-auth
+...
+$ aws-auth help
+...
+
+
+
+

Alternatively, install aws-auth with the +krew plugin manager for kubectl.

+
+
+
+
$ kubectl krew install aws-auth
+...
+$ kubectl aws-auth
+...
+
+
+
+

Review the +aws-auth docs on GitHub for more information, including the go library.

+
+ +
+

The aws-iam-authenticator project includes a CLI for updating the +ConfigMap.

+
+
+

Download +a release on GitHub.

+
+
+

Add cluster permissions to an IAM Role:

+
+
+
+
$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config
+...
+
+
+
+
+

Alternative Approaches to Authentication and Access Management

+
+

While IAM is the preferred way to authenticate users who need access to +an EKS cluster, it is possible to use an OIDC identity provider such as +GitHub using an authentication proxy and Kubernetes +impersonation. +Posts for two such solutions have been published on the AWS Open Source +blog:

+
+ +
+

!!! attention EKS natively supports OIDC authentication without using a +proxy. For further information, please read the launch blog, +Introducing +OIDC identity provider authentication for Amazon EKS. For an example +showing how to configure EKS with Dex, a popular open source OIDC +provider with connectors for a variety of different authention methods, +see +Using +Dex & dex-k8s-authenticator to authenticate to Amazon EKS. As described +in the blogs, the username/group of users authenticated by an OIDC +provider will appear in the Kubernetes audit log.

+
+
+

You can also use +AWS +SSO to federate AWS with an external identity provider, e.g. Azure AD. +If you decide to use this, the AWS CLI v2.0 includes an option to create +a named profile that makes it easy to associate an SSO session with your +current CLI session and assume an IAM role. Know that you must assume a +role prior to running kubectl as the IAM role is used to determine +the user’s Kubernetes RBAC group.

+
+
+
+
+

Identities and Credentials for EKS pods

+
+

Certain applications that run within a Kubernetes cluster need +permission to call the Kubernetes API to function properly. For example, +the AWS +Load Balancer Controller needs to be able to list a Service’s +Endpoints. The controller also needs to be able to invoke AWS APIs to +provision and configure an ALB. In this section we will explore the best +practices for assigning rights and privileges to Pods.

+
+
+

Kubernetes Service Accounts

+
+

A service account is a special type of object that allows you to assign +a Kubernetes RBAC role to a pod. A default service account is created +automatically for each Namespace within a cluster. When you deploy a pod +into a Namespace without referencing a specific service account, the +default service account for that Namespace will automatically get +assigned to the Pod and the Secret, i.e. the service account (JWT) token +for that service account, will get mounted to the pod as a volume at +/var/run/secrets/kubernetes.io/serviceaccount. Decoding the service +account token in that directory will reveal the following metadata:

+
+
+
+
{
+  "iss": "kubernetes/serviceaccount",
+  "kubernetes.io/serviceaccount/namespace": "default",
+  "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z",
+  "kubernetes.io/serviceaccount/service-account.name": "default",
+  "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba",
+  "sub": "system:serviceaccount:default:default"
+}
+
+
+
+

The default service account has the following permissions to the +Kubernetes API.

+
+
+
+
apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  annotations:
+    rbac.authorization.kubernetes.io/autoupdate: "true"
+  creationTimestamp: "2020-01-30T18:13:25Z"
+  labels:
+    kubernetes.io/bootstrapping: rbac-defaults
+  name: system:discovery
+  resourceVersion: "43"
+  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery
+  uid: 350d2ab8-438c-11ea-9438-063a49b60fba
+rules:
+- nonResourceURLs:
+  - /api
+  - /api/*
+  - /apis
+  - /apis/*
+  - /healthz
+  - /openapi
+  - /openapi/*
+  - /version
+  - /version/
+  verbs:
+  - get
+
+
+
+

This role authorizes unauthenticated and authenticated users to read API +information and is deemed safe to be publicly accessible.

+
+
+

When an application running within a Pod calls the Kubernetes APIs, the +Pod needs to be assigned a service account that explicitly grants it +permission to call those APIs. Similar to guidelines for user access, +the Role or ClusterRole bound to a service account should be restricted +to the API resources and methods that the application needs to function +and nothing else. To use a non-default service account simply set the +spec.serviceAccountName field of a Pod to the name of the service +account you wish to use. For additional information about creating +service accounts, see +https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions.

+
+
+

!!! note Prior to Kubernetes 1.24, Kubernetes would automatically create +a secret for each a service account. This secret was mounted to the pod +at /var/run/secrets/kubernetes.io/serviceaccount and would be used by +the pod to authenticate to the Kubernetes API server. In Kubernetes +1.24, a service account token is dynamically generated when the pod runs +and is only valid for an hour by default. A secret for the service +account will not be created. If you have an application that runs +outside the cluster that needs to authenticate to the Kubernetes API, +e.g. Jenkins, you will need to create a secret of type +kubernetes.io/service-account-token along with an annotation that +references the service account such as +metadata.annotations.kubernetes.io/service-account.name: <SERVICE_ACCOUNT_NAME>. +Secrets created in this way do not expire.

+
+
+
+

IAM Roles for Service Accounts (IRSA)

+
+

IRSA is a feature that allows you to assign an IAM role to a Kubernetes +service account. It works by leveraging a Kubernetes feature known as +Service +Account Token Volume Projection. When Pods are configured with a +Service Account that references an IAM Role, the Kubernetes API server +will call the public OIDC discovery endpoint for the cluster on startup. +The endpoint cryptographically signs the OIDC token issued by Kubernetes +and the resulting token mounted as a volume. This signed token allows +the Pod to call the AWS APIs associated IAM role. When an AWS API is +invoked, the AWS SDKs calls sts:AssumeRoleWithWebIdentity. After +validating the token’s signature, IAM exchanges the Kubernetes issued +token for a temporary AWS role credential.

+
+
+

When using IRSA, it is important to +reuse AWS SDK sessions to avoid +unneeded calls to AWS STS.

+
+
+

Decoding the (JWT) token for IRSA will produce output similar to the +example you see below:

+
+
+
+
{
+  "aud": [
+    "sts.amazonaws.com"
+  ],
+  "exp": 1582306514,
+  "iat": 1582220114,
+  "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128",
+  "kubernetes.io": {
+    "namespace": "default",
+    "pod": {
+      "name": "alpine-57b5664646-rf966",
+      "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436"
+    },
+    "serviceaccount": {
+      "name": "s3-read-only",
+      "uid": "a720ba5c-5406-11ea-9438-063a49b60fba"
+    }
+  },
+  "nbf": 1582220114,
+  "sub": "system:serviceaccount:default:s3-read-only"
+}
+
+
+
+

This particular token grants the Pod view-only privileges to S3 by +assuming an IAM role. When the application attempts to read from S3, the +token is exchanged for a temporary set of IAM credentials that resembles +this:

+
+
+
+
{
+    "AssumedRoleUser": {
+        "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc",
+        "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc"
+    },
+    "Audience": "sts.amazonaws.com",
+    "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128",
+    "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only",
+    "Credentials": {
+        "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1",
+        "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=",
+        "Expiration": "2020-02-20T18:49:50Z",
+        "AccessKeyId": "XXXX36C6WWEJUMHA3L7Z"
+    }
+}
+
+
+
+

A mutating webhook that runs as part of the EKS control plane injects +the AWS Role ARN and the path to a web identity token file into the Pod +as environment variables. These values can also be supplied manually.

+
+
+
+
AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME
+AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
+
+
+
+

The kubelet will automatically rotate the projected token when it is +older than 80% of its total TTL, or after 24 hours. The AWS SDKs are +responsible for reloading the token when it rotates. For further +information about IRSA, see +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html.

+
+
+
+

EKS Pod Identities

+
+

EKS +Pod Identities is a feature launched at re:Invent 2023 that allows you +to assign an IAM role to a kubernetes service account, without the need +to configure an Open Id Connect (OIDC) identity provider(IDP) for each +cluster in your AWS account. To use EKS Pod Identity, you must deploy an +agent which runs as a DaemonSet pod on every eligible worker node. This +agent is made available to you as an EKS Add-on and is a pre-requisite +to use EKS Pod Identity feature. Your applications must use a +supported +version of the AWS SDK to use this feature.

+
+
+

When EKS Pod Identities are configured for a Pod, EKS will mount and +refresh a pod identity token at +/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token. +This token will be used by the AWS SDK to communicate with the EKS Pod +Identity Agent, which uses the pod identity token and the agent’s IAM +role to create temporary credentials for your pods by calling the +AssumeRoleForPodIdentity +API. The pod identity token delivered to your pods is a JWT issued from +your EKS cluster and cryptographically signed, with appropriate JWT +claims for use with EKS Pod Identities.

+
+
+

To learn more about EKS Pod Identities, please see +this +blog.

+
+
+

You do not have to make any modifications to your application code to +use EKS Pod Identities. Supported AWS SDK versions will automatically +discover credentials made available with EKS Pod Identities by using the +credential +provider chain. Like IRSA, EKS pod identities sets variables within +your pods to direct them how to find AWS credentials.

+
+
+
Working with IAM roles for EKS Pod Identities
+
+
    +
  • +

    EKS Pod Identities can only directly assume an IAM role that belongs +to the same AWS account as the EKS cluster. To access an IAM role in +another AWS account, you must assume that role by +configuring +a profile in your SDK configuration, or in your +application’s +code.

    +
  • +
  • +

    When EKS Pod Identities are being configured for Service Accounts, the +person or process configuring the Pod Identity Association must have the +iam:PassRole entitlement for that role.

    +
  • +
  • +

    Each Service Account may only have one IAM role associated with it +through EKS Pod Identities, however you can associate the same IAM role +with multiple service accounts.

    +
  • +
  • +

    IAM roles used with EKS Pod Identities must allow the +pods.eks.amazonaws.com Service Principal to assume them, and set +session tags. The following is an example role trust policy which allows +EKS Pod Identities to use an IAM role:

    +
  • +
+
+
+
+
{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Effect": "Allow",
+      "Principal": {
+        "Service": "pods.eks.amazonaws.com"
+      },
+      "Action": [
+        "sts:AssumeRole",
+        "sts:TagSession"
+      ],
+      "Condition": {
+        "StringEquals": {
+          "aws:SourceOrgId": "${aws:ResourceOrgId}"
+        }
+      }
+    }
+  ]
+}
+
+
+
+

AWS recommends using condition keys like aws:SourceOrgId to help +protect against the +cross-service +confused deputy problem. In the above example role trust policy, the +ResourceOrgId is a variable equal to the AWS Organizations +Organization ID of the AWS Organization that the AWS account belongs to. +EKS will pass in a value for aws:SourceOrgId equal to that when +assuming a role with EKS Pod Identities.

+
+
+
+
ABAC and EKS Pod Identities
+
+

When EKS Pod Identities assumes an IAM role, it sets the following +session tags:

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EKS Pod Identities Session TagValue

kubernetes-namespace

The namespace the pod associated with EKS Pod +Identities runs in.

kubernetes-service-account

The name of the kubernetes service account +associated with EKS Pod Identities

eks-cluster-arn

The ARN of the EKS cluster, +e.g. arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}. +The cluster ARN is unique, but if a cluster is deleted and recreated in +the same region with the same name, within the same AWS account, it will +have the same ARN.

eks-cluster-name

The name of the EKS cluster. Please note that EKS +cluster names can be same within your AWS account, and EKS clusters in +other AWS accounts.

kubernetes-pod-name

The name of the pod in EKS.

kubernetes-pod-uid

The UID of the pod in EKS.

+
+

These session tags allow you to use +Attribute +Based Access Control(ABAC) to grant access to your AWS resources to +only specific kubernetes service accounts. When doing so, it is very +important to understand that kubernetes service accounts are only +unique within a namespace, and kubernetes namespaces are only unique +within an EKS cluster. These session tags can be accessed in AWS +policies by using the aws:PrincipalTag/<tag-key> global condition +key, such as aws:PrincipalTag/eks-cluster-arn

+
+
+

For example, if you wanted to grant access to only a specific service +account to access an AWS resource in your account with an IAM or +resource policy, you would need to check eks-cluster-arn and +kubernetes-namespace tags as well as the +kubernetes-service-account to ensure that only that service accounts +from the intended cluster have access to that resource as other clusters +could have identical kubernetes-service-accounts and +kubernetes-namespaces.

+
+
+

This example S3 Bucket policy only grants access to objects in the S3 +bucket it’s attached to, only if kubernetes-service-account, +kubernetes-namespace, eks-cluster-arn all meet their expected +values, where the EKS cluster is hosted in the AWS account +111122223333.

+
+
+
+
{
+    "Version": "2012-10-17",
+    "Statement": [
+        {
+            "Effect": "Allow",
+            "Principal": {
+                "AWS": "arn:aws:iam::111122223333:root"
+            },
+            "Action": "s3:*",
+            "Resource":            [
+                "arn:aws:s3:::ExampleBucket/*"
+            ],
+            "Condition": {
+                "StringEquals": {
+                    "aws:PrincipalTag/kubernetes-service-account": "s3objectservice",
+                    "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster",
+                    "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace"
+                }
+            }
+        }
+    ]
+}
+
+
+
+
+
+

EKS Pod Identities compared to IRSA

+
+

Both EKS Pod Identities and IRSA are preferred ways to deliver temporary +AWS credentials to your EKS pods. Unless you have specific usecases for +IRSA, we recommend you use EKS Pod Identities when using EKS. This table +helps compare the two features.

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#EKS Pod IdentitiesIRSA

Requires permission to create an OIDC IDP in your AWS accounts?

No

Yes

Requires unique IDP setup per cluster

No

Yes

Sets relevant session tags for use with ABAC

Yes

No

Requires an iam:PassRole Check?

Yes

No

Uses AWS STS Quota from your AWS account?

No

Yes

Can access other AWS accounts

Indirectly with role chaining

Directly +with sts:AssumeRoleWithWebIdentity

Compatible with AWS SDKs

Yes

Yes

Requires Pod Identity Agent Daemonset on nodes?

Yes

No

+
+
+
+

Identities and Credentials for EKS pods Recommendations

+
+

Update the aws-node daemonset to use IRSA

+
+

At present, the aws-node daemonset is configured to use a role assigned +to the EC2 instances to assign IPs to pods. This role includes several +AWS managed policies, e.g. AmazonEKS_CNI_Policy and +EC2ContainerRegistryReadOnly that effectively allow all pods running +on a node to attach/detach ENIs, assign/unassign IP addresses, or pull +images from ECR. Since this presents a risk to your cluster, it is +recommended that you update the aws-node daemonset to use IRSA. A script +for doing this can be found in the +repository +for this guide.

+
+
+

The aws-node daemonset does not support EKS Pod Identities at this time.

+
+
+
+

Restrict access to the instance profile assigned to the worker node

+
+

When you use IRSA or EKS Pod Identities, it updates the credential chain +of the pod to use IRSA or EKS Pod Identities first, however, the pod +can still inherit the rights of the instance profile assigned to the +worker node. When using IRSA or EKS Pod Identities, it is strongly +recommended that you block access +instance +metadata to help ensure that your applications only have the +permissions they require, and not their nodes.

+
+
+

!!! caution Blocking access to instance metadata will prevent pods that +do not use IRSA or EKS Pod Identities from inheriting the role assigned +to the worker node.

+
+
+

You can block access to instance metadata by requiring the instance to +use IMDSv2 only and updating the hop count to 1 as in the example below. +You can also include these settings in the node group’s launch template. +Do not disable instance metadata as this will prevent components like +the node termination handler and other things that rely on instance +metadata from working properly.

+
+
+
+
$ aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1
+...
+
+
+
+

If you are using Terraform to create launch templates for use with +Managed Node Groups, add the metadata block to configure the hop count +as seen in this code snippet:

+
+
+

tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...

+
+
+

You can also block a pod’s access to EC2 metadata by manipulating +iptables on the node. For further information about this method, see +Limiting +access to the instance metadata service.

+
+
+

If you have an application that is using an older version of the AWS SDK +that doesn’t support IRSA or EKS Pod Identities, you should update the +SDK version.

+
+
+
+

Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster

+
+

The trust policy can be scoped to a Namespace or a specific service +account within a Namespace. When using IRSA it’s best to make the role +trust policy as explicit as possible by including the service account +name. This will effectively prevent other Pods within the same Namespace +from assuming the role. The CLI eksctl will do this automatically +when you use it to create service accounts/IAM roles. See +https://eksctl.io/usage/iamserviceaccounts/ for further information.

+
+
+

When working with IAM directly, this is adding condition into the role’s +trust policy that uses conditions to ensure the :sub claim are the +namespace and service account you expect. As an example, before we had +an IRSA token with a sub claim of +“system:serviceaccount:default:s3-read-only” . This is the default +namespace and the service account is s3-read-only. You would use a +condition like the following to ensure that only your service account in +a given namespace from your cluster can assume that role:

+
+
+
+
  "Condition": {
+      "StringEquals": {
+          "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com",
+          "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only"
+      }
+  }
+
+
+
+
+

Use one IAM role per application

+
+

With both IRSA and EKS Pod Identity, it is a best practice to give each +application its own IAM role. This gives you improved isolation as you +can modify one application without impacting another, and allows you to +apply the principal of least privilege by only granting an application +the permissions it needs.

+
+
+

When using ABAC with EKS Pod Identity, you may use a common IAM role +across multiple service accounts and rely on their session attributes +for access control. This is especially useful when operating at scale, +as ABAC allows you to operate with fewer IAM roles.

+
+
+
+

When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2

+
+

IMDSv2 +requires you use a PUT request to get a session token. The initial PUT +request has to include a TTL for the session token. Newer versions of +the AWS SDKs will handle this and the renewal of said token +automatically. It’s also important to be aware that the default hop +limit on EC2 instances is intentionally set to 1 to prevent IP +forwarding. As a consequence, Pods that request a session token that are +run on EC2 instances may eventually time out and fallback to using the +IMDSv1 data flow. EKS adds support IMDSv2 by enabling both v1 and v2 +and changing the hop limit to 2 on nodes provisioned by eksctl or with +the official CloudFormation templates.

+
+
+
+

Disable auto-mounting of service account tokens

+
+

If your application doesn’t need to call the Kubernetes API set the +automountServiceAccountToken attribute to false in the PodSpec +for your application or patch the default service account in each +namespace so that it’s no longer mounted to pods automatically. For +example:

+
+
+
+
kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'
+
+
+
+
+

Use dedicated service accounts for each application

+
+

Each application should have its own dedicated service account. This +applies to service accounts for the Kubernetes API as well as IRSA and +EKS Pod Identity.

+
+
+

!!! attention If you employ a blue/green approach to cluster upgrades +instead of performing an in-place cluster upgrade when using IRSA, you +will need to update the trust policy of each of the IRSA IAM roles with +the OIDC endpoint of the new cluster. A blue/green cluster upgrade is +where you create a cluster running a newer version of Kubernetes +alongside the old cluster and use a load balancer or a service mesh to +seamlessly shift traffic from services running on the old cluster to the +new cluster. When using blue/green cluster upgrades with EKS Pod +Identity, you would create pod identity associations between the IAM +roles and service accounts in the new cluster. And update the IAM role +trust policy if you have a sourceArn condition.

+
+
+
+

Run the application as a non-root user

+
+

Containers run as root by default. While this allows them to read the +web identity token file, running a container as root is not considered a +best practice. As an alternative, consider adding the +spec.securityContext.runAsUser attribute to the PodSpec. The value +of runAsUser is arbitrary value.

+
+
+

In the following example, all processes within the Pod will run under +the user ID specified in the runAsUser field.

+
+
+
+
apiVersion: v1
+kind: Pod
+metadata:
+  name: security-context-demo
+spec:
+  securityContext:
+    runAsUser: 1000
+    runAsGroup: 3000
+  containers:
+  - name: sec-ctx-demo
+    image: busybox
+    command: [ "sh", "-c", "sleep 1h" ]
+
+
+
+

When you run a container as a non-root user, it prevents the container +from reading the IRSA service account token because the token is +assigned 0600 [root] permissions by default. If you update the +securityContext for your container to include fsgroup=65534 [Nobody] it +will allow the container to read the token.

+
+
+
+
spec:
+  securityContext:
+    fsGroup: 65534
+
+
+
+

In Kubernetes 1.19 and above, this change is no longer required and +applications can read the IRSA service account token without adding them +to the Nobody group.

+
+
+
+

Grant least privileged access to applications

+
+

Action Hero is a utility +that you can run alongside your application to identify the AWS API +calls and corresponding IAM permissions your application needs to +function properly. It is similar to +IAM +Access Advisor in that it helps you gradually limit the scope of IAM +roles assigned to applications. Consult the documentation on granting +least +privileged access to AWS resources for further information.

+
+
+

Consider setting a +permissions +boundary on IAM roles used with IRSA and Pod Identities. You can use +the permissions boundary to ensure that the roles used by IRSA or Pod +Identities can not exceed a maximum level of permissions. For an example +guide on getting started with permissions boundaries with an example +permissions boundary policy, please see this +github +repo.

+
+
+
+

Review and revoke unnecessary anonymous access to your EKS cluster

+
+

Ideally anonymous access should be disabled for all API actions. +Anonymous access is granted by creating a RoleBinding or +ClusterRoleBinding for the Kubernetes built-in user system:anonymous. +You can use the rbac-lookup +tool to identify permissions that system:anonymous user has on your +cluster:

+
+
+
+
./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)'
+system:anonymous               cluster-wide        ClusterRole/system:discovery
+system:unauthenticated         cluster-wide        ClusterRole/system:discovery
+system:unauthenticated         cluster-wide        ClusterRole/system:public-info-viewer
+
+
+
+

Any role or ClusterRole other than system:public-info-viewer should not +be bound to system:anonymous user or system:unauthenticated group.

+
+
+

There may be some legitimate reasons to enable anonymous access on +specific APIs. If this is the case for your cluster ensure that only +those specific APIs are accessible by anonymous user and exposing those +APIs without authentication doesn’t make your cluster vulnerable.

+
+
+

Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was +associated to system:discovery and system:basic-user ClusterRoles by +default. Note that even if you have updated your cluster to version 1.14 +or higher, these permissions may still be enabled on your cluster, since +cluster updates do not revoke these permissions. To check which +ClusterRoles have “system:unauthenticated” except +system:public-info-viewer you can run the following command (requires jq +util):

+
+
+
+
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name'
+
+
+
+

And “system:unauthenticated” can be removed from all the roles except +“system:public-info-viewer” using:

+
+
+
+
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f -
+
+
+
+

Alternatively, you can check and remove it manually by kubectl describe +and kubectl edit. To check if system:unauthenticated group has +system:discovery permissions on your cluster run the following command:

+
+
+
+
kubectl describe clusterrolebindings system:discovery
+
+Name:         system:discovery
+Labels:       kubernetes.io/bootstrapping=rbac-defaults
+Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
+Role:
+  Kind:  ClusterRole
+  Name:  system:discovery
+Subjects:
+  Kind   Name                    Namespace
+  ----   ----                    ---------
+  Group  system:authenticated
+  Group  system:unauthenticated
+
+
+
+

To check if system:unauthenticated group has system:basic-user +permission on your cluster run the following command:

+
+
+
+
kubectl describe clusterrolebindings system:basic-user
+
+Name:         system:basic-user
+Labels:       kubernetes.io/bootstrapping=rbac-defaults
+Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
+Role:
+  Kind:  ClusterRole
+  Name:  system:basic-user
+Subjects:
+  Kind   Name                    Namespace
+  ----   ----                    ---------
+  Group  system:authenticated
+  Group  system:unauthenticated
+
+
+
+

If system:unauthenticated group is bound to system:discovery and/or +system:basic-user ClusterRoles on your cluster, you should disassociate +these roles from system:unauthenticated group. Edit system:discovery +ClusterRoleBinding using the following command:

+
+
+
+
kubectl edit clusterrolebindings system:discovery
+
+
+
+

The above command will open the current definition of system:discovery +ClusterRoleBinding in an editor as shown below:

+
+
+
+
# Please edit the object below. Lines beginning with a '#' will be ignored,
+# and an empty file will abort the edit. If an error occurs while saving this file will be
+# reopened with the relevant failures.
+#
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  annotations:
+    rbac.authorization.kubernetes.io/autoupdate: "true"
+  creationTimestamp: "2021-06-17T20:50:49Z"
+  labels:
+    kubernetes.io/bootstrapping: rbac-defaults
+  name: system:discovery
+  resourceVersion: "24502985"
+  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery
+  uid: b7936268-5043-431a-a0e1-171a423abeb6
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: system:discovery
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: Group
+  name: system:authenticated
+- apiGroup: rbac.authorization.k8s.io
+  kind: Group
+  name: system:unauthenticated
+
+
+
+

Delete the entry for system:unauthenticated group from the “subjects” +section in the above editor screen.

+
+
+

Repeat the same steps for system:basic-user ClusterRoleBinding.

+
+
+
+

Reuse AWS SDK sessions with IRSA

+
+

When you use IRSA, applications written using the AWS SDK use the token +delivered to your pods to call sts:AssumeRoleWithWebIdentity to +generate temporary AWS credentials. This is different from other AWS +compute services, where the compute service delivers temporary AWS +credentials directly to the AWS compute resource, such as a lambda +function. This means that every time an AWS SDK session is initialized, +a call to AWS STS for AssumeRoleWithWebIdentity is made. If your +application scales rapidly and initializes many AWS SDK sessions, you +may experience throttling from AWS STS as your code will be making many +calls for AssumeRoleWithWebIdentity.

+
+
+

To avoid this scenario, we recommend reusing AWS SDK sessions within +your application so that unnecessary calls to +AssumeRoleWithWebIdentity are not made.

+
+
+

In the following example code, a session is created using the boto3 +python SDK, and that same session is used to create clients and interact +with both Amazon S3 and Amazon SQS. AssumeRoleWithWebIdentity is +only called once, and the AWS SDK will refresh the credentials of +my_session when they expire automatically.

+
+
+
+
import boto3
+
+= Create your own session
+
+my_session = boto3.session.Session()
+
+= Now we can create low-level clients from our session
+
+sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`')
+
+s3response = s3.list_buckets() sqsresponse = sqs.list_queues()
+
+#print the response from the S3 and SQS APIs print("`s3 response:`")
+print(s3response) print("`—`") print("`sqs response:`")
+print(sqsresponse) ```
+
+If you’re migrating an application from another AWS compute service,
+such as EC2, to EKS with IRSA, this is a particularly important detail.
+On other compute services initializing an AWS SDK session does not call
+AWS STS unless you instruct it to.
+
+=== Alternative approaches
+
+While IRSA and EKS Pod Identities are the _preferred ways_ to assign an
+AWS identity to a pod, they require that you include recent version of
+the AWS SDKs in your application. For a complete listing of the SDKs
+that currently support IRSA, see
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html,
+for EKS Pod Identities, see
+https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html.
+If you have an application that you can’t immediately update with a
+compatible SDK, there are several community-built solutions available
+for assigning IAM roles to Kubernetes pods, including
+https://github.com/jtblin/kube2iam[kube2iam] and
+https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse,
+condone, nor support the use of these solutions, they are frequently
+used by the community at large to achieve similar results as IRSA and
+EKS Pod Identities.
+
+If you need to use one of these non-aws provided solutions, please
+exercise due diligence and ensure you understand security implications
+of doing so.
+
+== Tools and Resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon
+EKS Security Immersion Workshop - Identity and Access Management]
+* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/fully-private-cluster[Terraform
+EKS Blueprints Pattern - Fully Private Amazon EKS Cluster]
+* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-iam-identity-center[Terraform
+EKS Blueprints Pattern - IAM Identity Center Single Sign-On for Amazon
+EKS Cluster]
+* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-okta[Terraform
+EKS Blueprints Pattern - Okta Single Sign-On for Amazon EKS Cluster]
+* https://github.com/liggitt/audit2rbac[audit2rbac]
+* https://github.com/mhausenblas/rbac.dev[rbac.dev] A list of additional
+resources, including blogs and tools, for Kubernetes RBAC
+* https://github.com/princespaghetti/actionhero[Action Hero]
+* https://github.com/jtblin/kube2iam[kube2iam]
+* https://github.com/uswitch/kiam[kiam]
+
+:leveloffset!:
+:leveloffset: +1
+
+= Pod Security
+
+The pod specification includes a variety of different attributes that
+can strengthen or weaken your overall security posture. As a Kubernetes
+practitioner your chief concern should be preventing a process that’s
+running in a container from escaping the isolation boundaries of the
+container runtime and gaining access to the underlying host.
+
+== Linux Capabilities
+
+The processes that run within a container run under the context of the
+[Linux] root user by default. Although the actions of root within a
+container are partially constrained by the set of Linux capabilities
+that the container runtime assigns to the containers, these default
+privileges could allow an attacker to escalate their privileges and/or
+gain access to sensitive information bound to the host, including
+Secrets and ConfigMaps. Below is a list of the default capabilities
+assigned to containers. For additional information about each
+capability, see
+http://man7.org/linux/man-pages/man7/capabilities.7.html.
+
+`+CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT+`
+
+!!! Info
+
+EC2 and Fargate pods are assigned the aforementioned capabilities by
+default. Additionally, Linux capabilities can only be dropped from
+Fargate pods.
+
+Pods that are run as privileged, inherit _all_ of the Linux capabilities
+associated with root on the host. This should be avoided if possible.
+
+=== Node Authorization
+
+All Kubernetes worker nodes use an authorization mode called
+https://kubernetes.io/docs/reference/access-authn-authz/node/[Node
+Authorization]. Node Authorization authorizes all API requests that
+originate from the kubelet and allows nodes to perform the following
+actions:
+
+Read operations:
+
+* services
+* endpoints
+* nodes
+* pods
+* secrets, configmaps, persistent volume claims and persistent volumes
+related to pods bound to the kubelet’s node
+
+Write operations:
+
+* nodes and node status (enable the `+NodeRestriction+` admission plugin
+to limit a kubelet to modify its own node)
+* pods and pod status (enable the `+NodeRestriction+` admission plugin
+to limit a kubelet to modify pods bound to itself)
+* events
+
+Auth-related operations:
+
+* Read/write access to the CertificateSigningRequest (CSR) API for TLS
+bootstrapping
+* the ability to create TokenReview and SubjectAccessReview for
+delegated authentication/authorization checks
+
+EKS uses the
+https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[node
+restriction admission controller] which only allows the node to modify a
+limited set of node attributes and pod objects that are bound to the
+node. Nevertheless, an attacker who manages to get access to the host
+will still be able to glean sensitive information about the environment
+from the Kubernetes API that could allow them to move laterally within
+the cluster.
+
+== Pod Security Solutions
+
+=== Pod Security Policy (PSP)
+
+In the past,
+https://kubernetes.io/docs/concepts/policy/pod-security-policy/[Pod
+Security Policy (PSP)] resources were used to specify a set of
+requirements that pods had to meet before they could be created. As of
+Kubernetes version 1.21, PSP have been deprecated. They are scheduled
+for removal in Kubernetes version 1.25.
+
+!!! Attention
+
+https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/[PSPs
+are deprecated] in Kubernetes version 1.21. You will have until version
+1.25 or roughly 2 years to transition to an alternative. This
+https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation[document]
+explains the motivation for this deprecation.
+
+=== Migrating to a new pod security solution
+
+Since PSPs have been removed as of Kubernetes v1.25, cluster
+administrators and operators must replace those security controls. Two
+solutions can fill this need:
+
+* Policy-as-code (PAC) solutions from the Kubernetes ecosystem
+* Kubernetes
+https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod
+Security Standards (PSS)]
+
+Both the PAC and PSS solutions can coexist with PSP; they can be used in
+clusters before PSP is removed. This eases adoption when migrating from
+PSP. Please see this
+https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/[document]
+when considering migrating from PSP to PSS.
+
+Kyverno, one of the PAC solutions outlined below, has specific guidance
+outlined in a
+https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/[blog
+post] when migrating from PSPs to its solution including analogous
+policies, feature comparisons, and a migration procedure. Additional
+information and guidance on migration to Kyverno with respect to Pod
+Security Admission (PSA) has been published on the AWS blog
+https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/[here].
+
+=== Policy-as-code (PAC)
+
+Policy-as-code (PAC) solutions provide guardrails to guide cluster
+users, and prevent unwanted behaviors, through prescribed and automated
+controls. PAC uses
+https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/[Kubernetes
+Dynamic Admission Controllers] to intercept the Kubernetes API server
+request flow, via a webhook call, and mutate and validate request
+payloads, based on policies written and stored as code. Mutation and
+validation happens before the API server request results in a change to
+the cluster. PAC solutions use policies to match and act on API server
+request payloads, based on taxonomy and values.
+
+There are several open source PAC solutions available for Kubernetes.
+These solutions are not part of the Kubernetes project; they are sourced
+from the Kubernetes ecosystem. Some PAC solutions are listed below.
+
+* https://open-policy-agent.github.io/gatekeeper/website/docs/[OPA/Gatekeeper]
+* https://www.openpolicyagent.org/[Open Policy Agent (OPA)]
+* https://kyverno.io/[Kyverno]
+* https://www.kubewarden.io/[Kubewarden]
+* https://www.jspolicy.com/[jsPolicy]
+
+For further information about PAC solutions and how to help you select
+the appropriate solution for your needs, see the links below.
+
+* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy-based
+countermeasures for Kubernetes – Part 1]
+* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy-based
+countermeasures for Kubernetes – Part 2]
+
+=== Pod Security Standards (PSS) and Pod Security Admission (PSA)
+
+In response to the PSP deprecation and the ongoing need to control pod
+security out-of-the-box, with a built-in Kubernetes solution, the
+Kubernetes
+https://github.com/kubernetes/community/tree/master/sig-auth[Auth
+Special Interest Group] created the
+https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod
+Security Standards (PSS)] and
+https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod
+Security Admission (PSA)]. The PSA effort includes an
+https://github.com/kubernetes/pod-security-admission#pod-security-admission[admission
+controller webhook project] that implements the controls defined in the
+PSS. This admission controller approach resembles that used in the PAC
+solutions.
+
+According to the Kubernetes documentation, the PSS _"`define three
+different policies to broadly cover the security spectrum. These
+policies are cumulative and range from highly-permissive to
+highly-restrictive.`"_
+
+These policies are defined as:
+
+* *Privileged:* Unrestricted (unsecure) policy, providing the widest
+possible level of permissions. This policy allows for known privilege
+escalations. It is the absence of a policy. This is good for
+applications such as logging agents, CNIs, storage drivers, and other
+system wide applications that need privileged access.
+* *Baseline:* Minimally restrictive policy which prevents known
+privilege escalations. Allows the default (minimally specified) Pod
+configuration. The baseline policy prohibits use of hostNetwork,
+hostPID, hostIPC, hostPath, hostPort, the inability to add Linux
+capabilities, along with several other restrictions.
+* *Restricted:* Heavily restricted policy, following current Pod
+hardening best practices. This policy inherits from the baseline and
+adds further restrictions such as the inability to run as root or a
+root-group. Restricted policies may impact an application’s ability to
+function. They are primarily targeted at running security critical
+applications.
+
+These policies define
+https://kubernetes.io/docs/concepts/security/pod-security-standards/#profile-details[profiles
+for pod execution], arranged into three levels of privileged
+vs. restricted access.
+
+To implement the controls defined by the PSS, PSA operates in three
+modes:
+
+* *enforce:* Policy violations will cause the pod to be rejected.
+* *audit:* Policy violations will trigger the addition of an audit
+annotation to the event recorded in the audit log, but are otherwise
+allowed.
+* *warn:* Policy violations will trigger a user-facing warning, but are
+otherwise allowed.
+
+These modes and the profile (restriction) levels are configured at the
+Kubernetes Namespace level, using labels, as seen in the below example.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: policy-test
+  labels:
+    pod-security.kubernetes.io/enforce: restricted
+----
+
+When used independently, these operational modes have different
+responses that result in different user experiences. The _enforce_ mode
+will prevent pods from being created if respective podSpecs violate the
+configured restriction level. However, in this mode, non-pod Kubernetes
+objects that create pods, such as Deployments, will not be prevented
+from being applied to the cluster, even if the podSpec therein violates
+the applied PSS. In this case the Deployment will be applied, while the
+pod(s) will be prevented from being applied.
+
+This is a difficult user experience, as there is no immediate indication
+that the successfully applied Deployment object belies failed pod
+creation. The offending podSpecs will not create pods. Inspecting the
+Deployment resource with `+kubectl get deploy <DEPLOYMENT_NAME> -oyaml+`
+will expose the message from the failed pod(s) `+.status.conditions+`
+element, as seen below.
+
+[source,yaml]
+----
+...
+status:
+  conditions:
+    - lastTransitionTime: "2022-01-20T01:02:08Z"
+      lastUpdateTime: "2022-01-20T01:02:08Z"
+      message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest":
+        allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false),
+        unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]),
+        runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true),
+        seccompProfile (pod or container "test" must set securityContext.seccompProfile.type
+        to "RuntimeDefault" or "Localhost")'
+      reason: FailedCreate
+      status: "True"
+      type: ReplicaFailure
+...
+----
+
+In both the _audit_ and _warn_ modes, the pod restrictions do not
+prevent violating pods from being created and started. However, in these
+modes audit annotations on API server audit log events and warnings to
+API server clients, such as _kubectl_, are triggered, respectively, when
+pods, as well as objects that create pods, contain podSpecs with
+violations. A `+kubectl+` _Warning_ message is seen below.
+
+[source,bash]
+----
+Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
+deployment.apps/test created
+----
+
+The PSA _audit_ and _warn_ modes are useful when introducing the PSS
+without negatively impacting cluster operations.
+
+The PSA operational modes are not mutually exclusive, and can be used in
+a cumulative manner. As seen below, the multiple modes can be configured
+in a single namespace.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: policy-test
+  labels:
+    pod-security.kubernetes.io/audit: restricted
+    pod-security.kubernetes.io/enforce: restricted
+    pod-security.kubernetes.io/warn: restricted
+----
+
+In the above example, the user-friendly warnings and audit annotations
+are provided when applying Deployments, while the enforce of violations
+are also provided at the pod level. In fact multiple PSA labels can use
+different profile levels, as seen below.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: policy-test
+  labels:
+    pod-security.kubernetes.io/enforce: baseline
+    pod-security.kubernetes.io/warn: restricted
+----
+
+In the above example, PSA is configured to allow the creation of all
+pods that satisfy the _baseline_ profile level, and then _warn_ on pods
+(and objects that create pods) that violate the _restricted_ profile
+level. This is a useful approach to determine the possible impacts when
+changing from the _baseline_ to _restricted_ profiles.
+
+==== Existing Pods
+
+If a namespace with existing pods is modified to use a more restrictive
+PSS profile, the _audit_ and _warn_ modes will produce appropriate
+messages; however, _enforce_ mode will not delete the pods. The warning
+messages are seen below.
+
+[source,bash]
+----
+Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest"
+Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
+namespace/policy-test configured
+----
+
+==== Exemptions
+
+PSA uses _Exemptions_ to exclude enforcement of violations against pods
+that would have otherwise been applied. These exemptions are listed
+below.
+
+* *Usernames:* requests from users with an exempt authenticated (or
+impersonated) username are ignored.
+* *RuntimeClassNames:* pods and workload resources specifying an exempt
+runtime class name are ignored.
+* *Namespaces:* pods and workload resources in an exempt namespace are
+ignored.
+
+These exemptions are applied statically in the
+https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller[PSA
+admission controller configuration] as part of the API server
+configuration.
+
+In the _Validating Webhook_ implementation the exemptions can be
+configured within a Kubernetes
+https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/20-configmap.yaml[ConfigMap]
+resource that gets mounted as a volume into the
+https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/50-deployment.yaml[pod-security-webhook]
+container.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: pod-security-webhook
+  namespace: pod-security-webhook
+data:
+  podsecurityconfiguration.yaml: |
+    apiVersion: pod-security.admission.config.k8s.io/v1
+    kind: PodSecurityConfiguration
+    defaults:
+      enforce: "restricted"
+      enforce-version: "latest"
+      audit: "restricted"
+      audit-version: "latest"
+      warn: "restricted"
+      warn-version: "latest"
+    exemptions:
+      # Array of authenticated usernames to exempt.
+      usernames: []
+      # Array of runtime class names to exempt.
+      runtimeClasses: []
+      # Array of namespaces to exempt.
+      namespaces: ["kube-system","policy-test1"]
+----
+
+As seen in the above ConfigMap YAML the cluster-wide default PSS level
+has been set to _restricted_ for all PSA modes, _audit_, _enforce_, and
+_warn_. This affects all namespaces, except those exempted:
+`+namespaces: ["kube-system","policy-test1"]+`. Additionally, in the
+_ValidatingWebhookConfiguration_ resource, seen below, the
+_pod-security-webhook_ namespace is also exempted from configured PSS.
+
+[source,yaml]
+----
+...
+webhooks:
+  # Audit annotations will be prefixed with this name
+  - name: "pod-security-webhook.kubernetes.io"
+    # Fail-closed admission webhooks can present operational challenges.
+    # You may want to consider using a failure policy of Ignore, but should
+    # consider the security tradeoffs.
+    failurePolicy: Fail
+    namespaceSelector:
+      # Exempt the webhook itself to avoid a circular dependency.
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: ["pod-security-webhook"]
+...
+----
+
+!!! Attention
+
+Pod Security Admissions graduated to stable in Kubernetes v1.25. If you
+wanted to use the Pod Security Admission feature prior to it being
+enabled by default, you needed to install the dynamic admission
+controller (mutating webhook). The instructions for installing and
+configuring the webhook can be found
+https://github.com/kubernetes/pod-security-admission/tree/master/webhook[here].
+
+=== Choosing between policy-as-code and Pod Security Standards
+
+The Pod Security Standards (PSS) were developed to replace the Pod
+Security Policy (PSP), by providing a solution that was built-in to
+Kubernetes and did not require solutions from the Kubernetes ecosystem.
+That being said, policy-as-code (PAC) solutions are considerably more
+flexible.
+
+The following list of Pros and Cons is designed help you make a more
+informed decision about your pod security solution.
+
+==== Policy-as-code (as compared to Pod Security Standards)
+
+Pros:
+
+* More flexible and more granular (down to attributes of resources if
+need be)
+* Not just focused on pods, can be used against different resources and
+actions
+* Not just applied at the namespace level
+* More mature than the Pod Security Standards
+* Decisions can be based on anything in the API server request payload,
+as well as existing cluster resources and external data (solution
+dependent)
+* Supports mutating API server requests before validation (solution
+dependent)
+* Can generate complementary policies and Kubernetes resources (solution
+dependent - From pod policies, Kyverno can
+https://kyverno.io/docs/writing-policies/autogen/[auto-gen] policies for
+higher-level controllers, such as Deployments. Kyverno can also generate
+additional Kubernetes resources _"`when a new resource is created or
+when the source is updated`"_ by using
+https://kyverno.io/docs/writing-policies/generate/[Generate Rules].)
+* Can be used to shift left, into CICD pipelines, before making calls to
+the Kubernetes API server (solution dependent)
+* Can be used to implement behaviors that are not necessarily security
+related, such as best practices, organizational standards, etc.
+* Can be used in non-Kubernetes use cases (solution dependent)
+* Because of flexibility, the user experience can be tuned to users’
+needs
+
+Cons:
+
+* Not built into Kubernetes
+* More complex to learn, configure, and support
+* Policy authoring may require new skills/languages/capabilities
+
+==== Pod Security Admission (as compared to policy-as-code)
+
+Pros:
+
+* Built into Kubernetes
+* Simpler to configure
+* No new languages to use or policies to author
+* If the cluster default admission level is configured to _privileged_,
+namespace labels can be used to opt namespaces into the pod security
+profiles.
+
+Cons:
+
+* Not as flexible or granular as policy-as-code
+* Only 3 levels of restrictions
+* Primarily focused on pods
+
+==== Summary
+
+If you currently do not have a pod security solution, beyond PSP, and
+your required pod security posture fits the model defined in the Pod
+Security Standards (PSS), then an easier path may be to adopt the PSS,
+in lieu of a policy-as-code solution. However, if your pod security
+posture does not fit the PSS model, or you envision adding additional
+controls, beyond that defined by PSS, then a policy-as-code solution
+would seem a better fit.
+
+== Recommendations
+
+=== Use multiple Pod Security Admission (PSA) modes for a better user experience
+
+As mentioned earlier, PSA _enforce_ mode prevents pods with PSS
+violations from being applied, but does not stop higher-level
+controllers, such as Deployments. In fact, the Deployment will be
+applied successfully without any indication that the pods failed to be
+applied. While you can use _kubectl_ to inspect the Deployment object,
+and discover the failed pods message from the PSA, the user experience
+could be better. To make the user experience better, multiple PSA modes
+(audit, enforce, warn) should be used.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: policy-test
+  labels:
+    pod-security.kubernetes.io/audit: restricted
+    pod-security.kubernetes.io/enforce: restricted
+    pod-security.kubernetes.io/warn: restricted
+----
+
+In the above example, with _enforce_ mode defined, when a Deployment
+manifest with PSS violations in the respective podSpec is attempted to
+be applied to the Kubernetes API server, the Deployment will be
+successfully applied, but the pods will not. And, since the _audit_ and
+_warn_ modes are also enabled, the API server client will receive a
+warning message and the API server audit log event will be annotated
+with a message as well.
+
+=== Restrict the containers that can run as privileged
+
+As mentioned, containers that run as privileged inherit all of the Linux
+capabilities assigned to root on the host. Seldom do containers need
+these types of privileges to function properly. There are multiple
+methods that can be used to restrict the permissions and capabilities of
+containers.
+
+!!! Attention
+
+Fargate is a launch type that enables you to run "`serverless`"
+container(s) where the containers of a pod are run on infrastructure
+that AWS manages. With Fargate, you cannot run a privileged container or
+configure your pod to use hostNetwork or hostPort.
+
+=== Do not run processes in containers as root
+
+All containers run as root by default. This could be problematic if an
+attacker is able to exploit a vulnerability in the application and get
+shell access to the running container. You can mitigate this risk a
+variety of ways. First, by removing the shell from the container image.
+Second, adding the USER directive to your Dockerfile or running the
+containers in the pod as a non-root user. The Kubernetes podSpec
+includes a set of fields, under `+spec.securityContext+`, that let you
+specify the user and/or group under which to run your application. These
+fields are `+runAsUser+` and `+runAsGroup+` respectively.
+
+To enforce the use of the `+spec.securityContext+`, and its associated
+elements, within the Kubernetes podSpec, policy-as-code or Pod Security
+Standards can be added to clusters. These solutions allow you to write
+and/or use policies or profiles that can validate inbound Kubernetes API
+server request payloads, before they are persisted into etcd.
+Furthermore, policy-as-code solutions can mutate inbound requests, and
+in some cases, generate new requests.
+
+=== Never run Docker in Docker or mount the socket in the container
+
+While this conveniently lets you to build/run images in Docker
+containers, you’re basically relinquishing complete control of the node
+to the process running in the container. If you need to build container
+images on Kubernetes use
+https://github.com/GoogleContainerTools/kaniko[Kaniko],
+https://github.com/containers/buildah[buildah], or a build service like
+https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html[CodeBuild]
+instead.
+
+!!! Tip
+
+Kubernetes clusters used for CICD processing, such as building container
+images, should be isolated from clusters running more generalized
+workloads.
+
+=== Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only
+
+`+hostPath+` is a volume that mounts a directory from the host directly
+to the container. Rarely will pods need this type of access, but if they
+do, you need to be aware of the risks. By default pods that run as root
+will have write access to the file system exposed by hostPath. This
+could allow an attacker to modify the kubelet settings, create symbolic
+links to directories or files not directly exposed by the hostPath,
+e.g. /etc/shadow, install ssh keys, read secrets mounted to the host,
+and other malicious things. To mitigate the risks from hostPath,
+configure the `+spec.containers.volumeMounts+` as `+readOnly+`, for
+example:
+
+[source,yaml]
+----
+volumeMounts:
+- name: hostPath-volume
+    readOnly: true
+    mountPath: /host-path
+----
+
+You should also use policy-as-code solutions to restrict the directories
+that can be used by `+hostPath+` volumes, or prevent `+hostPath+` usage
+altogether. You can use the Pod Security Standards _Baseline_ or
+_Restricted_ policies to prevent the use of `+hostPath+`.
+
+For further information about the dangers of privileged escalation, read
+Seth Art’s blog
+https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation[Bad
+Pods: Kubernetes Pod Privilege Escalation].
+
+=== Set requests and limits for each container to avoid resource contention and DoS attacks
+
+A pod without requests or limits can theoretically consume all of the
+resources available on a host. As additional pods are scheduled onto a
+node, the node may experience CPU or memory pressure which can cause the
+Kubelet to terminate or evict pods from the node. While you can’t
+prevent this from happening all together, setting requests and limits
+will help minimize resource contention and mitigate the risk from poorly
+written applications that consume an excessive amount of resources.
+
+The `+podSpec+` allows you to specify requests and limits for CPU and
+memory. CPU is considered a compressible resource because it can be
+oversubscribed. Memory is incompressible, i.e. it cannot be shared among
+multiple containers.
+
+When you specify _requests_ for CPU or memory, you’re essentially
+designating the amount of _memory_ that containers are guaranteed to
+get. Kubernetes aggregates the requests of all the containers in a pod
+to determine which node to schedule the pod onto. If a container exceeds
+the requested amount of memory it may be subject to termination if
+there’s memory pressure on the node.
+
+_Limits_ are the maximum amount of CPU and memory resources that a
+container is allowed to consume and directly corresponds to the
+`+memory.limit_in_bytes+` value of the cgroup created for the container.
+A container that exceeds the memory limit will be OOM killed. If a
+container exceeds its CPU limit, it will be throttled.
+
+!!! Tip
+
+When using container `+resources.limits+` it is strongly recommended
+that container resource usage (a.k.a. Resource Footprints) be
+data-driven and accurate, based on load testing. Absent an accurate and
+trusted resource footprint, container `+resources.limits+` can be
+padded. For example, `+resources.limits.memory+` could be padded 20-30%
+higher than observable maximums, to account for potential memory
+resource limit inaccuracies.
+
+Kubernetes uses three Quality of Service (QoS) classes to prioritize the
+workloads running on a node. These include:
+
+* guaranteed
+* burstable
+* best-effort
+
+If limits and requests are not set, the pod is configured as
+_best-effort_ (lowest priority). Best-effort pods are the first to get
+killed when there is insufficient memory. If limits are set on _all_
+containers within the pod, or if the requests and limits are set to the
+same values and not equal to 0, the pod is configured as _guaranteed_
+(highest priority). Guaranteed pods will not be killed unless they
+exceed their configured memory limits. If the limits and requests are
+configured with different values and not equal to 0, or one container
+within the pod sets limits and the others don’t or have limits set for
+different resources, the pods are configured as _burstable_ (medium
+priority). These pods have some resource guarantees, but can be killed
+once they exceed their requested memory.
+
+!!! Attention
+
+Requests don’t affect the `+memory_limit_in_bytes+` value of the
+container’s cgroup; the cgroup limit is set to the amount of memory
+available on the host. Nevertheless, setting the requests value too low
+could cause the pod to be targeted for termination by the kubelet if the
+node undergoes memory pressure.
+
+[width="100%",cols="<25%,<25%,<25%,<25%",options="header",]
+|===
+|Class |Priority |Condition |Kill Condition
+|Guaranteed |highest |limit = request != 0 |Only exceed memory limits
+
+|Burstable |medium |limit != request != 0 |Can be killed if exceed
+request memory
+
+|Best-Effort |lowest |limit & request Not Set |First to get killed when
+there’s insufficient memory
+|===
+
+For additional information about resource QoS, please refer to the
+https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/[Kubernetes
+documentation].
+
+You can force the use of requests and limits by setting a
+https://kubernetes.io/docs/concepts/policy/resource-quotas/[resource
+quota] on a namespace or by creating a
+https://kubernetes.io/docs/concepts/policy/limit-range/[limit range]. A
+resource quota allows you to specify the total amount of resources,
+e.g. CPU and RAM, allocated to a namespace. When it’s applied to a
+namespace, it forces you to specify requests and limits for all
+containers deployed into that namespace. By contrast, limit ranges give
+you more granular control of the allocation of resources. With limit
+ranges you can min/max for CPU and memory resources per pod or per
+container within a namespace. You can also use them to set default
+request/limit values if none are provided.
+
+Policy-as-code solutions can be used enforce requests and limits. or to
+even create the resource quotas and limit ranges when namespaces are
+created.
+
+=== Do not allow privileged escalation
+
+Privileged escalation allows a process to change the security context
+under which its running. Sudo is a good example of this as are binaries
+with the SUID or SGID bit. Privileged escalation is basically a way for
+users to execute a file with the permissions of another user or group.
+You can prevent a container from using privileged escalation by
+implementing a policy-as-code mutating policy that sets
+`+allowPrivilegeEscalation+` to `+false+` or by setting
+`+securityContext.allowPrivilegeEscalation+` in the `+podSpec+`.
+Policy-as-code policies can also be used to prevent API server requests
+from succeeding if incorrect settings are detected. Pod Security
+Standards can also be used to prevent pods from using privilege
+escalation.
+
+=== Disable ServiceAccount token mounts
+
+For pods that do not need to access the Kubernetes API, you can disable
+the automatic mounting of a ServiceAccount token on a pod spec, or for
+all pods that use a particular ServiceAccount.
+
+!!! Attention
+
+Disabling ServiceAccount mounting does not prevent a pod from having
+network access to the Kubernetes API. To prevent a pod from having any
+network access to the Kubernetes API, you will need to modify the
+https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS
+cluster endpoint access] and use a
+link:../network/#network-policy[NetworkPolicy] to block pod access.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-no-automount
+spec:
+  automountServiceAccountToken: false
+----
+
+[source,yaml]
+----
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: sa-no-automount
+automountServiceAccountToken: false
+----
+
+=== Disable service discovery
+
+For pods that do not need to lookup or call in-cluster services, you can
+reduce the amount of information given to a pod. You can set the Pod’s
+DNS policy to not use CoreDNS, and not expose services in the pod’s
+namespace as environment variables. See the
+https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables[Kubernetes
+docs on environment variables] for more information on service links.
+The default value for a pod’s DNS policy is "`ClusterFirst`" which uses
+in-cluster DNS, while the non-default value "`Default`" uses the
+underlying node’s DNS resolution. See the
+https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy[Kubernetes
+docs on Pod DNS policy] for more information.
+
+!!! Attention
+
+Disabling service links and changing the pod’s DNS policy does not
+prevent a pod from having network access to the in-cluster DNS service.
+An attacker can still enumerate services in a cluster by reaching the
+in-cluster DNS service. (ex:
+`+dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP+`) To prevent
+in-cluster service discovery, use a
+link:../network/#network-policy[NetworkPolicy] to block pod access
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-no-service-info
+spec:
+    dnsPolicy: Default # "Default" is not the true default value
+    enableServiceLinks: false
+----
+
+=== Configure your images with read-only root file system
+
+Configuring your images with a read-only root file system prevents an
+attacker from overwriting a binary on the file system that your
+application uses. If your application has to write to the file system,
+consider writing to a temporary directory or attach and mount a volume.
+You can enforce this by setting the pod’s SecurityContext as follows:
+
+[source,yaml]
+----
+...
+securityContext:
+  readOnlyRootFilesystem: true
+...
+----
+
+Policy-as-code and Pod Security Standards can be used to enforce this
+behavior.
+
+!!! Info
+
+As per https://kubernetes.io/docs/concepts/windows/intro/[Windows
+containers in Kubernetes] `+securityContext.readOnlyRootFilesystem+`
+cannot be set to `+true+` for a container running on Windows as write
+access is required for registry and system processes to run inside the
+container.
+
+== Tools and resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/3-pod-security[Amazon
+EKS Security Immersion Workshop - Pod Security]
+* https://github.com/open-policy-agent/gatekeeper-library[open-policy-agent/gatekeeper-library:
+The OPA Gatekeeper policy library] a library of OPA/Gatekeeper policies
+that you can use as a substitute for PSPs.
+* https://kyverno.io/policies/[Kyverno Policy Library]
+* A collection of common OPA and Kyverno
+https://github.com/aws/aws-eks-best-practices/tree/master/policies[policies]
+for EKS.
+* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy
+based countermeasures: part 1]
+* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy
+based countermeasures: part 2]
+* https://appvia.github.io/psp-migration/[Pod Security Policy Migrator]
+a tool that converts PSPs to OPA/Gatekeeper, KubeWarden, or Kyverno
+policies
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides process and filesystem
+policies as well as admission control rules.
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Tenant Isolation
+
+When we think of multi-tenancy, we often want to isolate a user or
+application from other users or applications running on a shared
+infrastructure.
+
+Kubernetes is a _single tenant orchestrator_, i.e. a single instance of
+the control plane is shared among all the tenants within a cluster.
+There are, however, various Kubernetes objects that you can use to
+create the semblance of multi-tenancy. For example, Namespaces and
+Role-based access controls (RBAC) can be implemented to logically
+isolate tenants from each other. Similarly, Quotas and Limit Ranges can
+be used to control the amount of cluster resources each tenant can
+consume. Nevertheless, the cluster is the only construct that provides a
+strong security boundary. This is because an attacker that manages to
+gain access to a host within the cluster can retrieve _all_ Secrets,
+ConfigMaps, and Volumes, mounted on that host. They could also
+impersonate the Kubelet which would allow them to manipulate the
+attributes of the node and/or move laterally within the cluster.
+
+The following sections will explain how to implement tenant isolation
+while mitigating the risks of using a single tenant orchestrator like
+Kubernetes.
+
+== Soft multi-tenancy
+
+With soft multi-tenancy, you use native Kubernetes constructs,
+e.g. namespaces, roles and role bindings, and network policies, to
+create logical separation between tenants. RBAC, for example, can
+prevent tenants from accessing or manipulate each other’s resources.
+Quotas and limit ranges control the amount of cluster resources each
+tenant can consume while network policies can help prevent applications
+deployed into different namespaces from communicating with each other.
+
+None of these controls, however, prevent pods from different tenants
+from sharing a node. If stronger isolation is required, you can use a
+node selector, anti-affinity rules, and/or taints and tolerations to
+force pods from different tenants to be scheduled onto separate nodes;
+often referred to as _sole tenant nodes_. This could get rather
+complicated, and cost prohibitive, in an environment with many tenants.
+
+!!! attention Soft multi-tenancy implemented with Namespaces does not
+allow you to provide tenants with a filtered list of Namespaces because
+Namespaces are a globally scoped Type. If a tenant has the ability to
+view a particular Namespace, it can view all Namespaces within the
+cluster.
+
+!!! warning With soft-multi-tenancy, tenants retain the ability to query
+CoreDNS for all services that run within the cluster by default. An
+attacker could exploit this by running dig SRV `+*.*.svc.cluster.local+`
+from any pod in the cluster. If you need to restrict access to DNS
+records of services that run within your clusters, consider using the
+Firewall or Policy plugins for CoreDNS. For additional information, see
+https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy.
+
+https://github.com/kiosk-sh/kiosk[Kiosk] is an open source project that
+can aid in the implementation of soft multi-tenancy. It is implemented
+as a series of CRDs and controllers that provide the following
+capabilities:
+
+* *Accounts & Account Users* to separate tenants in a shared Kubernetes
+cluster
+* *Self-Service Namespace Provisioning* for account users
+* *Account Limits* to ensure quality of service and fairness when
+sharing a cluster
+* *Namespace Templates* for secure tenant isolation and self-service
+namespace initialization
+
+https://loft.sh[Loft] is a commercial offering from the maintainers of
+Kiosk and https://github.com/devspace-cloud/devspace[DevSpace] that adds
+the following capabilities:
+
+* *Multi-cluster access* for granting access to spaces in different
+clusters
+* *Sleep mode* scales down deployments in a space during periods of
+inactivity
+* *Single sign-on* with OIDC authentication providers like GitHub
+
+There are three primary use cases that can be addressed by soft
+multi-tenancy.
+
+=== Enterprise Setting
+
+The first is in an Enterprise setting where the "`tenants`" are
+semi-trusted in that they are employees, contractors, or are otherwise
+authorized by the organization. Each tenant will typically align to an
+administrative division such as a department or team.
+
+In this type of setting, a cluster administrator will usually be
+responsible for creating namespaces and managing policies. They may also
+implement a delegated administration model where certain individuals are
+given oversight of a namespace, allowing them to perform CRUD operations
+for non-policy related objects like deployments, services, pods, jobs,
+etc.
+
+The isolation provided by a container runtime may be acceptable within
+this setting or it may need to be augmented with additional controls for
+pod security. It may also be necessary to restrict communication between
+services in different namespaces if stricter isolation is required.
+
+=== Kubernetes as a Service
+
+By contrast, soft multi-tenancy can be used in settings where you want
+to offer Kubernetes as a service (KaaS). With KaaS, your application is
+hosted in a shared cluster along with a collection of controllers and
+CRDs that provide a set of PaaS services. Tenants interact directly with
+the Kubernetes API server and are permitted to perform CRUD operations
+on non-policy objects. There is also an element of self-service in that
+tenants may be allowed to create and manage their own namespaces. In
+this type of environment, tenants are assumed to be running untrusted
+code.
+
+To isolate tenants in this type of environment, you will likely need to
+implement strict network policies as well as _pod sandboxing_.
+Sandboxing is where you run the containers of a pod inside a micro VM
+like Firecracker or in a user-space kernel. Today, you can create
+sandboxed pods with EKS Fargate.
+
+=== Software as a Service (SaaS)
+
+The final use case for soft multi-tenancy is in a Software-as-a-Service
+(SaaS) setting. In this environment, each tenant is associated with a
+particular _instance_ of an application that’s running within the
+cluster. Each instance often has its own data and uses separate access
+controls that are usually independent of Kubernetes RBAC.
+
+Unlike the other use cases, the tenant in a SaaS setting does not
+directly interface with the Kubernetes API. Instead, the SaaS
+application is responsible for interfacing with the Kubernetes API to
+create the necessary objects to support each tenant.
+
+== Kubernetes Constructs
+
+In each of these instances the following constructs are used to isolate
+tenants from each other:
+
+=== Namespaces
+
+Namespaces are fundamental to implementing soft multi-tenancy. They
+allow you to divide the cluster into logical partitions. Quotas, network
+policies, service accounts, and other objects needed to implement
+multi-tenancy are scoped to a namespace.
+
+=== Network policies
+
+By default, all pods in a Kubernetes cluster are allowed to communicate
+with each other. This behavior can be altered using network policies.
+
+Network policies restrict communication between pods using labels or IP
+address ranges. In a multi-tenant environment where strict network
+isolation between tenants is required, we recommend starting with a
+default rule that denies communication between pods, and another rule
+that allows all pods to query the DNS server for name resolution. With
+that in place, you can begin adding more permissive rules that allow for
+communication within a namespace. This can be further refined as
+required.
+
+!!! note Amazon
+https://aws.amazon.com/blogs/containers/amazon-vpc-cni-now-supports-kubernetes-network-policies/[VPC
+CNI now supports Kubernetes Network Policies] to create policies that
+can isolate sensitive workloads and protect them from unauthorized
+access when running Kubernetes on AWS. This means that you can use all
+the capabilities of the Network Policy API within your Amazon EKS
+cluster. This level of granular control enables you to implement the
+principle of least privilege, which ensures that only authorized pods
+are allowed to communicate with each other.
+
+!!! attention Network policies are necessary but not sufficient. The
+enforcement of network policies requires a policy engine such as Calico
+or Cilium.
+
+=== Role-based access control (RBAC)
+
+Roles and role bindings are the Kubernetes objects used to enforce
+role-based access control (RBAC) in Kubernetes. *Roles* contain lists of
+actions that can be performed against objects in your cluster. *Role
+bindings* specify the individuals or groups to whom the roles apply. In
+the enterprise and KaaS settings, RBAC can be used to permit
+administration of objects by selected groups or individuals.
+
+=== Quotas
+
+Quotas are used to define limits on workloads hosted in your cluster.
+With quotas, you can specify the maximum amount of CPU and memory that a
+pod can consume, or you can limit the number of resources that can be
+allocated in a cluster or namespace. *Limit ranges* allow you to declare
+minimum, maximum, and default values for each limit.
+
+Overcommitting resources in a shared cluster is often beneficial because
+it allows you maximize your resources. However, unbounded access to a
+cluster can cause resource starvation, which can lead to performance
+degradation and loss of application availability. If a pod’s requests
+are set too low and the actual resource utilization exceeds the capacity
+of the node, the node will begin to experience CPU or memory pressure.
+When this happens, pods may be restarted and/or evicted from the node.
+
+To prevent this from happening, you should plan to impose quotas on
+namespaces in a multi-tenant environment to force tenants to specify
+requests and limits when scheduling their pods on the cluster. It will
+also mitigate a potential denial of service by constraining the amount
+of resources a pod can consume.
+
+You can also use quotas to apportion the cluster’s resources to align
+with a tenant’s spend. This is particularly useful in the KaaS scenario.
+
+=== Pod priority and preemption
+
+Pod priority and preemption can be useful when you want to provide more
+importance to a Pod relative to other Pods. For example, with pod
+priority you can configure pods from customer A to run at a higher
+priority than customer B. When there’s insufficient capacity available,
+the scheduler will evict the lower-priority pods from customer B to
+accommodate the higher-priority pods from customer A. This can be
+especially handy in a SaaS environment where customers willing to pay a
+premium receive a higher priority.
+
+!!! attention Pods priority can have an undesired effect on other Pods
+with lower priority. For example, although the victim pods are
+terminated gracefully but the PodDisruptionBudget is not guaranteed,
+which could break a application with lower priority that relies on a
+quorum of Pods, see
+https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#limitations-of-preemption[Limitations
+of preemption].
+
+== Mitigating controls
+
+Your chief concern as an administrator of a multi-tenant environment is
+preventing an attacker from gaining access to the underlying host. The
+following controls should be considered to mitigate this risk:
+
+=== Sandboxed execution environments for containers
+
+Sandboxing is a technique by which each container is run in its own
+isolated virtual machine. Technologies that perform pod sandboxing
+include https://firecracker-microvm.github.io/[Firecracker] and Weave’s
+https://www.weave.works/blog/firekube-fast-and-secure-kubernetes-clusters-using-weave-ignite[Firekube].
+
+For additional information about the effort to make Firecracker a
+supported runtime for EKS, see
+https://threadreaderapp.com/thread/1238496944684597248.html.
+
+=== Open Policy Agent (OPA) & Gatekeeper
+
+https://github.com/open-policy-agent/gatekeeper[Gatekeeper] is a
+Kubernetes admission controller that enforces policies created with
+https://www.openpolicyagent.org/[OPA]. With OPA you can create a policy
+that runs pods from tenants on separate instances or at a higher
+priority than other tenants. A collection of common OPA policies can be
+found in the GitHub
+https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository]
+for this project.
+
+There is also an experimental https://github.com/coredns/coredns-opa[OPA
+plugin for CoreDNS] that allows you to use OPA to filter/control the
+records returned by CoreDNS.
+
+=== Kyverno
+
+https://kyverno.io[Kyverno] is a Kubernetes native policy engine that
+can validate, mutate, and generate configurations with policies as
+Kubernetes resources. Kyverno uses Kustomize-style overlays for
+validation, supports JSON Patch and strategic merge patch for mutation,
+and can clone resources across namespaces based on flexible triggers.
+
+You can use Kyverno to isolate namespaces, enforce pod security and
+other best practices, and generate default configurations such as
+network policies. Several examples are included in the GitHub
+https://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno[repository]
+for this project. Many others are included in the
+https://kyverno.io/policies/[policy library] on the Kyverno website.
+
+=== Isolating tenant workloads to specific nodes
+
+Restricting tenant workloads to run on specific nodes can be used to
+increase isolation in the soft multi-tenancy model. With this approach,
+tenant-specific workloads are only run on nodes provisioned for the
+respective tenants. To achieve this isolation, native Kubernetes
+properties (node affinity, and taints and tolerations) are used to
+target specific nodes for pod scheduling, and prevent pods, from other
+tenants, from being scheduled on the tenant-specific nodes.
+
+==== Part 1 - Node affinity
+
+Kubernetes
+https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity[node
+affinity] is used to target nodes for scheduling, based on node
+https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/[labels].
+With node affinity rules, the pods are attracted to specific nodes that
+match the selector terms. In the below pod specification, the
+`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity is
+applied to the respective pod. The result is that the pod will target
+nodes that are labeled with the following key/value:
+`+node-restriction.kubernetes.io/tenant: tenants-x+`.
+
+[source,yaml]
+----
+...
+spec:
+  affinity:
+    nodeAffinity:
+      requiredDuringSchedulingIgnoredDuringExecution:
+        nodeSelectorTerms:
+        - matchExpressions:
+          - key: node-restriction.kubernetes.io/tenant
+            operator: In
+            values:
+            - tenants-x
+...
+----
+
+With this node affinity, the label is required during scheduling, but
+not during execution; if the underlying nodes’ labels change, the pods
+will not be evicted due solely to that label change. However, future
+scheduling could be impacted.
+
+!!! Warning The label prefix of `+node-restriction.kubernetes.io/+` has
+special meaning in Kubernetes.
+https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[NodeRestriction]
+which is enabled for EKS clusters prevents `+kubelet+` from
+adding/removing/updating labels with this prefix. Attackers aren’t able
+to use the `+kubelet+`’s credentials to update the node object or modify
+the system setup to pass these labels into `+kubelet+` as `+kubelet+`
+isn’t allowed to modify these labels. If this prefix is used for all pod
+to node scheduling, it prevents scenarios where an attacker may want to
+attract a different set of workloads to a node by modifying the node
+labels.
+
+!!! Info Instead of node affinity, we could have used the
+https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector[node
+selector]. However, node affinity is more expressive and allows for more
+conditions to be considered during pod scheduling. For additional
+information about the differences and more advanced scheduling choices,
+please see this CNCF blog post on
+https://www.cncf.io/blog/2021/07/27/advanced-kubernetes-pod-to-node-scheduling/[Advanced
+Kubernetes pod to node scheduling].
+
+==== Part 2 - Taints and tolerations
+
+Attracting pods to nodes is just the first part of this three-part
+approach. For this approach to work, we must repel pods from scheduling
+onto nodes for which the pods are not authorized. To repel unwanted or
+unauthorized pods, Kubernetes uses node
+https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[taints].
+Taints are used to place conditions on nodes that prevent pods from
+being scheduled. The below taint uses a key-value pair of
+`+tenant: tenants-x+`.
+
+[source,yaml]
+----
+...
+    taints:
+      - key: tenant
+        value: tenants-x
+        effect: NoSchedule
+...
+----
+
+Given the above node `+taint+`, only pods that _tolerate_ the taint will
+be allowed to be scheduled on the node. To allow authorized pods to be
+scheduled onto the node, the respective pod specifications must include
+a `+toleration+` to the taint, as seen below.
+
+[source,yaml]
+----
+...
+  tolerations:
+  - effect: NoSchedule
+    key: tenant
+    operator: Equal
+    value: tenants-x
+...
+----
+
+Pods with the above `+toleration+` will not be stopped from scheduling
+on the node, at least not because of that specific taint. Taints are
+also used by Kubernetes to temporarily stop pod scheduling during
+certain conditions, like node resource pressure. With node affinity, and
+taints and tolerations, we can effectively attract the desired pods to
+specific nodes and repel unwanted pods.
+
+!!! attention Certain Kubernetes pods are required to run on all nodes.
+Examples of these pods are those started by the
+https://github.com/containernetworking/cni[Container Network Interface
+(CNI)] and
+https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/[kube-proxy]
+https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[daemonsets].
+To that end, the specifications for these pods contain very permissive
+tolerations, to tolerate different taints. Care should be taken to not
+change these tolerations. Changing these tolerations could result in
+incorrect cluster operation. Additionally, policy-management tools, such
+as https://github.com/open-policy-agent/gatekeeper[OPA/Gatekeeper] and
+https://kyverno.io/[Kyverno] can be used to write validating policies
+that prevent unauthorized pods from using these permissive tolerations.
+
+==== Part 3 - Policy-based management for node selection
+
+There are several tools that can be used to help manage the node
+affinity and tolerations of pod specifications, including enforcement of
+rules in CICD pipelines. However, enforcement of isolation should also
+be done at the Kubernetes cluster level. For this purpose,
+policy-management tools can be used to _mutate_ inbound Kubernetes API
+server requests, based on request payloads, to apply the respective node
+affinity rules and tolerations mentioned above.
+
+For example, pods destined for the _tenants-x_ namespace can be
+_stamped_ with the correct node affinity and toleration to permit
+scheduling on the _tenants-x_ nodes. Utilizing policy-management tools
+configured using the Kubernetes
+https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook[Mutating
+Admission Webhook], policies can be used to mutate the inbound pod
+specifications. The mutations add the needed elements to allow desired
+scheduling. An example OPA/Gatekeeper policy that adds a node affinity
+is seen below.
+
+[source,yaml]
+----
+apiVersion: mutations.gatekeeper.sh/v1alpha1
+kind: Assign
+metadata:
+  name: mutator-add-nodeaffinity-pod
+  annotations:
+    aws-eks-best-practices/description: >-
+      Adds Node affinity - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
+spec:
+  applyTo:
+  - groups: [""]
+    kinds: ["Pod"]
+    versions: ["v1"]
+  match:
+    namespaces: ["tenants-x"]
+  location: "spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms"
+  parameters:
+    assign:
+      value:
+        - matchExpressions:
+          - key: "tenant"
+            operator: In
+            values:
+            - "tenants-x"
+----
+
+The above policy is applied to a Kubernetes API server request, to apply
+a pod to the _tenants-x_ namespace. The policy adds the
+`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity rule,
+so that pods are attracted to nodes with the `+tenant: tenants-x+`
+label.
+
+A second policy, seen below, adds the toleration to the same pod
+specification, using the same matching criteria of target namespace and
+groups, kinds, and versions.
+
+[source,yaml]
+----
+apiVersion: mutations.gatekeeper.sh/v1alpha1
+kind: Assign
+metadata:
+  name: mutator-add-toleration-pod
+  annotations:
+    aws-eks-best-practices/description: >-
+      Adds toleration - https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
+spec:
+  applyTo:
+  - groups: [""]
+    kinds: ["Pod"]
+    versions: ["v1"]
+  match:
+    namespaces: ["tenants-x"]
+  location: "spec.tolerations"
+  parameters:
+    assign:
+      value:
+      - key: "tenant"
+        operator: "Equal"
+        value: "tenants-x"
+        effect: "NoSchedule"
+----
+
+The above policies are specific to pods; this is due to the paths to the
+mutated elements in the policies’ `+location+` elements. Additional
+policies could be written to handle resources that create pods, like
+Deployment and Job resources. The listed policies and other examples can
+been seen in the companion
+https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa/gatekeeper/node-selector[GitHub
+project] for this guide.
+
+The result of these two mutations is that pods are attracted to the
+desired node, while at the same time, not repelled by the specific node
+taint. To verify this, we can see the snippets of output from two
+`+kubectl+` calls to get the nodes labeled with `+tenant=tenants-x+`,
+and get the pods in the `+tenants-x+` namespace.
+
+[source,bash]
+----
+kubectl get nodes -l tenant=tenants-x
+NAME
+ip-10-0-11-255...
+ip-10-0-28-81...
+ip-10-0-43-107...
+
+kubectl -n tenants-x get pods -owide
+NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE
+tenant-test-deploy-58b895ff87-2q7xw   1/1     Running   0          13s   10.0.42.143   ip-10-0-43-107...
+tenant-test-deploy-58b895ff87-9b6hg   1/1     Running   0          13s   10.0.18.145   ip-10-0-28-81...
+tenant-test-deploy-58b895ff87-nxvw5   1/1     Running   0          13s   10.0.30.117   ip-10-0-28-81...
+tenant-test-deploy-58b895ff87-vw796   1/1     Running   0          13s   10.0.3.113    ip-10-0-11-255...
+tenant-test-pod                       1/1     Running   0          13s   10.0.35.83    ip-10-0-43-107...
+----
+
+As we can see from the above outputs, all the pods are scheduled on the
+nodes labeled with `+tenant=tenants-x+`. Simply put, the pods will only
+run on the desired nodes, and the other pods (without the required
+affinity and tolerations) will not. The tenant workloads are effectively
+isolated.
+
+An example mutated pod specification is seen below.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Pod
+metadata:
+  name: tenant-test-pod
+  namespace: tenants-x
+spec:
+  affinity:
+    nodeAffinity:
+      requiredDuringSchedulingIgnoredDuringExecution:
+        nodeSelectorTerms:
+        - matchExpressions:
+          - key: tenant
+            operator: In
+            values:
+            - tenants-x
+...
+  tolerations:
+  - effect: NoSchedule
+    key: tenant
+    operator: Equal
+    value: tenants-x
+...
+----
+
+!!! attention Policy-management tools that are integrated to the
+Kubernetes API server request flow, using mutating and validating
+admission webhooks, are designed to respond to the API server’s request
+within a specified timeframe. This is usually 3 seconds or less. If the
+webhook call fails to return a response within the configured time, the
+mutation and/or validation of the inbound API sever request may or may
+not occur. This behavior is based on whether the admission webhook
+configurations are set to
+https://open-policy-agent.github.io/gatekeeper/website/docs/#admission-webhook-fail-open-by-default[Fail
+Open or Fail Close].
+
+In the above examples, we used policies written for OPA/Gatekeeper.
+However, there are other policy management tools that handle our
+node-selection use case as well. For example, this
+https://kyverno.io/policies/other/add_node_affinity/add_node_affinity/[Kyverno
+policy] could be used to handle the node affinity mutation.
+
+!!! tip If operating correctly, mutating policies will effect the
+desired changes to inbound API server request payloads. However,
+validating policies should also be included to verify that the desired
+changes occur, before changes are allowed to persist. This is especially
+important when using these policies for tenant-to-node isolation. It is
+also a good idea to include _Audit_ policies to routinely check your
+cluster for unwanted configurations.
+
+=== References
+
+* https://github.com/cruise-automation/k-rail[k-rail] Designed to help
+you secure a multi-tenant environment through the enforcement of certain
+policies.
+* https://d1.awsstatic.com/whitepapers/security-practices-for-multi-tenant-saas-apps-using-eks.pdf[Security
+Practices for MultiTenant SaaS Applications using Amazon EKS]
+
+== Hard multi-tenancy
+
+Hard multi-tenancy can be implemented by provisioning separate clusters
+for each tenant. While this provides very strong isolation between
+tenants, it has several drawbacks.
+
+First, when you have many tenants, this approach can quickly become
+expensive. Not only will you have to pay for the control plane costs for
+each cluster, you will not be able to share compute resources between
+clusters. This will eventually cause fragmentation where a subset of
+your clusters are underutilized while others are overutilized.
+
+Second, you will likely need to buy or build special tooling to manage
+all of these clusters. In time, managing hundreds or thousands of
+clusters may simply become too unwieldy.
+
+Finally, creating a cluster per tenant will be slow relative to a
+creating a namespace. Nevertheless, a hard-tenancy approach may be
+necessary in highly-regulated industries or in SaaS environments where
+strong isolation is required.
+
+== Future directions
+
+The Kubernetes community has recognized the current shortcomings of soft
+multi-tenancy and the challenges with hard multi-tenancy. The
+https://github.com/kubernetes-sigs/multi-tenancy[Multi-Tenancy Special
+Interest Group (SIG)] is attempting to address these shortcomings
+through several incubation projects, including Hierarchical Namespace
+Controller (HNC) and Virtual Cluster.
+
+The HNC proposal (KEP) describes a way to create parent-child
+relationships between namespaces with [policy] object inheritance along
+with an ability for tenant administrators to create sub-namespaces.
+
+The Virtual Cluster proposal describes a mechanism for creating separate
+instances of the control plane services, including the API server, the
+controller manager, and scheduler, for each tenant within the cluster
+(also known as "`Kubernetes on Kubernetes`").
+
+The
+https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/README.md[Multi-Tenancy
+Benchmarks] proposal provides guidelines for sharing clusters using
+namespaces for isolation and segmentation, and a command line tool
+https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/kubectl-mtb/README.md[kubectl-mtb]
+to validate conformance to the guidelines.
+
+== Multi-cluster management tools and resources
+
+* https://banzaicloud.com/[Banzai Cloud]
+* https://d2iq.com/solutions/ksphere/kommander[Kommander]
+* https://github.com/lensapp/lens[Lens]
+* https://nirmata.com[Nirmata]
+* https://rafay.co/[Rafay]
+* https://rancher.com/products/rancher/[Rancher]
+* https://www.weave.works/oss/flux/[Weave Flux]
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Auditing and logging
+
+Collecting and analyzing [audit] logs is useful for a variety of
+different reasons. Logs can help with root cause analysis and
+attribution, i.e. ascribing a change to a particular user. When enough
+logs have been collected, they can be used to detect anomalous behaviors
+too. On EKS, the audit logs are sent to Amazon Cloudwatch Logs. The
+audit policy for EKS is as follows:
+
+[source,yaml]
+----
+apiVersion: audit.k8s.io/v1beta1
+kind: Policy
+rules:
+  # Log aws-auth configmap changes
+  - level: RequestResponse
+    namespaces: ["kube-system"]
+    verbs: ["update", "patch", "delete"]
+    resources:
+      - group: "" # core
+        resources: ["configmaps"]
+        resourceNames: ["aws-auth"]
+    omitStages:
+      - "RequestReceived"
+  - level: None
+    users: ["system:kube-proxy"]
+    verbs: ["watch"]
+    resources:
+      - group: "" # core
+        resources: ["endpoints", "services", "services/status"]
+  - level: None
+    users: ["kubelet"] # legacy kubelet identity
+    verbs: ["get"]
+    resources:
+      - group: "" # core
+        resources: ["nodes", "nodes/status"]
+  - level: None
+    userGroups: ["system:nodes"]
+    verbs: ["get"]
+    resources:
+      - group: "" # core
+        resources: ["nodes", "nodes/status"]
+  - level: None
+    users:
+      - system:kube-controller-manager
+      - system:kube-scheduler
+      - system:serviceaccount:kube-system:endpoint-controller
+    verbs: ["get", "update"]
+    namespaces: ["kube-system"]
+    resources:
+      - group: "" # core
+        resources: ["endpoints"]
+  - level: None
+    users: ["system:apiserver"]
+    verbs: ["get"]
+    resources:
+      - group: "" # core
+        resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
+  - level: None
+    users:
+      - system:kube-controller-manager
+    verbs: ["get", "list"]
+    resources:
+      - group: "metrics.k8s.io"
+  - level: None
+    nonResourceURLs:
+      - /healthz*
+      - /version
+      - /swagger*
+  - level: None
+    resources:
+      - group: "" # core
+        resources: ["events"]
+  - level: Request
+    users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
+    verbs: ["update","patch"]
+    resources:
+      - group: "" # core
+        resources: ["nodes/status", "pods/status"]
+    omitStages:
+      - "RequestReceived"
+  - level: Request
+    userGroups: ["system:nodes"]
+    verbs: ["update","patch"]
+    resources:
+      - group: "" # core
+        resources: ["nodes/status", "pods/status"]
+    omitStages:
+      - "RequestReceived"
+  - level: Request
+    users: ["system:serviceaccount:kube-system:namespace-controller"]
+    verbs: ["deletecollection"]
+    omitStages:
+      - "RequestReceived"
+  # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
+  # so only log at the Metadata level.
+  - level: Metadata
+    resources:
+      - group: "" # core
+        resources: ["secrets", "configmaps"]
+      - group: authentication.k8s.io
+        resources: ["tokenreviews"]
+    omitStages:
+      - "RequestReceived"
+  - level: Request
+    resources:
+      - group: ""
+        resources: ["serviceaccounts/token"]
+  - level: Request
+    verbs: ["get", "list", "watch"]
+    resources:
+      - group: "" # core
+      - group: "admissionregistration.k8s.io"
+      - group: "apiextensions.k8s.io"
+      - group: "apiregistration.k8s.io"
+      - group: "apps"
+      - group: "authentication.k8s.io"
+      - group: "authorization.k8s.io"
+      - group: "autoscaling"
+      - group: "batch"
+      - group: "certificates.k8s.io"
+      - group: "extensions"
+      - group: "metrics.k8s.io"
+      - group: "networking.k8s.io"
+      - group: "policy"
+      - group: "rbac.authorization.k8s.io"
+      - group: "scheduling.k8s.io"
+      - group: "settings.k8s.io"
+      - group: "storage.k8s.io"
+    omitStages:
+      - "RequestReceived"
+  # Default level for known APIs
+  - level: RequestResponse
+    resources:
+      - group: "" # core
+      - group: "admissionregistration.k8s.io"
+      - group: "apiextensions.k8s.io"
+      - group: "apiregistration.k8s.io"
+      - group: "apps"
+      - group: "authentication.k8s.io"
+      - group: "authorization.k8s.io"
+      - group: "autoscaling"
+      - group: "batch"
+      - group: "certificates.k8s.io"
+      - group: "extensions"
+      - group: "metrics.k8s.io"
+      - group: "networking.k8s.io"
+      - group: "policy"
+      - group: "rbac.authorization.k8s.io"
+      - group: "scheduling.k8s.io"
+      - group: "settings.k8s.io"
+      - group: "storage.k8s.io"
+    omitStages:
+      - "RequestReceived"
+  # Default level for all other requests.
+  - level: Metadata
+    omitStages:
+      - "RequestReceived"
+----
+
+== Recommendations
+
+=== Enable audit logs
+
+The audit logs are part of the EKS managed Kubernetes control plane logs
+that are managed by EKS. Instructions for enabling/disabling the control
+plane logs, which includes the logs for the Kubernetes API server, the
+controller manager, and the scheduler, along with the audit log, can be
+found here,
+https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export.
+
+!!! info When you enable control plane logging, you will incur
+https://aws.amazon.com/cloudwatch/pricing/[costs] for storing the logs
+in CloudWatch. This raises a broader issue about the ongoing cost of
+security. Ultimately you will have to weigh those costs against the cost
+of a security breach, e.g. financial loss, damage to your reputation,
+etc. You may find that you can adequately secure your environment by
+implementing only some of the recommendations in this guide.
+
+!!! warning The maximum size for a CloudWatch Logs entry is
+https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html[256KB]
+whereas the maximum Kubernetes API request size is 1.5MiB. Log entries
+greater than 256KB will either be truncated or only include the request
+metadata.
+
+=== Utilize audit metadata
+
+Kubernetes audit logs include two annotations that indicate whether or
+not a request was authorized `+authorization.k8s.io/decision+` and the
+reason for the decision `+authorization.k8s.io/reason+`. Use these
+attributes to ascertain why a particular API call was allowed.
+
+=== Create alarms for suspicious events
+
+Create an alarm to automatically alert you where there is an increase in
+403 Forbidden and 401 Unauthorized responses, and then use attributes
+like `+host+`, `+sourceIPs+`, and `+k8s_user.username+` to find out
+where those requests are coming from.
+
+=== Analyze logs with Log Insights
+
+Use CloudWatch Log Insights to monitor changes to RBAC objects,
+e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few
+sample queries appear below:
+
+Lists updates to the `+aws-auth+` ConfigMap:
+
+[source,bash]
+----
+fields @timestamp, @message
+| filter @logStream like "kube-apiserver-audit"
+| filter verb in ["update", "patch"]
+| filter objectRef.resource = "configmaps" and objectRef.name = "aws-auth" and objectRef.namespace = "kube-system"
+| sort @timestamp desc
+----
+
+Lists creation of new or changes to validation webhooks:
+
+[source,bash]
+----
+fields @timestamp, @message
+| filter @logStream like "kube-apiserver-audit"
+| filter verb in ["create", "update", "patch"] and responseStatus.code = 201
+| filter objectRef.resource = "validatingwebhookconfigurations"
+| sort @timestamp desc
+----
+
+Lists create, update, delete operations to Roles:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"]
+----
+
+Lists create, update, delete operations to RoleBindings:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"]
+----
+
+Lists create, update, delete operations to ClusterRoles:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"]
+----
+
+Lists create, update, delete operations to ClusterRoleBindings:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"]
+----
+
+Plots unauthorized read operations against Secrets:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter objectRef.resource="secrets" and verb in ["get", "watch", "list"] and responseStatus.code="401"
+| stats count() by bin(1m)
+----
+
+List of failed anonymous requests:
+
+[source,bash]
+----
+fields @timestamp, @message, sourceIPs.0
+| sort @timestamp desc
+| limit 100
+| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"]
+----
+
+=== Audit your CloudTrail logs
+
+AWS APIs called by pods that are utilizing IAM Roles for Service
+Accounts (IRSA) are automatically logged to CloudTrail along with the
+name of the service account. If the name of a service account that
+wasn’t explicitly authorized to call an API appears in the log, it may
+be an indication that the IAM role’s trust policy was misconfigured.
+Generally speaking, Cloudtrail is a great way to ascribe AWS API calls
+to specific IAM principals.
+
+=== Use CloudTrail Insights to unearth suspicious activity
+
+CloudTrail insights automatically analyzes write management events from
+CloudTrail trails and alerts you of unusual activity. This can help you
+identify when there’s an increase in call volume on write APIs in your
+AWS account, including from pods that use IRSA to assume an IAM role.
+See
+https://aws.amazon.com/blogs/aws/announcing-cloudtrail-insights-identify-and-respond-to-unusual-api-activity/[Announcing
+CloudTrail Insights: Identify and Response to Unusual API Activity] for
+further information.
+
+=== Additional resources
+
+As the volume of logs increases, parsing and filtering them with Log
+Insights or another log analysis tool may become ineffective. As an
+alternative, you might want to consider running
+https://github.com/falcosecurity/falco[Sysdig Falco] and
+https://github.com/sysdiglabs/ekscloudwatch[ekscloudwatch]. Falco
+analyzes audit logs and flags anomalies or abuse over an extended period
+of time. The ekscloudwatch project forwards audit log events from
+CloudWatch to Falco for analysis. Falco provides a set of
+https://github.com/falcosecurity/plugins/blob/master/plugins/k8saudit/rules/k8s_audit_rules.yaml[default
+audit rules] along with the ability to add your own.
+
+Yet another option might be to store the audit logs in S3 and use the
+SageMaker
+https://docs.aws.amazon.com/sagemaker/latest/dg/randomcutforest.html[Random
+Cut Forest] algorithm to anomalous behaviors that warrant further
+investigation.
+
+== Tools and resources
+
+The following commercial and open source projects can be used to assess
+your cluster’s alignment with established best practices:
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/5-detective-controls[Amazon
+EKS Security Immersion Workshop - Detective Controls]
+* https://github.com/Shopify/kubeaudit[kubeaudit]
+* https://github.com/octarinesec/kube-scan[kube-scan] Assigns a risk
+score to the workloads running in your cluster in accordance with the
+Kubernetes Common Configuration Scoring System framework
+* https://kubesec.io/[kubesec.io]
+* https://github.com/FairwindsOps/polaris[polaris]
+* https://github.com/aquasecurity/starboard[Starboard]
+* https://support.snyk.io/hc/en-us/articles/360003916138-Kubernetes-integration-overview[Snyk]
+* https://github.com/kubescape/kubescape[Kubescape] Kubescape is an open
+source kubernetes security tool that scans clusters, YAML files, and
+Helm charts. It detects misconfigurations according to multiple
+frameworks (including
+https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo/?utm_source=github&utm_medium=repository[NSA-CISA]
+and
+https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/[MITRE
+ATT&CK®].)
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Network security
+
+Network security has several facets. The first involves the application
+of rules which restrict the flow of network traffic between services.
+The second involves the encryption of traffic while it is in transit.
+The mechanisms to implement these security measures on EKS are varied
+but often include the following items:
+
+== Traffic control
+
+* Network Policies
+* Security Groups
+
+== Network encryption
+
+* Service Mesh
+* Container Network Interfaces (CNIs)
+* Ingress Controllers and Load Balancers
+* Nitro Instances
+* ACM Private CA with cert-manager
+
+== Network policy
+
+Within a Kubernetes cluster, all Pod to Pod communication is allowed by
+default. While this flexibility may help promote experimentation, it is
+not considered secure. Kubernetes network policies give you a mechanism
+to restrict network traffic between Pods (often referred to as East/West
+traffic) as well as between Pods and external services. Kubernetes
+network policies operate at layers 3 and 4 of the OSI model. Network
+policies use pod, namespace selectors and labels to identify source and
+destination pods, but can also include IP addresses, port numbers,
+protocols, or a combination of these. Network Policies can be applied to
+both Inbound or Outbound connections to the pod, often called Ingress
+and Egress rules.
+
+With native network policy support of Amazon VPC CNI Plugin, you can
+implement network policies to secure network traffic in kubernetes
+clusters. This integrates with the upstream Kubernetes Network Policy
+API, ensuring compatibility and adherence to Kubernetes standards. You
+can define policies using different
+https://kubernetes.io/docs/concepts/services-networking/network-policies/[identifiers]
+supported by the upstream API. By default, all ingress and egress
+traffic is allowed to a pod. When a network policy with a policyType
+Ingress is specified, only allowed connections into the pod are those
+from the pod’s node and those allowed by the ingress rules. Same applies
+for egress rules. If multiple rules are defined, then union of all rules
+are taken into account when making the decision. Thus, order of
+evaluation does not affect the policy result.
+
+!!! attention When you first provision an EKS cluster, VPC CNI Network
+Policy functionality is not enabled by default. Ensure you deployed
+supported VPC CNI Add-on version and set `+ENABLE_NETWORK_POLICY+` flag
+to `+true+` on the vpc-cni add-on to enable this. Refer
+https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html[Amazon
+EKS User guide] for detailed instructions.
+
+== Recommendations
+
+=== Getting Started with Network Policies - Follow Principle of Least Privilege
+
+==== Create a default deny policy
+
+As with RBAC policies, it is recommended to follow least privileged
+access principles with network policies. Start by creating a deny all
+policy that restricts all inbound and outbound traffic with in a
+namespace.
+
+[source,yaml]
+----
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: default-deny
+  namespace: default
+spec:
+  podSelector: {}
+  policyTypes:
+  - Ingress
+  - Egress
+----
+
+.default-deny
+image::./images/default-deny.jpg[default-deny]
+
+!!! tip The image above was created by the network policy viewer from
+https://orca.tufin.io/netpol/[Tufin].
+
+==== Create a rule to allow DNS queries
+
+Once you have the default deny all rule in place, you can begin layering
+on additional rules, such as a rule that allows pods to query CoreDNS
+for name resolution.
+
+[source,yaml]
+----
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: allow-dns-access
+  namespace: default
+spec:
+  podSelector:
+    matchLabels: {}
+  policyTypes:
+  - Egress
+  egress:
+  - to:
+    - namespaceSelector:
+        matchLabels:
+          kubernetes.io/metadata.name: kube-system
+      podSelector:
+        matchLabels:
+          k8s-app: kube-dns
+    ports:
+    - protocol: UDP
+      port: 53
+----
+
+.allow-dns-access
+image::./images/allow-dns-access.jpg[allow-dns-access]
+
+==== Incrementally add rules to selectively allow the flow of traffic between namespaces/pods
+
+Understand the application requirements and create fine-grained ingress
+and egress rules as needed. Below example shows how to restrict ingress
+traffic on port 80 to `+app-one+` from `+client-one+`. This helps
+minimize the attack surface and reduces the risk of unauthorized access.
+
+[source,yaml]
+----
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: allow-ingress-app-one
+  namespace: default
+spec:
+  podSelector:
+    matchLabels:
+      k8s-app: app-one
+  policyTypes:
+  - Ingress
+  ingress:
+  - from:
+    - podSelector:
+        matchLabels:
+          k8s-app: client-one
+    ports:
+    - protocol: TCP
+      port: 80
+----
+
+.allow-ingress-app-one
+image::./images/allow-ingress-app-one.png[allow-ingress-app-one]
+
+=== Monitoring network policy enforcement
+
+* *Use Network Policy editor*
+** https://networkpolicy.io/[Network policy editor] helps with
+visualizations, security score, autogenerates from network flow logs
+** Build network policies in an interactive way
+* *Audit Logs*
+** Regularly review audit logs of your EKS cluster
+** Audit logs provide wealth of information about what actions have been
+performed on your cluster including changes to network policies
+** Use this information to track changes to your network policies over
+time and detect any unauthorized or unexpected changes
+* *Automated testing*
+** Implement automated testing by creating a test environment that
+mirrors your production environment and periodically deploy workloads
+that attempt to violate your network policies.
+* *Monitoring metrics*
+** Configure your observability agents to scrape the prometheus metrics
+from the VPC CNI node agents, that allows to monitor the agent health,
+and sdk errors.
+* *Audit Network Policies regularly*
+** Periodically audit your Network Policies to make sure that they meet
+your current application requirements. As your application evolves, an
+audit gives you the opportunity to remove redundant ingress, egress
+rules and make sure that your applications don’t have excessive
+permissions.
+* *Ensure Network Policies exists using Open Policy Agent (OPA)*
+** Use OPA Policy like shown below to ensure Network Policy always
+exists before onboarding application pods. This policy denies onboarding
+k8s pods with a label `+k8s-app: sample-app+` if corresponding network
+policy does not exist.
+
+[source,javascript]
+----
+package kubernetes.admission
+import data.kubernetes.networkpolicies
+
+deny[msg] {
+    input.request.kind.kind == "Pod"
+    pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels}
+    contains_label(pod_label_value, "sample-app")
+    np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels}
+    not contains_label(np_label_value, "sample-app")
+    msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name])
+}
+contains_label(arr, val) {
+    arr[_] == val
+}
+----
+
+=== Troubleshooting
+
+==== Monitor the vpc-network-policy-controller, node-agent logs
+
+Enable the EKS Control plane controller manager logs to diagnose the
+network policy functionality. You can stream the control plane logs to a
+CloudWatch log group and use
+https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html[CloudWatch
+Log insights] to perform advanced queries. From the logs, you can view
+what pod endpoint objects are resolved to a Network Policy,
+reconcilation status of the policies, and debug if the policy is working
+as expected.
+
+In addition, Amazon VPC CNI allows you to enable the collection and
+export of policy enforcement logs to
+https://aws.amazon.com/cloudwatch/[Amazon Cloudwatch] from the EKS
+worker nodes. Once enabled, you can leverage
+https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html[CloudWatch
+Container Insights] to provide insights on your usage related to Network
+Policies.
+
+Amazon VPC CNI also ships an SDK that provides an interface to interact
+with eBPF programs on the node. The SDK is installed when the
+`+aws-node+` is deployed onto the nodes. You can find the SDK binary
+installed under `+/opt/cni/bin+` directory on the node. At launch, the
+SDK provides support for fundamental functionalities such as inspecting
+eBPF programs and maps.
+
+[source,shell]
+----
+sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
+----
+
+==== Log network traffic metadata
+
+https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html[AWS VPC
+Flow Logs] captures metadata about the traffic flowing through a VPC,
+such as source and destination IP address and port along with
+accepted/dropped packets. This information could be analyzed to look for
+suspicious or unusual activity between resources within the VPC,
+including Pods. However, since the IP addresses of pods frequently
+change as they are replaced, Flow Logs may not be sufficient on its own.
+Calico Enterprise extends the Flow Logs with pod labels and other
+metadata, making it easier to decipher the traffic flows between pods.
+
+== Security groups
+
+EKS uses
+https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS
+VPC Security Groups] (SGs) to control the traffic between the Kubernetes
+control plane and the cluster’s worker nodes. Security groups are also
+used to control the traffic between worker nodes, and other VPC
+resources, and external IP addresses. When you provision an EKS cluster
+(with Kubernetes version 1.14-eks.3 or greater), a cluster security
+group is automatically created for you. This security group allows
+unfettered communication between the EKS control plane and the nodes
+from managed node groups. For simplicity, it is recommended that you add
+the cluster SG to all node groups, including unmanaged node groups.
+
+Prior to Kubernetes version 1.14 and EKS version eks.3, there were
+separate security groups configured for the EKS control plane and node
+groups. The minimum and suggested rules for the control plane and node
+group security groups can be found at
+https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html.
+The minimum rules for the _control plane security group_ allows port 443
+inbound from the worker node SG. This rule is what allows the kubelets
+to communicate with the Kubernetes API server. It also includes port
+10250 for outbound traffic to the worker node SG; 10250 is the port that
+the kubelets listen on. Similarly, the minimum _node group_ rules allow
+port 10250 inbound from the control plane SG and 443 outbound to the
+control plane SG. Finally there is a rule that allows unfettered
+communication between nodes within a node group.
+
+If you need to control communication between services that run within
+the cluster and service the run outside the cluster such as an RDS
+database, consider
+https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html[security
+groups for pods]. With security groups for pods, you can assign an
+*existing* security group to a collection of pods.
+
+!!! warning If you reference a security group that does not exist prior
+to the creation of the pods, the pods will not get scheduled.
+
+You can control which pods are assigned to a security group by creating
+a `+SecurityGroupPolicy+` object and specifying a `+PodSelector+` or a
+`+ServiceAccountSelector+`. Setting the selectors to `+{}+` will assign
+the SGs referenced in the `+SecurityGroupPolicy+` to all pods in a
+namespace or all Service Accounts in a namespace. Be sure you’ve
+familiarized yourself with all the
+https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations[considerations]
+before implementing security groups for pods.
+
+!!! important If you use SGs for pods you *must* create SGs that allow
+port 53 outbound to the cluster security group. Similarly, you *must*
+update the cluster security group to accept port 53 inbound traffic from
+the pod security group.
+
+!!! important The
+https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups[limits
+for security groups] still apply when using security groups for pods so
+use them judiciously.
+
+!!! important You *must* create rules for inbound traffic from the
+cluster security group (kubelet) for all of the probes configured for
+pod.
+
+!!! important Security groups for pods relies on a feature known as
+https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html[ENI
+trunking] which was created to increase the ENI density of an EC2
+instance. When a pod is assigned to an SG, a VPC controller associates a
+branch ENI from the node group with the pod. If there aren’t enough
+branch ENIs available in a node group at the time the pod is scheduled,
+the pod will stay in pending state. The number of branch ENIs an
+instance can support varies by instance type/family. See
+https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types
+for further details.
+
+While security groups for pods offers an AWS-native way to control
+network traffic within and outside of your cluster without the overhead
+of a policy daemon, other options are available. For example, the Cilium
+policy engine allows you to reference a DNS name in a network policy.
+Calico Enterprise includes an option for mapping network policies to AWS
+security groups. If you’ve implemented a service mesh like Istio, you
+can use an egress gateway to restrict network egress to specific, fully
+qualified domains or IP addresses. For further information about this
+option, read the three part series on
+https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/[egress
+traffic control in Istio].
+
+== When to use Network Policy vs Security Group for Pods?
+
+=== When to use Kubernetes network policy
+
+* *Controlling pod-to-pod traffic*
+** Suitable for controlling network traffic between pods inside a
+cluster (east-west traffic)
+* *Control traffic at the IP address or port level (OSI layer 3 or 4)*
+
+=== When to use AWS Security groups for pods (SGP)
+
+* *Leverage existing AWS configurations*
+** If you already have complex set of EC2 security groups that manage
+access to AWS services and you are migrating applications from EC2
+instances to EKS, SGPs can be a very good choice allowing you to reuse
+security group resources and apply them to your pods.
+* *Control access to AWS services*
+** Your applications running within an EKS cluster wants to communicate
+with other AWS services (RDS database), use SGPs as an efficient
+mechanism to control the traffic from the pods to AWS services.
+* *Isolation of Pod & Node traffic*
+** If you want to completely separate pod traffic from the rest of the
+node traffic, use SGP in `+POD_SECURITY_GROUP_ENFORCING_MODE=strict+`
+mode.
+
+=== Best practices using `+Security groups for pods+` and `+Network Policy+`
+
+* *Layered security*
+** Use a combination of SGP and kubernetes network policy for a layered
+security approach
+** Use SGPs to limit network level access to AWS services that are not
+part of a cluster, while kubernetes network policies can restrict
+network traffic between pods inside the cluster
+* *Principle of least privilege*
+** Only allow necessary traffic between pods or namespaces
+* *Segment your applications*
+** Wherever possible, segment applications by the network policy to
+reduce the blast radius if an application is compromised
+* *Keep policies simple and clear*
+** Kubernetes network policies can be quite granular and complex, its
+best to keep them as simple as possible to reduce the risk of
+misconfiguration and ease the management overhead
+* *Reduce the attack surface*
+** Minimize the attack surface by limiting the exposure of your
+applications
+
+!!! attention Security Groups for pods provides two enforcing modes:
+`+strict+` and `+standard+`. You must use `+standard+` mode when using
+both Network Policy and Security Groups for pods features in an EKS
+cluster.
+
+When it comes to network security, a layered approach is often the most
+effective solution. Using kubernetes network policy and SGP in
+combination can provide a robust defense-in-depth strategy for your
+applications running in EKS.
+
+== Service Mesh Policy Enforcement or Kubernetes network policy
+
+A `+service mesh+` is a dedicated infrastructure layer that you can add
+to your applications. It allows you to transparently add capabilities
+like observability, traffic management, and security, without adding
+them to your own code.
+
+Service mesh enforces policies at Layer 7 (application) of OSI model
+whereas kubernetes network policies operate at Layer 3 (network) and
+Layer 4 (transport). There are many offerings in this space like AWS
+AppMesh, Istio, Linkerd, etc.,
+
+=== When to use Service mesh for policy enforcement
+
+* Have existing investment in a service mesh
+* Need more advanced capabilities like traffic management, observability
+& security
+** Traffic control, load balancing, circuit breaking, rate limiting,
+timeouts etc.
+** Detailed insights into how your services are performing (latency,
+error rates, requests per second, request volumes etc.)
+** You want to implement and leverage service mesh for security features
+like mTLS
+
+=== Choose Kubernetes network policy for simpler use cases
+
+* Limit which pods can communicate with each other
+* Network policies require fewer resources than a service mesh making
+them a good fit for simpler use cases or for smaller clusters where the
+overhead of running and managing a service mesh might not be justified
+
+!!! tip Network policies and Service mesh can also be used together. Use
+network policies to provide a baseline level of security and isolation
+between your pods and then use a service mesh to add additional
+capabilities like traffic management, observability and security.
+
+== ThirdParty Network Policy Engines
+
+Consider a Third Party Network Policy Engine when you have advanced
+policy requirements like Global Network Policies, support for DNS
+Hostname based rules, Layer 7 rules, ServiceAccount based rules, and
+explicit deny/log actions, etc.,
+https://docs.projectcalico.org/introduction/[Calico], is an open source
+policy engine from https://tigera.io[Tigera] that works well with EKS.
+In addition to implementing the full set of Kubernetes network policy
+features, Calico supports extended network polices with a richer set of
+features, including support for layer 7 rules, e.g. HTTP, when
+integrated with Istio. Calico policies can be scoped to Namespaces,
+Pods, service accounts, or globally. When policies are scoped to a
+service account, it associates a set of ingress/egress rules with that
+service account. With the proper RBAC rules in place, you can prevent
+teams from overriding these rules, allowing IT security professionals to
+safely delegate administration of namespaces. Isovalent, the maintainers
+of https://cilium.readthedocs.io/en/stable/intro/[Cilium], have also
+extended the network policies to include partial support for layer 7
+rules, e.g. HTTP. Cilium also has support for DNS hostnames which can be
+useful for restricting traffic between Kubernetes Services/Pods and
+resources that run within or outside of your VPC. By contrast, Calico
+Enterprise includes a feature that allows you to map a Kubernetes
+network policy to an AWS security group, as well as DNS hostnames.
+
+You can find a list of common Kubernetes network policies at
+https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar
+set of rules for Calico are available at
+https://docs.projectcalico.org/security/calico-network-policy.
+
+=== Migration to Amazon VPC CNI Network Policy Engine
+
+To maintain consistency and avoid unexpected pod communication behavior,
+it is recommended to deploy only one Network Policy Engine in your
+cluster. If you want to migrate from 3P to VPC CNI Network Policy
+Engine, we recommend converting your existing 3P NetworkPolicy CRDs to
+the Kubernetes NetworkPolicy resources before enabling VPC CNI network
+policy support. And, test the migrated policies in a separate test
+cluster before applying them in you production environment. This allows
+you to identify and address any potential issues or inconsistencies in
+pod communication behavior.
+
+==== Migration Tool
+
+To assist in your migration process, we have developed a tool called
+https://github.com/awslabs/k8s-network-policy-migrator[K8s Network
+Policy Migrator] that converts your existing Calico/Cilium network
+policy CRDs to Kubernetes native network policies. After conversion you
+can directly test the converted network policies on your new clusters
+running VPC CNI network policy controller. The tool is designed to help
+you streamline the migration process and ensure a smooth transition.
+
+!!! Important Migration tool will only convert 3P policies that are
+compatible with native kubernetes network policy api. If you are using
+advanced network policy features offered by 3P plugins, Migration tool
+will skip and report them.
+
+Please note that migration tool is currently not supported by AWS VPC
+CNI Network policy engineering team, it is made available to customers
+on a best-effort basis. We encourage you to utilize this tool to
+facilitate your migration process. In the event that you encounter any
+issues or bugs with the tool, we kindly ask you create a
+https://github.com/awslabs/k8s-network-policy-migrator/issues[GitHub
+issue]. Your feedback is invaluable to us and will assist in the
+continuous improvement of our services.
+
+=== Additional Resources
+
+* https://youtu.be/lEY2WnRHYpg[Kubernetes & Tigera: Network
+Policies&#44; Security&#44; and Audit]
+* https://www.tigera.io/tigera-products/calico-enterprise/[Calico
+Enterprise]
+* https://cilium.readthedocs.io/en/stable/intro/[Cilium]
+* https://cilium.io/blog/2021/02/10/network-policy-editor[NetworkPolicy
+Editor] an interactive policy editor from Cilium
+* https://www.inspektor-gadget.io/docs/latest/gadgets/advise/network-policy/[Inspektor
+Gadget advise network-policy gadget] Suggests network policies based on
+an analysis of network traffic
+
+== Encryption in transit
+
+Applications that need to conform to PCI, HIPAA, or other regulations
+may need to encrypt data while it is in transit. Nowadays TLS is the de
+facto choice for encrypting traffic on the wire. TLS, like it’s
+predecessor SSL, provides secure communications over a network using
+cryptographic protocols. TLS uses symmetric encryption where the keys to
+encrypt the data are generated based on a shared secret that is
+negotiated at the beginning of the session. The following are a few ways
+that you can encrypt data in a Kubernetes environment.
+
+=== Nitro Instances
+
+Traffic exchanged between the following Nitro instance types, e.g. C5n,
+G4, I3en, M5dn, M5n, P3dn, R5dn, and R5n, is automatically encrypted by
+default. When there’s an intermediate hop, like a transit gateway or a
+load balancer, the traffic is not encrypted. See
+https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/data-protection.html#encryption-transit[Encryption
+in transit] for further details on encryption in transit as well as the
+complete list of instances types that support network encryption by
+default.
+
+=== Container Network Interfaces (CNIs)
+
+https://www.weave.works/oss/net/[WeaveNet] can be configured to
+automatically encrypt all traffic using NaCl encryption for sleeve
+traffic, and IPsec ESP for fast datapath traffic.
+
+=== Service Mesh
+
+Encryption in transit can also be implemented with a service mesh like
+App Mesh, Linkerd v2, and Istio. AppMesh supports
+https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html[mTLS]
+with X.509 certificates or Envoy’s Secret Discovery Service(SDS).
+Linkerd and Istio both have support for mTLS.
+
+The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples]
+GitHub repository provides walkthroughs for configuring mTLS using X.509
+certificates and SPIRE as SDS provider with your Envoy container:
+
+* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-file-based[Configuring
+mTLS using X.509 certificates]
+* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-sds-based[Configuring
+TLS using SPIRE (SDS)]
+
+App Mesh also supports
+https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html[TLS
+encryption] with a private certificate issued by
+https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS
+Certificate Manager] (ACM) or a certificate stored on the local file
+system of the virtual node.
+
+The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples]
+GitHub repository provides walkthroughs for configuring TLS using
+certificates issued by ACM and certificates that are packaged with your
+Envoy container:
+
+* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/howto-tls-file-provided[Configuring
+TLS with File Provided TLS Certificates]
+* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm[Configuring
+TLS with AWS Certificate Manager]
+
+=== Ingress Controllers and Load Balancers
+
+Ingress controllers are a way for you to intelligently route HTTP/S
+traffic that emanates from outside the cluster to services running
+inside the cluster. Oftentimes, these Ingresses are fronted by a layer 4
+load balancer, like the Classic Load Balancer or the Network Load
+Balancer (NLB). Encrypted traffic can be terminated at different places
+within the network, e.g. at the load balancer, at the ingress resource,
+or the Pod. How and where you terminate your SSL connection will
+ultimately be dictated by your organization’s network security policy.
+For instance, if you have a policy that requires end-to-end encryption,
+you will have to decrypt the traffic at the Pod. This will place
+additional burden on your Pod as it will have to spend cycles
+establishing the initial handshake. Overall SSL/TLS processing is very
+CPU intensive. Consequently, if you have the flexibility, try performing
+the SSL offload at the Ingress or the load balancer.
+
+==== Use encryption with AWS Elastic load balancers
+
+The
+https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html[AWS
+Application Load Balancer] (ALB) and
+https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html[Network
+Load Balancer] (NLB) both have support for transport encryption (SSL and
+TLS). The `+alb.ingress.kubernetes.io/certificate-arn+` annotation for
+the ALB lets you to specify which certificates to add to the ALB. If you
+omit the annotation the controller will attempt to add certificates to
+listeners that require it by matching the available
+https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS
+Certificate Manager (ACM)] certificates using the host field. Starting
+with EKS v1.15 you can use the
+`+service.beta.kubernetes.io/aws-load-balancer-ssl-cert+` annotation
+with the NLB as shown in the example below.
+
+[source,yaml]
+----
+apiVersion: v1
+kind: Service
+metadata:
+  name: demo-app
+  namespace: default
+  labels:
+    app: demo-app
+  annotations:
+     service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
+     service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<certificate ARN>"
+     service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
+     service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
+spec:
+  type: LoadBalancer
+  ports:
+  - port: 443
+    targetPort: 80
+    protocol: TCP
+  selector:
+    app: demo-app
+---
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+  name: nginx
+  namespace: default
+  labels:
+    app: demo-app
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: demo-app
+  template:
+    metadata:
+      labels:
+        app: demo-app
+    spec:
+      containers:
+        - name: nginx
+          image: nginx
+          ports:
+            - containerPort: 443
+              protocol: TCP
+            - containerPort: 80
+              protocol: TCP
+----
+
+Following are additional examples for SSL/TLS termination.
+
+* https://aws.amazon.com/blogs/containers/securing-eks-ingress-contour-lets-encrypt-gitops/[Securing
+EKS Ingress With Contour And Let’s Encrypt The GitOps Way]
+* https://aws.amazon.com/premiumsupport/knowledge-center/terminate-https-traffic-eks-acm/[How
+do I terminate HTTPS traffic on Amazon EKS workloads with ACM?]
+
+!!! attention Some Ingresses, like the AWS LB controller, implement the
+SSL/TLS using Annotations instead of as part of the Ingress Spec.
+
+=== ACM Private CA with cert-manager
+
+You can enable TLS and mTLS to secure your EKS application workloads at
+the ingress, on the pod, and between pods using ACM Private Certificate
+Authority (CA) and https://cert-manager.io/[cert-manager], a popular
+Kubernetes add-on to distribute, renew, and revoke certificates. ACM
+Private CA is a highly-available, secure, managed CA without the upfront
+and maintenance costs of managing your own CA. If you are using the
+default Kubernetes certificate authority, there is an opportunity to
+improve your security and meet compliance requirements with ACM Private
+CA. ACM Private CA secures private keys in FIPS 140-2 Level 3 hardware
+security modules (very secure), compared with the default CA storing
+keys encoded in memory (less secure). A centralized CA also gives you
+more control and improved auditability for private certificates both
+inside and outside of a Kubernetes environment.
+
+==== Short-Lived CA Mode for Mutual TLS Between Workloads
+
+When using ACM Private CA for mTLS in EKS, it is recommended that you
+use short lived certificates with _short-lived CA mode_. Although it is
+possible to issue out short-lived certificates in the general-purpose CA
+mode, using short-lived CA mode works out more cost-effective (~75%
+cheaper than general mode) for use cases where new certificates need to
+be issued frequently. In addition to this, you should try to align the
+validity period of the private certificates with the lifetime of the
+pods in your EKS cluster.
+https://aws.amazon.com/certificate-manager/private-certificate-authority/[Learn
+more about ACM Private CA and its benefits here].
+
+==== ACM Setup Instructions
+
+Start by creating a Private CA by following procedures provided in the
+https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html[ACM
+Private CA tech docs]. Once you have a Private CA, install cert-manager
+using https://cert-manager.io/docs/installation/[regular installation
+instructions]. After installing cert-manager, install the Private CA
+Kubernetes cert-manager plugin by following the
+https://github.com/cert-manager/aws-privateca-issuer#setup[setup
+instructions in GitHub]. The plugin lets cert-manager request private
+certificates from ACM Private CA.
+
+Now that you have a Private CA and an EKS cluster with cert-manager and
+the plugin installed, it’s time to set permissions and create the
+issuer. Update IAM permissions of the EKS node role to allow access to
+ACM Private CA. Replace the `+<CA_ARN>+` with the value from your
+Private CA:
+
+[source,json]
+----
+{
+    "Version": "2012-10-17",
+    "Statement": [
+        {
+            "Sid": "awspcaissuer",
+            "Action": [
+                "acm-pca:DescribeCertificateAuthority",
+                "acm-pca:GetCertificate",
+                "acm-pca:IssueCertificate"
+            ],
+            "Effect": "Allow",
+            "Resource": "<CA_ARN>"
+        }
+    ]
+}
+----
+
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[Service
+Roles for IAM Accounts&#44; or IRSA] can also be used. Please see the
+Additional Resources section below for complete examples.
+
+Create an Issuer in Amazon EKS by creating a Custom Resource Definition
+file named cluster-issuer.yaml with the following text in it, replacing
+`+<CA_ARN>+` and `+<Region>+` information with your Private CA.
+
+[source,yaml]
+----
+apiVersion: awspca.cert-manager.io/v1beta1
+kind: AWSPCAClusterIssuer
+metadata:
+          name: demo-test-root-ca
+spec:
+          arn: <CA_ARN>
+          region: <Region>
+----
+
+Deploy the Issuer you created.
+
+[source,bash]
+----
+kubectl apply -f cluster-issuer.yaml
+----
+
+Your EKS cluster is configured to request certificates from Private CA.
+You can now use cert-manager’s `+Certificate+` resource to issue
+certificates by changing the `+issuerRef+` field’s values to the Private
+CA Issuer you created above. For more details on how to specify and
+request Certificate resources, please check cert-manager’s
+https://cert-manager.io/docs/usage/certificate/[Certificate Resources
+guide].
+https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/[See
+examples here].
+
+=== ACM Private CA with Istio and cert-manager
+
+If you are running Istio in your EKS cluster, you can disable the Istio
+control plane (specifically `+istiod+`) from functioning as the root
+Certificate Authority (CA), and configure ACM Private CA as the root CA
+for mTLS between workloads. If you’re going with this approach, consider
+using the _short-lived CA mode_ in ACM Private CA. Refer to the
+link:#short-lived-ca-mode-for-mutual-tls-between-workloads[previous
+section] and this
+https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[blog
+post] for more details.
+
+==== How Certificate Signing Works in Istio (Default)
+
+Workloads in Kubernetes are identified using service accounts. If you
+don’t specify a service account, Kubernetes will automatically assign
+one to your workload. Also, service accounts automatically mount an
+associated token. This token is used by the service account for
+workloads to authenticate against the Kubernetes API. The service
+account may be sufficient as an identity for Kubernetes but Istio has
+its own identity management system and CA. When a workload starts up
+with its envoy sidecar proxy, it needs an identity assigned from Istio
+in order for it to be deemed as trustworthy and allowed to communicate
+with other services in the mesh.
+
+To get this identity from Istio, the `+istio-agent+` sends a request
+known as a certificate signing request (or CSR) to the Istio control
+plane. This CSR contains the service account token so that the
+workload’s identity can be verified before being processed. This
+verification process is handled by `+istiod+`, which acts as both the
+Registration Authority (or RA) and the CA. The RA serves as a gatekeeper
+that makes sure only verified CSR makes it through to the CA. Once the
+CSR is verified, it will be forwarded to the CA which will then issue a
+certificate containing a https://spiffe.io/[SPIFFE] identity with the
+service account. This certificate is called a SPIFFE verifiable identity
+document (or SVID). The SVID is assigned to the requesting service for
+identification purposes and to encrypt the traffic in transit between
+the communicating services.
+
+.Default flow for Istio Certificate Signing Requests
+image::./images/default-istio-csr-flow.png[Default flow for Istio
+Certificate Signing Requests]
+
+==== How Certificate Signing Works in Istio with ACM Private CA
+
+You can use a cert-manager add-on called the Istio Certificate Signing
+Request agent
+(https://cert-manager.io/docs/projects/istio-csr/[istio-csr]) to
+integrate Istio with ACM Private CA. This agent allows Istio workloads
+and control plane components to be secured with cert manager issuers, in
+this case ACM Private CA. The _istio-csr_ agent exposes the same service
+that _istiod_ serves in the default config of validating incoming CSRs.
+Except, after verification, it will convert the requests into resources
+that cert manager supports (i.e. integrations with external CA issuers).
+
+Whenever there’s a CSR from a workload, it will be forwarded to
+_istio-csr_, which will request certificates from ACM Private CA. This
+communication between _istio-csr_ and ACM Private CA is enabled by the
+https://github.com/cert-manager/aws-privateca-issuer[AWS Private CA
+issuer plugin]. Cert manager uses this plugin to request TLS
+certificates from ACM Private CA. The issuer plugin will communicate
+with the ACM Private CA service to request a signed certificate for the
+workload. Once the certificate has been signed, it will be returned to
+_istio-csr_, which will read the signed request, and return it to the
+workload that initiated the CSR.
+
+.Flow for Istio Certificate Signing Requests with istio-csr
+image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio
+Certificate Signing Requests with istio-csr]
+
+==== Istio with Private CA Setup Instructions
+
+[arabic]
+. Start by following the same
+link:#acm-private-ca-with-cert-manager[setup instructions in this
+section] to complete the following:
+. Create a Private CA
+. Install cert-manager
+. Install the issuer plugin
+. Set permissions and create an issuer. The issuer represents the CA and
+is used to sign `+istiod+` and mesh workload certificates. It will
+communicate with ACM Private CA.
+. Create an `+istio-system+` namespace. This is where the
+`+istiod certificate+` and other Istio resources will be deployed.
+. Install Istio CSR configured with AWS Private CA Issuer Plugin. You
+can preserve the certificate signing requests for workloads to verify
+that they get approved and signed
+(`+preserveCertificateRequests=true+`).
++
+[source,bash]
+----
+helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \
+--set "app.certmanager.issuer.group=awspca.cert-manager.io" \
+--set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \
+--set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \
+--set "app.certmanager.preserveCertificateRequests=true" \
+--set "app.server.maxCertificateDuration=48h" \
+--set "app.tls.certificateDuration=24h" \
+--set "app.tls.istiodCertificateDuration=24h" \
+--set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \
+--set "volumeMounts[0].name=root-ca" \
+--set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \
+--set "volumes[0].name=root-ca" \
+--set "volumes[0].secret.secretName=istio-root-ca"
+----
+. Install Istio with custom configurations to replace `+istiod+` with
+`+cert-manager istio-csr+` as the certificate provider for the mesh.
+This process can be carried out using the
+https://tetrate.io/blog/what-is-istio-operator/[Istio Operator].
++
+[source,yaml]
+----
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+metadata:
+  name: istio
+  namespace: istio-system
+spec:
+  profile: "demo"
+  hub: gcr.io/istio-release
+  values:
+  global:
+    # Change certificate provider to cert-manager istio agent for istio agent
+    caAddress: cert-manager-istio-csr.cert-manager.svc:443
+  components:
+    pilot:
+      k8s:
+        env:
+          # Disable istiod CA Sever functionality
+        - name: ENABLE_CA_SERVER
+          value: "false"
+        overlays:
+        - apiVersion: apps/v1
+          kind: Deployment
+          name: istiod
+          patches:
+
+            # Mount istiod serving and webhook certificate from Secret mount
+          - path: spec.template.spec.containers.[name:discovery].args[7]
+            value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt"
+          - path: spec.template.spec.containers.[name:discovery].args[8]
+            value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key"
+          - path: spec.template.spec.containers.[name:discovery].args[9]
+            value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem"
+
+          - path: spec.template.spec.containers.[name:discovery].volumeMounts[6]
+            value:
+              name: cert-manager
+              mountPath: "/etc/cert-manager/tls"
+              readOnly: true
+          - path: spec.template.spec.containers.[name:discovery].volumeMounts[7]
+            value:
+              name: ca-root-cert
+              mountPath: "/etc/cert-manager/ca"
+              readOnly: true
+
+          - path: spec.template.spec.volumes[6]
+            value:
+              name: cert-manager
+              secret:
+                secretName: istiod-tls
+          - path: spec.template.spec.volumes[7]
+            value:
+              name: ca-root-cert
+              configMap:
+                defaultMode: 420
+                name: istio-ca-root-cert
+----
+. Deploy the above custom resource you created.
++
+[source,bash]
+----
+istioctl operator init
+kubectl apply -f istio-custom-config.yaml
+----
+. Now you can deploy a workload to the mesh in your EKS cluster and
+https://istio.io/latest/docs/reference/config/security/peer_authentication/[enforce
+mTLS].
+
+.Istio certificate signing requests
+image::./images/istio-csr-requests.png[Istio certificate signing
+requests]
+
+== Tools and resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/6-network-security[Amazon
+EKS Security Immersion Workshop - Network security]
+* https://aws.amazon.com/blogs/security/tls-enabled-kubernetes-clusters-with-acm-private-ca-and-amazon-eks-2/[How
+to implement cert-manager and the ACM Private CA plugin to enable TLS in
+EKS].
+* https://aws.amazon.com/blogs/containers/setting-up-end-to-end-tls-encryption-on-amazon-eks-with-the-new-aws-load-balancer-controller/[Setting
+up end-to-end TLS encryption on Amazon EKS with the new AWS Load
+Balancer Controller and ACM Private CA].
+* https://github.com/cert-manager/aws-privateca-issuer[Private CA
+Kubernetes cert-manager plugin on GitHub].
+* https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaKubernetes.html[Private
+CA Kubernetes cert-manager plugin user guide].
+* https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[How
+to use AWS Private Certificate Authority short-lived certificate mode]
+* https://itnext.io/verifying-service-mesh-tls-in-kubernetes-using-ksniff-and-wireshark-2e993b26bf95[Verifying
+Service Mesh TLS in Kubernetes&#44; Using ksniff and Wireshark]
+* https://github.com/eldadru/ksniff[ksniff]
+* https://github.com/monzo/egress-operator[egress-operator] An operator
+and DNS plugin to control egress traffic from your cluster without
+protocol inspection
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides policy network rules,
+data loss prevention (DLP), web application firewall (WAF) and network
+threat signatures.
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Data encryption and secrets management
+
+== Encryption at rest
+
+There are three different AWS-native storage options you can use with
+Kubernetes:
+https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html[EBS],
+https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html[EFS],
+and https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html[FSx
+for Lustre]. All three offer encryption at rest using a service managed
+key or a customer master key (CMK). For EBS you can use the in-tree
+storage driver or the
+https://github.com/kubernetes-sigs/aws-ebs-csi-driver[EBS CSI driver].
+Both include parameters for encrypting volumes and supplying a CMK. For
+EFS, you can use the
+https://github.com/kubernetes-sigs/aws-efs-csi-driver[EFS CSI driver],
+however, unlike EBS, the EFS CSI driver does not support dynamic
+provisioning. If you want to use EFS with EKS, you will need to
+provision and configure at-rest encryption for the file system prior to
+creating a PV. For further information about EFS file encryption, please
+refer to
+https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html[Encrypting
+Data at Rest]. Besides offering at-rest encryption, EFS and FSx for
+Lustre include an option for encrypting data in transit. FSx for Lustre
+does this by default. For EFS, you can add transport encryption by
+adding the `+tls+` parameter to `+mountOptions+` in your PV as in this
+example:
+
+[source,yaml]
+----
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+  name: efs-pv
+spec:
+  capacity:
+    storage: 5Gi
+  volumeMode: Filesystem
+  accessModes:
+    - ReadWriteOnce
+  persistentVolumeReclaimPolicy: Retain
+  storageClassName: efs-sc
+  mountOptions:
+    - tls
+  csi:
+    driver: efs.csi.aws.com
+    volumeHandle: <file_system_id>
+----
+
+The https://github.com/kubernetes-sigs/aws-fsx-csi-driver[FSx CSI
+driver] supports dynamic provisioning of Lustre file systems. It
+encrypts data with a service managed key by default, although there is
+an option to provide your own CMK as in this example:
+
+[source,yaml]
+----
+kind: StorageClass
+apiVersion: storage.k8s.io/v1
+metadata:
+  name: fsx-sc
+provisioner: fsx.csi.aws.com
+parameters:
+  subnetId: subnet-056da83524edbe641
+  securityGroupIds: sg-086f61ea73388fb6b
+  deploymentType: PERSISTENT_1
+  kmsKeyId: <kms_arn>
+----
+
+!!! attention As of May 28, 2020 all data written to the ephemeral
+volume in EKS Fargate pods is encrypted by default using an
+industry-standard AES-256 cryptographic algorithm. No modifications to
+your application are necessary as encryption and decryption are handled
+seamlessly by the service.
+
+=== Encrypt data at rest
+
+Encrypting data at rest is considered a best practice. If you’re unsure
+whether encryption is necessary, encrypt your data.
+
+=== Rotate your CMKs periodically
+
+Configure KMS to automatically rotate your CMKs. This will rotate your
+keys once a year while saving old keys indefinitely so that your data
+can still be decrypted. For additional information see
+https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html[Rotating
+customer master keys]
+
+=== Use EFS access points to simplify access to shared datasets
+
+If you have shared datasets with different POSIX file permissions or
+want to restrict access to part of the shared file system by creating
+different mount points, consider using EFS access points. To learn more
+about working with access points, see
+https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today,
+if you want to use an access point (AP) you’ll need to reference the AP
+in the PV’s `+volumeHandle+` parameter.
+
+!!! attention As of March 23, 2021 the EFS CSI driver supports dynamic
+provisioning of EFS Access Points. Access points are
+application-specific entry points into an EFS file system that make it
+easier to share a file system between multiple pods. Each EFS file
+system can have up to 120 PVs. See
+https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/[Introducing
+Amazon EFS CSI dynamic provisioning] for additional information.
+
+== Secrets management
+
+Kubernetes secrets are used to store sensitive information, such as user
+certificates, passwords, or API keys. They are persisted in etcd as
+base64 encoded strings. On EKS, the EBS volumes for etcd nodes are
+encrypted with
+https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html[EBS
+encryption]. A pod can retrieve a Kubernetes secrets objects by
+referencing the secret in the `+podSpec+`. These secrets can either be
+mapped to an environment variable or mounted as volume. For additional
+information on creating secrets, see
+https://kubernetes.io/docs/concepts/configuration/secret/.
+
+!!! caution Secrets in a particular namespace can be referenced by all
+pods in the secret’s namespace.
+
+!!! caution The node authorizer allows the Kubelet to read all of the
+secrets mounted to the node.
+
+=== Use AWS KMS for envelope encryption of Kubernetes secrets
+
+This allows you to encrypt your secrets with a unique data encryption
+key (DEK). The DEK is then encrypted using a key encryption key (KEK)
+from AWS KMS which can be automatically rotated on a recurring schedule.
+With the KMS plugin for Kubernetes, all Kubernetes secrets are stored in
+etcd in ciphertext instead of plain text and can only be decrypted by
+the Kubernetes API server. For additional details, see
+https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/[using
+EKS encryption provider support for defense in depth]
+
+=== Audit the use of Kubernetes Secrets
+
+On EKS, turn on audit logging and create a CloudWatch metrics filter and
+alarm to alert you when a secret is used (optional). The following is an
+example of a metrics filter for the Kubernetes audit log,
+`+{($.verb="get") && ($.objectRef.resource="secret")}+`. You can also
+use the following queries with CloudWatch Log Insights:
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| stats count(*) by objectRef.name as secret
+| filter verb="get" and objectRef.resource="secrets"
+----
+
+The above query will display the number of times a secret has been
+accessed within a specific timeframe.
+
+[source,bash]
+----
+fields @timestamp, @message
+| sort @timestamp desc
+| limit 100
+| filter verb="get" and objectRef.resource="secrets"
+| display objectRef.namespace, objectRef.name, user.username, responseStatus.code
+----
+
+This query will display the secret, along with the namespace and
+username of the user who attempted to access the secret and the response
+code.
+
+=== Rotate your secrets periodically
+
+Kubernetes doesn’t automatically rotate secrets. If you have to rotate
+secrets, consider using an external secret store, e.g. Vault or AWS
+Secrets Manager.
+
+=== Use separate namespaces as a way to isolate secrets from different applications
+
+If you have secrets that cannot be shared between applications in a
+namespace, create a separate namespace for those applications.
+
+=== Use volume mounts instead of environment variables
+
+The values of environment variables can unintentionally appear in logs.
+Secrets mounted as volumes are instantiated as tmpfs volumes (a RAM
+backed file system) that are automatically removed from the node when
+the pod is deleted.
+
+=== Use an external secrets provider
+
+There are several viable alternatives to using Kubernetes secrets,
+including https://aws.amazon.com/secrets-manager/[AWS Secrets Manager]
+and Hashicorp’s
+https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar/[Vault].
+These services offer features such as fine grained access controls,
+strong encryption, and automatic rotation of secrets that are not
+available with Kubernetes Secrets. Bitnami’s
+https://github.com/bitnami-labs/sealed-secrets[Sealed Secrets] is
+another approach that uses asymmetric encryption to create "`sealed
+secrets`". A public key is used to encrypt the secret while the private
+key used to decrypt the secret is kept within the cluster, allowing you
+to safely store sealed secrets in source control systems like Git. See
+https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/[Managing
+secrets deployment in Kubernetes using Sealed Secrets] for further
+information.
+
+As the use of external secrets stores has grown, so has need for
+integrating them with Kubernetes. The
+https://github.com/kubernetes-sigs/secrets-store-csi-driver[Secret Store
+CSI Driver] is a community project that uses the CSI driver model to
+fetch secrets from external secret stores. Currently, the Driver has
+support for
+https://github.com/aws/secrets-store-csi-driver-provider-aws[AWS Secrets
+Manager], Azure, Vault, and GCP. The AWS provider supports both AWS
+Secrets Manager *and* AWS Parameter Store. It can also be configured to
+rotate secrets when they expire and can synchronize AWS Secrets Manager
+secrets to Kubernetes Secrets. Synchronization of secrets can be useful
+when you need to reference a secret as an environment variable instead
+of reading them from a volume.
+
+!!! note When the the secret store CSI driver has to fetch a secret, it
+assumes the IRSA role assigned to the pod that references a secret. The
+code for this operation can be found
+https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go[here].
+
+For additional information about the AWS Secrets & Configuration
+Provider (ASCP) refer to the following resources:
+
+* https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-configuration-provider-with-kubernetes-secrets-store-csi-driver/[How
+to use AWS Secrets Configuration Provider with Kubernetes Secret Store
+CSI Driver]
+* https://docs.aws.amazon.com/secretsmanager/latest/userguide/integrating_csi_driver.html[Integrating
+Secrets Manager secrets with Kubernetes Secrets Store CSI Driver]
+
+https://github.com/external-secrets/external-secrets[external-secrets]
+is yet another way to use an external secret store with Kubernetes. Like
+the CSI Driver, external-secrets works against a variety of different
+backends, including AWS Secrets Manager. The difference is, rather than
+retrieving secrets from the external secret store, external-secrets
+copies secrets from these backends to Kubernetes as Secrets. This lets
+you manage secrets using your preferred secret store and interact with
+secrets in a Kubernetes-native way.
+
+== Tools and resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/13-data-encryption-and-secret-management[Amazon
+EKS Security Immersion Workshop - Data Encryption and Secrets
+Management]
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Runtime security
+
+Runtime security provides active protection for your containers while
+they’re running. The idea is to detect and/or prevent malicious activity
+from occurring inside the container. This can be achieved with a number
+of mechanisms in the Linux kernel or kernel extensions that are
+integrated with Kubernetes, such as Linux capabilities, secure computing
+(seccomp), AppArmor, or SELinux. There are also options like Amazon
+GuardDuty and third party tools that can assist with establishing
+baselines and detecting anomalous activity with less manual
+configuration of Linux kernel mechanisms.
+
+!!! attention Kubernetes does not currently provide any native
+mechanisms for loading seccomp, AppArmor, or SELinux profiles onto
+Nodes. They either have to be loaded manually or installed onto Nodes
+when they are bootstrapped. This has to be done prior to referencing
+them in your Pods because the scheduler is unaware of which nodes have
+profiles. See below how tools like Security Profiles Operator can help
+automate provisioning of profiles onto nodes.
+
+== Security contexts and built-in Kubernetes controls
+
+Many Linux runtime security mechanisms are tightly integrated with
+Kubernetes and can be configured through Kubernetes
+https://kubernetes.io/docs/tasks/configure-pod-container/security-context/[security
+contexts]. One such option is the `+privileged+` flag, which is
+`+false+` by default and if enabled is essentially equivalent to root on
+the host. It is nearly always inappropriate to enable privileged mode in
+production workloads, but there are many more controls that can provide
+more granular privileges to containers as appropriate.
+
+=== Linux capabilities
+
+Linux capabilities allow you to grant certain capabilities to a Pod or
+container without providing all the abilities of the root user. Examples
+include `+CAP_NET_ADMIN+`, which allows configuring network interfaces
+or firewalls, or `+CAP_SYS_TIME+`, which allows manipulation of the
+system clock.
+
+=== Seccomp
+
+With secure computing (seccomp) you can prevent a containerized
+application from making certain syscalls to the underlying host
+operating system’s kernel. While the Linux operating system has a few
+hundred system calls, the lion’s share of them are not necessary for
+running containers. By restricting what syscalls can be made by a
+container, you can effectively decrease your application’s attack
+surface.
+
+Seccomp works by intercepting syscalls and only allowing those that have
+been allowlisted to pass through. Docker has a
+https://github.com/moby/moby/blob/master/profiles/seccomp/default.json[default]
+seccomp profile which is suitable for a majority of general purpose
+workloads, and other container runtimes like containerd provide
+comparable defaults. You can configure your container or Pod to use the
+container runtime’s default seccomp profile by adding the following to
+the `+securityContext+` section of the Pod spec:
+
+[source,yaml]
+----
+securityContext:
+  seccompProfile:
+    type: RuntimeDefault
+----
+
+As of 1.22 (in alpha, stable as of 1.27), the above `+RuntimeDefault+`
+can be used for all Pods on a Node using a
+https://kubernetes.io/docs/tutorials/security/seccomp/#enable-the-use-of-runtimedefault-as-the-default-seccomp-profile-for-all-workloads[single
+kubelet flag], `+--seccomp-default+`. Then the profile specified in
+`+securityContext+` is only needed for other profiles.
+
+It’s also possible to create your own profiles for things that require
+additional privileges. This can be very tedious to do manually, but
+there are tools like
+https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget]
+(also recommended in the link:../network/[network security section] for
+generating network policies) and
+https://github.com/inspektor-gadget/inspektor-gadget[Security Profiles
+Operator] that support using tools like eBPF or logs to record baseline
+privilege requirements as seccomp profiles. Security Profiles Operator
+further allows automating the deployment of recorded profiles to nodes
+for use by Pods and containers.
+
+=== AppArmor and SELinux
+
+AppArmor and SELinux are known as
+https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access
+control or MAC systems]. They are similar in concept to seccomp but with
+different APIs and abilities, allowing access control for e.g. specific
+filesystem paths or network ports. Support for these tools depends on
+the Linux distribution, with Debian/Ubuntu supporting AppArmor and
+RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see
+the link:../hosts/#run-selinux[infrastructure security section] for
+further discussion of SELinux.
+
+Both AppArmor and SELinux are integrated with Kubernetes, but as of
+Kubernetes 1.28 AppArmor profiles must be specified via
+https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod[annotations]
+while SELinux labels can be set through the
+https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#selinuxoptions-v1-core[SELinuxOptions]
+field on the security context directly.
+
+As with seccomp profiles, the Security Profiles Operator mentioned above
+can assist with deploying profiles onto nodes in the cluster. (In the
+future, the project also aims to generate profiles for AppArmor and
+SELinux as it does for seccomp.)
+
+== Recommendations
+
+=== Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments
+
+If you do not currently have a solution for continuously monitoring EKS
+runtimes and analyzing EKS audit logs, and scanning for malware and
+other suspicious activity, Amazon strongly recommends the use of
+https://aws.amazon.com/guardduty/[Amazon GuardDuty] for customers who
+want a simple, fast, secure, scalable, and cost-effective one-click way
+to protect their AWS environments. Amazon GuardDuty is a security
+monitoring service that analyzes and processes foundational data
+sources, such as AWS CloudTrail management events, AWS CloudTrail event
+logs, VPC flow logs (from Amazon EC2 instances), Kubernetes audit logs,
+and DNS logs. It also includes EKS runtime monitoring. It uses
+continuously updated threat intelligence feeds, such as lists of
+malicious IP addresses and domains, and machine learning to identify
+unexpected, potentially unauthorized, and malicious activity within your
+AWS environment. This can include issues like escalation of privileges,
+use of exposed credentials, or communication with malicious IP
+addresses, domains, presence of malware on your Amazon EC2 instances and
+EKS container workloads, or discovery of suspicious API activity.
+GuardDuty informs you of the status of your AWS environment by producing
+security findings that you can view in the GuardDuty console or through
+Amazon EventBridge. GuardDuty also provides support for you to export
+your findings to an Amazon Simple Storage Service (S3) bucket, and
+integrate with other services such as AWS Security Hub and Detective.
+
+Watch this AWS Online Tech Talk
+https://www.youtube.com/watch?v=oNHGRRroJuE["`Enhanced threat detection
+for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks`"] to see
+how to enable these additional EKS security features step-by-step in
+minutes.
+
+=== Optionally: Use a 3rd party solution for runtime monitoring
+
+Creating and managing seccomp and Apparmor profiles can be difficult if
+you’re not familiar with Linux security. If you don’t have the time to
+become proficient, consider using a 3rd party commercial solution. A lot
+of them have moved beyond static profiles like Apparmor and seccomp and
+have begun using machine learning to block or alert on suspicious
+activity. A handful of these solutions can be found below in the
+link:#tools-and-resources[tools] section. Additional options can be
+found on the https://aws.amazon.com/marketplace/features/containers[AWS
+Marketplace for Containers].
+
+=== Consider add/dropping Linux capabilities before writing seccomp policies
+
+Capabilities involve various checks in kernel functions reachable by
+syscalls. If the check fails, the syscall typically returns an error.
+The check can be done either right at the beginning of a specific
+syscall, or deeper in the kernel in areas that might be reachable
+through multiple different syscalls (such as writing to a specific
+privileged file). Seccomp, on the other hand, is a syscall filter which
+is applied to all syscalls before they are run. A process can set up a
+filter which allows them to revoke their right to run certain syscalls,
+or specific arguments for certain syscalls.
+
+Before using seccomp, consider whether adding/removing Linux
+capabilities gives you the control you need. See
+https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container[Setting
+capabilities for- containers] for further information.
+
+=== See whether you can accomplish your aims by using Pod Security Policies (PSPs)
+
+Pod Security Policies offer a lot of different ways to improve your
+security posture without introducing undue complexity. Explore the
+options available in PSPs before venturing into building seccomp and
+Apparmor profiles.
+
+!!! warning As of Kubernetes 1.25, PSPs have been removed and replaced
+with the
+https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod
+Security Admission] controller. Third-party alternatives which exist
+include OPA/Gatekeeper and Kyverno. A collection of Gatekeeper
+constraints and constraint templates for implementing policies commonly
+found in PSPs can be pulled from the
+https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy[Gatekeeper
+library] repository on GitHub. And many replacements for PSPs can be
+found in the https://main.kyverno.io/policies/[Kyverno policy library]
+including the full collection of
+https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod
+Security Standards].
+
+== Tools and Resources
+
+* https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6[7
+things you should know before you start]
+* https://github.com/kubernetes/kubernetes/tree/master/test/images/apparmor-loader[AppArmor
+Loader]
+* https://kubernetes.io/docs/tutorials/clusters/apparmor/#setting-up-nodes-with-profiles[Setting
+up nodes with profiles]
+* https://github.com/kubernetes-sigs/security-profiles-operator[Security
+Profiles Operator] is a Kubernetes enhancement which aims to make it
+easier for users to use SELinux, seccomp and AppArmor in Kubernetes
+clusters. It provides capabilities for both generating profiles from
+running workloads and loading profiles onto Kubernetes nodes for use in
+Pods.
+* https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget]
+allows inspecting, tracing, and profiling many aspects of runtime
+behavior on Kubernetes, including assisting in the generation of seccomp
+profiles.
+* https://www.aquasec.com/products/aqua-cloud-native-security-platform/[Aqua]
+* https://www.qualys.com/apps/container-security/[Qualys]
+* https://www.stackrox.com/use-cases/threat-detection/[Stackrox]
+* https://sysdig.com/products/kubernetes-security/[Sysdig Secure]
+* https://docs.paloaltonetworks.com/cn-series[Prisma]
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides process profile rules
+and file access rules.
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Protecting the infrastructure (hosts)
+
+Inasmuch as it’s important to secure your container images, it’s equally
+important to safeguard the infrastructure that runs them. This section
+explores different ways to mitigate risks from attacks launched directly
+against the host. These guidelines should be used in conjunction with
+those outlined in the link:runtime.md[Runtime Security] section.
+
+== Recommendations
+
+=== Use an OS optimized for running containers
+
+Consider using Flatcar Linux, Project Atomic, RancherOS, and
+https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a
+special purpose OS from AWS designed for running Linux containers. It
+includes a reduced attack surface, a disk image that is verified on
+boot, and enforced permission boundaries using SELinux.
+
+Alternately, use the
+https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html[EKS
+optimized AMI] for your Kubernetes worker nodes. The EKS optimized AMI
+is released regularly and contains a minimal set of OS packages and
+binaries necessary to run your containerized workloads.
+
+Please refer https://github.com/aws-samples/amazon-eks-ami-rhel[Amazon
+EKS AMI RHEL Build Specification] for a sample configuration script
+which can be used for building a custom Amazon EKS AMI running on Red
+Hat Enterprise Linux using Hashicorp Packer. This script can be further
+leveraged to build STIG compliant EKS custom AMIs.
+
+=== Keep your worker node OS updated
+
+Regardless of whether you use a container-optimized host OS like
+Bottlerocket or a larger, but still minimalist, Amazon Machine Image
+like the EKS optimized AMIs, it is best practice to keep these host OS
+images up to date with the latest security patches.
+
+For the EKS optimized AMIs, regularly check the
+https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md[CHANGELOG]
+and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes
+channel] and automate the rollout of updated worker node images into
+your cluster.
+
+=== Treat your infrastructure as immutable and automate the replacement of your worker nodes
+
+Rather than performing in-place upgrades, replace your workers when a
+new patch or update becomes available. This can be approached a couple
+of ways. You can either add instances to an existing autoscaling group
+using the latest AMI as you sequentially cordon and drain nodes until
+all of the nodes in the group have been replaced with the latest AMI.
+Alternatively, you can add instances to a new node group while you
+sequentially cordon and drain nodes from the old node group until all of
+the nodes have been replaced. EKS
+https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed
+node groups] uses the first approach and will display a message in the
+console to upgrade your workers when a new AMI becomes available.
+`+eksctl+` also has a mechanism for creating node groups with the latest
+AMI and for gracefully cordoning and draining pods from nodes groups
+before the instances are terminated. If you decide to use a different
+method for replacing your worker nodes, it is strongly recommended that
+you automate the process to minimize human oversight as you will likely
+need to replace workers regularly as new updates/patches are released
+and when the control plane is upgraded.
+
+With EKS Fargate, AWS will automatically update the underlying
+infrastructure as updates become available. Oftentimes this can be done
+seamlessly, but there may be times when an update will cause your pod to
+be rescheduled. Hence, we recommend that you create deployments with
+multiple replicas when running your application as a Fargate pod.
+
+=== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes]
+
+kube-bench is an open source project from Aqua that evaluates your
+cluster against the CIS benchmarks for Kubernetes. The benchmark
+describes the best practices for securing unmanaged Kubernetes clusters.
+The CIS Kubernetes Benchmark encompasses the control plane and the data
+plane. Since Amazon EKS provides a fully managed control plane, not all
+of the recommendations from the CIS Kubernetes Benchmark are applicable.
+To ensure this scope reflects how Amazon EKS is implemented, AWS created
+the _CIS Amazon EKS Benchmark_. The EKS benchmark inherits from CIS
+Kubernetes Benchmark with additional inputs from the community with
+specific configuration considerations for EKS clusters.
+
+When running https://github.com/aquasecurity/kube-bench[kube-bench]
+against an EKS cluster, follow
+https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster[these
+instructions] from Aqua Security. For further information see
+https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing
+The CIS Amazon EKS Benchmark].
+
+=== Minimize access to worker nodes
+
+Instead of enabling SSH access, use
+https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM
+Session Manager] when you need to remote into a host. Unlike SSH keys
+which can be lost, copied, or shared, Session Manager allows you to
+control access to EC2 instances using IAM. Moreover, it provides an
+audit trail and log of the commands that were run on the instance.
+
+As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2
+Launch Templates. This allows you to embed the SSM agent into the AMI or
+install it as the worker node is being bootstrapped. If you rather not
+modify the Optimized AMI or the ASG’s launch template, you can install
+the SSM agent with a DaemonSet as in
+https://github.com/aws-samples/ssm-agent-daemonset-installer[this
+example].
+
+==== Minimal IAM policy for SSM based SSH Access
+
+The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a
+number of permissions that are not required for SSM Session Manager /
+SSM RunCommand if you’re just looking to avoid SSH access. Of concern
+specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which
+would allow for the role to access all parameters in Parameter Store
+(including SecureStrings with the AWS managed KMS key configured).
+
+The following IAM policy contains the minimal set of permissions to
+enable node access via SSM Systems Manager.
+
+[source,json]
+----
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "EnableAccessViaSSMSessionManager",
+      "Effect": "Allow",
+      "Action": [
+        "ssmmessages:OpenDataChannel",
+        "ssmmessages:OpenControlChannel",
+        "ssmmessages:CreateDataChannel",
+        "ssmmessages:CreateControlChannel",
+        "ssm:UpdateInstanceInformation"
+      ],
+      "Resource": "*"
+    },
+    {
+      "Sid": "EnableSSMRunCommand",
+      "Effect": "Allow",
+      "Action": [
+        "ssm:UpdateInstanceInformation",
+        "ec2messages:SendReply",
+        "ec2messages:GetMessages",
+        "ec2messages:GetEndpoint",
+        "ec2messages:FailMessage",
+        "ec2messages:DeleteMessage",
+        "ec2messages:AcknowledgeMessage"
+      ],
+      "Resource": "*"
+    }
+  ]
+}
+----
+
+With this policy in place and the
+https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html[Session
+Manager plugin] installed, you can then run
+
+[source,bash]
+----
+aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE]
+----
+
+to access the node.
+
+!!! note You may also want to consider adding permissions to
+https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable
+Session Manager logging].
+
+=== Deploy workers onto private subnets
+
+By deploying workers onto private subnets, you minimize their exposure
+to the Internet where attacks often originate. Beginning April 22, 2020,
+the assignment of public IP addresses to nodes in a managed node groups
+will be controlled by the subnet they are deployed onto. Prior to this,
+nodes in a Managed Node Group were automatically assigned a public IP.
+If you choose to deploy your worker nodes on to public subnets,
+implement restrictive AWS security group rules to limit their exposure.
+
+=== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices
+
+You can use
+https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon
+Inspector] to check for unintended network access to your nodes and for
+vulnerabilities on the underlying Amazon EC2 instances.
+
+Amazon Inspector can provide common vulnerabilities and exposures (CVE)
+data for your Amazon EC2 instances only if the Amazon EC2 Systems
+Manager (SSM) agent is installed and enabled. This agent is preinstalled
+on several
+https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html[Amazon
+Machine Images (AMIs)] including
+https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS
+optimized Amazon Linux AMIs]. Regardless of SSM agent status, all of
+your Amazon EC2 instances are scanned for network reachability issues.
+For more information about configuring scans for Amazon EC2, see
+https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html[Scanning
+Amazon EC2 instances].
+
+!!! attention Inspector cannot be run on the infrastructure used to run
+Fargate pods.
+
+== Alternatives
+
+=== Run SELinux
+
+!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS,
+Bottlerocket, and Amazon Linux 2023
+
+SELinux provides an additional layer of security to keep containers
+isolated from each other and from the host. SELinux allows
+administrators to enforce mandatory access controls (MAC) for every
+user, application, process, and file. Think of it as a backstop that
+restricts the operations that can be performed against to specific
+resources based on a set of labels. On EKS, SELinux can be used to
+prevent containers from accessing each other’s resources.
+
+Container SELinux policies are defined in the
+https://github.com/containers/container-selinux[container-selinux]
+package. Docker CE requires this package (along with its dependencies)
+so that the processes and files created by Docker (or other container
+runtimes) run with limited system access. Containers leverage the
+`+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These
+policies effectively prevent containers from accessing certain features
+of the host.
+
+When you configure SELinux for Docker, Docker automatically labels
+workloads `+container_t+` as a type and gives each container a unique
+MCS level. This will isolate containers from one another. If you need
+looser restrictions, you can create your own profile in SElinux which
+grants a container permissions to specific areas of the file system.
+This is similar to PSPs in that you can create different profiles for
+different containers/pods. For example, you can have a profile for
+general workloads with a set of restrictive controls and another for
+things that require privileged access.
+
+SELinux for Containers has a set of options that can be configured to
+modify the default restrictions. The following SELinux Booleans can be
+enabled or disabled based on your needs:
+
+[width="100%",cols="30%,^40%,30%",options="header",]
+|===
+|Boolean |Default |Description
+|`+container_connect_any+` |`+off+` |Allow containers to access
+privileged ports on the host. For example, if you have a container that
+needs to map ports to 443 or 80 on the host.
+
+|`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup
+configuration. For example, a container running systemd will need this
+to be enabled.
+
+|`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file
+system.
+|===
+
+By default, containers are allowed to read/execute under `+/usr+` and
+read most content from `+/etc+`. The files under `+/var/lib/docker+` and
+`+/var/lib/containers+` have the label `+container_var_lib_t+`. To view
+a full list of default, labels see the
+https://github.com/containers/container-selinux/blob/master/container.fc[container.fc]
+file.
+
+[source,bash]
+----
+docker container run -it \
+  -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \
+  centos:7 cat /host/repositories.json
+# cat: /host/repositories.json: Permission denied
+
+docker container run -it \
+  -v /etc/passwd:/host/etc/passwd \
+  centos:7 cat /host/etc/passwd
+# cat: /host/etc/passwd: Permission denied
+----
+
+Files labeled with `+container_file_t+` are the only files that are
+writable by containers. If you want a volume mount to be writeable, you
+will needed to specify `+:z+` or `+:Z+` at the end.
+
+* `+:z+` will re-label the files so that the container can read/write
+* `+:Z+` will re-label the files so that *only* the container can
+read/write
+
+[source,bash]
+----
+ls -Z /var/lib/misc
+# -rw-r--r--. root root system_u:object_r:var_lib_t:s0   postfix.aliasesdb-stamp
+
+docker container run -it \
+  -v /var/lib/misc:/host/var/lib/misc:z \
+  centos:7 echo "Relabeled!"
+
+ls -Z /var/lib/misc
+#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp
+----
+
+[source,bash]
+----
+docker container run -it \
+  -v /var/log:/host/var/log:Z \
+  fluentbit:latest
+----
+
+In Kubernetes, relabeling is slightly different. Rather than having
+Docker automatically relabel the files, you can specify a custom MCS
+label to run the pod. Volumes that support relabeling will automatically
+be relabeled so that they are accessible. Pods with a matching MCS label
+will be able to access the volume. If you need strict isolation, set a
+different MCS label for each pod.
+
+[source,yaml]
+----
+securityContext:
+  seLinuxOptions:
+    # Provide a unique MCS label per container
+    # You can specify user, role, and type also
+    # enforcement based on type and level (svert)
+    level: s0:c144:c154
+----
+
+In this example `+s0:c144:c154+` corresponds to an MCS label assigned to
+a file that the container is allowed to access.
+
+On EKS you could create policies that allow for privileged containers to
+run, like FluentD and create an SELinux policy to allow it to read from
+/var/log on the host without needing to relabel the host directory. Pods
+with the same label will be able to access the same host volumes.
+
+We have implemented
+https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for
+Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These
+AMIs were developed to demonstrate sample implementations that meet
+requirements of highly regulated customers, such as STIG, CJIS, and C2S.
+
+!!! caution SELinux will ignore containers where the type is unconfined.
+
+== Tools and resources
+
+* https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux
+Kubernetes RBAC and Shipping Security Policies for On-prem Applications]
+* https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html[Iterative
+Hardening of Kubernetes]
+* https://linux.die.net/man/1/audit2allow[Audit2Allow]
+* https://linux.die.net/man/8/sealert[SEAlert]
+* https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica[Generate
+SELinux policies for containers with Udica] describes a tool that looks
+at container spec files for Linux capabilities, ports, and mount points,
+and generates a set of SELinux rules that allow the container to run
+properly
+* https://github.com/aws-samples/amazon-eks-custom-amis#hardening[AMI
+Hardening] playbooks for hardening the OS to meet different regulatory
+requirements
+* https://github.com/keikoproj/upgrade-manager[Keiko Upgrade Manager] an
+open source project from Intuit that orchestrates the rotation of worker
+nodes.
+* https://sysdig.com/products/kubernetes-security/[Sysdig Secure]
+* https://eksctl.io/[eksctl]
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Compliance
+
+Compliance is a shared responsibility between AWS and the consumers of
+its services. Generally speaking, AWS is responsible for "`security of
+the cloud`" whereas its users are responsible for "`security in the
+cloud.`" The line that delineates what AWS and its users are responsible
+for will vary depending on the service. For example, with Fargate, AWS
+is responsible for managing the physical security of its data centers,
+the hardware, the virtual infrastructure (Amazon EC2), and the container
+runtime (Docker). Users of Fargate are responsible for securing the
+container image and their application. Knowing who is responsible for
+what is an important consideration when running workloads that must
+adhere to compliance standards.
+
+The following table shows the compliance programs with which the
+different container services conform.
+
+[width="99%",cols="30%,^17%,^17%,^19%,^17%",options="header",]
+|===
+|Compliance Program |Amazon ECS Orchestrator |Amazon EKS Orchestrator
+|ECS Fargate |Amazon ECR
+|PCI DSS Level 1 |1 |1 |1 |1
+
+|HIPAA Eligible |1 |1 |1 |1
+
+|SOC I |1 |1 |1 |1
+
+|SOC II |1 |1 |1 |1
+
+|SOC III |1 |1 |1 |1
+
+|ISO 27001:2013 |1 |1 |1 |1
+
+|ISO 9001:2015 |1 |1 |1 |1
+
+|ISO 27017:2015 |1 |1 |1 |1
+
+|ISO 27018:2019 |1 |1 |1 |1
+
+|IRAP |1 |1 |1 |1
+
+|FedRAMP Moderate (East/West) |1 |1 |0 |1
+
+|FedRAMP High (GovCloud) |1 |1 |0 |1
+
+|DOD CC SRG |1 |DISA Review (IL5) |0 |1
+
+|HIPAA BAA |1 |1 |1 |1
+
+|MTCS |1 |1 |0 |1
+
+|C5 |1 |1 |0 |1
+
+|K-ISMS |1 |1 |0 |1
+
+|ENS High |1 |1 |0 |1
+
+|OSPAR |1 |1 |0 |1
+
+|HITRUST CSF |1 |1 |1 |1
+|===
+
+Compliance status changes over time. For the latest status, always refer
+to https://aws.amazon.com/compliance/services-in-scope/.
+
+For further information about cloud accreditation models and best
+practices, see the AWS whitepaper,
+https://d1.awsstatic.com/whitepapers/accreditation-models-for-secure-cloud-adoption.pdf[Accreditation
+Models for Secure Cloud Adoption]
+
+== Shifting Left
+
+The concept of shifting left involves catching policy violations and
+errors earlier in the software development lifecycle. From a security
+perspective, this can be very beneficial. A developer, for example, can
+fix issues with their configuration before their application is deployed
+to the cluster. Catching mistakes like this earlier will help prevent
+configurations that violate your policies from being deployed.
+
+=== Policy as Code
+
+Policy can be thought of as a set of rules for governing behaviors,
+i.e. behaviors that are allowed or those that are prohibited. For
+example, you may have a policy that says that all Dockerfiles should
+include a USER directive that causes the container to run as a non-root
+user. As a document, a policy like this can be hard to discover and
+enforce. It may also become outdated as your requirements change. With
+Policy as Code (PaC) solutions, you can automate security, compliance,
+and privacy controls that detect, prevent, reduce, and counteract known
+and persistent threats. Furthermore, they give you mechanism to codify
+your policies and manage them as you do other code artifacts. The
+benefit of this approach is that you can reuse your DevOps and GitOps
+strategies to manage and consistently apply policies across fleets of
+Kubernetes clusters. Please refer to
+https://aws.github.io/aws-eks-best-practices/security/docs/pods/#pod-security[Pod
+Security] for information about PaC options and the future of PSPs.
+
+=== Use policy-as-code tools in pipelines to detect violations before deployment
+
+* https://www.openpolicyagent.org/[OPA] is an open source policy engine
+that’s part of the CNCF. It’s used for making policy decisions and can
+be run a variety of different ways, e.g. as a language library or a
+service. OPA policies are written in a Domain Specific Language (DSL)
+called Rego. While it is often run as part of a Kubernetes Dynamic
+Admission Controller as the
+https://github.com/open-policy-agent/gatekeeper[Gatekeeper] project, OPA
+can also be incorporated into your CI/CD pipeline. This allows
+developers to get feedback about their configuration earlier in the
+release cycle which can subsequently help them resolve issues before
+they get to production. A collection of common OPA policies can be found
+in the GitHub
+https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository]
+for this project.
+* https://github.com/open-policy-agent/conftest[Conftest] is built on
+top of OPA and it provides a developer focused experience for testing
+Kubernetes configuration.
+* https://kyverno.io/[Kyverno] is a policy engine designed for
+Kubernetes. With Kyverno, policies are managed as Kubernetes resources
+and no new language is required to write policies. This allows using
+familiar tools such as kubectl, git, and kustomize to manage policies.
+Kyverno policies can validate, mutate, and generate Kubernetes resources
+plus ensure OCI image supply chain security. The
+https://kyverno.io/docs/kyverno-cli/[Kyverno CLI] can be used to test
+policies and validate resources as part of a CI/CD pipeline. All the
+Kyverno community policies can be found on the
+https://kyverno.io/policies/[Kyverno website], and for examples using
+the Kyverno CLI to write tests in pipelines, see the
+https://github.com/kyverno/policies[policies repository].
+
+== Tools and resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/10-regulatory-compliance[Amazon
+EKS Security Immersion Workshop - Regulatory Compliance]
+* https://github.com/aquasecurity/kube-bench[kube-bench]
+* https://github.com/docker/docker-bench-security[docker-bench-security]
+* https://aws.amazon.com/inspector/[AWS Inspector]
+* https://github.com/kubernetes/community/blob/master/sig-security/security-audit-2019/findings/Kubernetes%20Final%20Report.pdf[Kubernetes
+Security Review] A 3rd party security assessment of Kubernetes 1.13.4
+(2019)
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides compliance reporting
+and custom compliance checks
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Incident response and forensics
+
+Your ability to react quickly to an incident can help minimize damage
+caused from a breach. Having a reliable alerting system that can warn
+you of suspicious behavior is the first step in a good incident response
+plan. When an incident does arise, you have to quickly decide whether to
+destroy and replace the effected container, or isolate and inspect the
+container. If you choose to isolate the container as part of a forensic
+investigation and root cause analysis, then the following set of
+activities should be followed:
+
+== Sample incident response plan
+
+=== Identify the offending Pod and worker node
+
+Your first course of action should be to isolate the damage. Start by
+identifying where the breach occurred and isolate that Pod and its node
+from the rest of the infrastructure.
+
+=== Identify the offending Pods and worker nodes using workload name
+
+If you know the name and namespace of the offending pod, you can
+identify the the worker node running the pod as follows:
+
+[source,bash]
+----
+kubectl get pods <name> --namespace <namespace> -o=jsonpath='{.spec.nodeName}{"\n"}'
+----
+
+If a https://kubernetes.io/docs/concepts/workloads/controllers/[Workload
+Resource] such as a Deployment has been compromised, it is likely that
+all the pods that are part of the workload resource are compromised. Use
+the following command to list all the pods of the Workload Resource and
+the nodes they are running on:
+
+[source,bash]
+----
+selector=$(kubectl get deployments <name> \
+ --namespace <namespace> -o json | jq -j \
+'.spec.selector.matchLabels | to_entries | .[] | "\(.key)=\(.value)"')
+
+kubectl get pods --namespace <namespace> --selector=$selector \
+-o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"'
+----
+
+The above command is for deployments. You can run the same command for
+other workload resources such as replicasets,, statefulsets, etc.
+
+=== Identify the offending Pods and worker nodes using service account name
+
+In some cases, you may identify that a service account is compromised.
+It is likely that pods using the identified service account are
+compromised. You can identify all the pods using the service account and
+nodes they are running on with the following command:
+
+[source,bash]
+----
+kubectl get pods -o json --namespace <namespace> | \
+    jq -r '.items[] |
+    select(.spec.serviceAccount == "<service account name>") |
+    "\(.metadata.name) \(.spec.nodeName)"'
+----
+
+=== Identify Pods with vulnerable or compromised images and worker nodes
+
+In some cases, you may discover that a container image being used in
+pods on your cluster is malicious or compromised. A container image is
+malicious or compromised, if it was found to contain malware, is a known
+bad image or has a CVE that has been exploited. You should consider all
+the pods using the container image compromised. You can identify the
+pods using the image and nodes they are running on with the following
+command:
+
+[source,bash]
+----
+IMAGE=<Name of the malicious/compromised image>
+
+kubectl get pods -o json --all-namespaces | \
+    jq -r --arg image "$IMAGE" '.items[] |
+    select(.spec.containers[] | .image == $image) |
+    "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"'
+----
+
+=== Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod
+
+A deny all traffic rule may help stop an attack that is already underway
+by severing all connections to the pod. The following Network Policy
+will apply to a pod with the label `+app=web+`.
+
+[source,yaml]
+----
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: default-deny
+spec:
+  podSelector:
+    matchLabels:
+      app: web
+  policyTypes:
+  - Ingress
+  - Egress
+----
+
+!!! attention A Network Policy may prove ineffective if an attacker has
+gained access to underlying host. If you suspect that has happened, you
+can use
+https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS
+Security Groups] to isolate a compromised host from other hosts. When
+changing a host’s security group, be aware that it will impact all
+containers running on that host.
+
+=== Revoke temporary security credentials assigned to the pod or worker node if necessary
+
+If the worker node has been assigned an IAM role that allows Pods to
+gain access to other AWS resources, remove those roles from the instance
+to prevent further damage from the attack. Similarly, if the Pod has
+been assigned an IAM role, evaluate whether you can safely remove the
+IAM policies from the role without impacting other workloads.
+
+=== Cordon the worker node
+
+By cordoning the impacted worker node, you’re informing the scheduler to
+avoid scheduling pods onto the affected node. This will allow you to
+remove the node for forensic study without disrupting other workloads.
+
+!!! info This guidance is not applicable to Fargate where each Fargate
+pod run in its own sandboxed environment. Instead of cordoning,
+sequester the affected Fargate pods by applying a network policy that
+denies all ingress and egress traffic.
+
+=== Enable termination protection on impacted worker node
+
+An attacker may attempt to erase their misdeeds by terminating an
+affected node. Enabling
+https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingDisableAPITermination[termination
+protection] can prevent this from happening.
+https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection[Instance
+scale-in protection] will protect the node from a scale-in event.
+
+!!! warning You cannot enable termination protection on a Spot instance.
+
+=== Label the offending Pod/Node with a label indicating that it is part of an active investigation
+
+This will serve as a warning to cluster administrators not to tamper
+with the affected Pods/Nodes until the investigation is complete.
+
+=== Capture volatile artifacts on the worker node
+
+* *Capture the operating system memory*. This will capture the Docker
+daemon (or other container runtime) and its subprocesses per container.
+This can be accomplished using tools like
+https://github.com/504ensicsLabs/LiME[LiME] and
+https://www.volatilityfoundation.org/[Volatility], or through
+higher-level tools such as
+https://aws.amazon.com/solutions/implementations/automated-forensics-orchestrator-for-amazon-ec2/[Automated
+Forensics Orchestrator for Amazon EC2] that build on top of them.
+* *Perform a netstat tree dump of the processes running and the open
+ports*. This will capture the docker daemon and its subprocess per
+container.
+* *Run commands to save container-level state before evidence is
+altered*. You can use capabilities of the container runtime to capture
+information about currently running containers. For example, with
+Docker, you could do the following:
+** `+docker top CONTAINER+` for processes running.
+** `+docker logs CONTAINER+` for daemon level held logs.
+** `+docker inspect CONTAINER+` for various information about the
+container.
++
+The same could be achieved with containerd using the
+https://github.com/containerd/nerdctl[nerdctl] CLI, in place of
+`+docker+` (e.g. `+nerdctl inspect+`). Some additional commands are
+available depending on the container runtime. For example, Docker has
+`+docker diff+` to see changes to the container filesystem or
+`+docker checkpoint+` to save all container state including volatile
+memory (RAM). See
+https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/[this
+Kubernetes blog post] for discussion of similar capabilities with
+containerd or CRI-O runtimes.
+* *Pause the container for forensic capture*.
+* *Snapshot the instance’s EBS volumes*.
+
+=== Redeploy compromised Pod or Workload Resource
+
+Once you have gathered data for forensic analysis, you can redeploy the
+compromised pod or workload resource.
+
+First roll out the fix for the vulnerability that was compromised and
+start new replacement pods. Then delete the vulnerable pods.
+
+If the vulnerable pods are managed by a higher-level Kubernetes workload
+resource (for example, a Deployment or DaemonSet), deleting them will
+schedule new ones. So vulnerable pods will be launched again. In that
+case you should deploy a new replacement workload resource after fixing
+the vulnerability. Then you should delete the vulnerable workload.
+
+== Recommendations
+
+=== Review the AWS Security Incident Response Whitepaper
+
+While this section gives a brief overview along with a few
+recommendations for handling suspected security breaches, the topic is
+exhaustively covered in the white paper,
+https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/welcome.html[AWS
+Security Incident Response].
+
+=== Practice security game days
+
+Divide your security practitioners into 2 teams: red and blue. The red
+team will be focused on probing different systems for vulnerabilities
+while the blue team will be responsible for defending against them. If
+you don’t have enough security practitioners to create separate teams,
+consider hiring an outside entity that has knowledge of Kubernetes
+exploits.
+
+https://github.com/cyberark/kubesploit[Kubesploit] is a penetration
+testing framework from CyberArk that you can use to conduct game days.
+Unlike other tools which scan your cluster for vulnerabilities,
+kubesploit simulates a real-world attack. This gives your blue team an
+opportunity to practice its response to an attack and gauge its
+effectiveness.
+
+=== Run penetration tests against your cluster
+
+Periodically attacking your own cluster can help you discover
+vulnerabilities and misconfigurations. Before getting started, follow
+the https://aws.amazon.com/security/penetration-testing/[penetration
+test guidelines] before conducting a test against your cluster.
+
+== Tools and resources
+
+* https://github.com/aquasecurity/kube-hunter[kube-hunter], a
+penetration testing tool for Kubernetes.
+* https://www.gremlin.com/product/#kubernetes[Gremlin], a chaos
+engineering toolkit that you can use to simulate attacks against your
+applications and infrastructure.
+* https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/AtredisPartners_Attacking_Kubernetes-v1.0.pdf[Attacking
+and Defending Kubernetes Installations]
+* https://www.cyberark.com/resources/threat-research-blog/kubesploit-a-new-offensive-tool-for-testing-containerized-environments[kubesploit]
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides vulnerability- and risk
+reporting as well as security event notification
+* https://www.youtube.com/watch?v=CH7S5rE3j8w[Advanced Persistent
+Threats]
+* https://www.youtube.com/watch?v=LtCx3zZpOfs[Kubernetes Practical
+Attack and Defense]
+* https://www.youtube.com/watch?v=1LMo0CftVC4[Compromising Kubernetes
+Cluster by Exploiting RBAC Permissions]
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Image security
+
+You should consider the container image as your first line of defense
+against an attack. An insecure, poorly constructed image can allow an
+attacker to escape the bounds of the container and gain access to the
+host. Once on the host, an attacker can gain access to sensitive
+information or move laterally within the cluster or with your AWS
+account. The following best practices will help mitigate risk of this
+happening.
+
+== Recommendations
+
+=== Create minimal images
+
+Start by removing all extraneous binaries from the container image. If
+you’re using an unfamiliar image from Dockerhub, inspect the image using
+an application like https://github.com/wagoodman/dive[Dive] which can
+show you the contents of each of the container’s layers. Remove all
+binaries with the SETUID and SETGID bits as they can be used to escalate
+privilege and consider removing all shells and utilities like nc and
+curl that can be used for nefarious purposes. You can find the files
+with SETUID and SETGID bits with the following command:
+
+[source,bash]
+----
+find / -perm /6000 -type f -exec ls -ld {} \;
+----
+
+To remove the special permissions from these files, add the following
+directive to your container image:
+
+[source,docker]
+----
+RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true
+----
+
+Colloquially, this is known as de-fanging your image.
+
+=== Use multi-stage builds
+
+Using multi-stage builds is a way to create minimal images. Oftentimes,
+multi-stage builds are used to automate parts of the Continuous
+Integration cycle. For example, multi-stage builds can be used to lint
+your source code or perform static code analysis. This affords
+developers an opportunity to get near immediate feedback instead of
+waiting for a pipeline to execute. Multi-stage builds are attractive
+from a security standpoint because they allow you to minimize the size
+of the final image pushed to your container registry. Container images
+devoid of build tools and other extraneous binaries improves your
+security posture by reducing the attack surface of the image. For
+additional information about multi-stage builds, see
+https://docs.docker.com/develop/develop-images/multistage-build/[Docker’s
+multi-stage builds documentation].
+
+=== Create Software Bill of Materials (SBOMs) for your container image
+
+A "`software bill of materials`" (SBOM) is a nested inventory of the
+software artifacts that make up your container image. SBOM is a key
+building block in software security and software supply chain risk
+management. https://anchore.com/sbom/[Generating&#44; storing SBOMS in a
+central repository and scanning SBOMs for vulnerabilities] helps address
+the following concerns:
+
+* *Visibility*: understand what components make up your container image.
+Storing in a central repository allows SBOMs to be audited and scanned
+anytime, even post deployment to detect and respond to new
+vulnerabilities such as zero day vulnerabilities.
+* *Provenance Verification*: assurance that existing assumptions of
+where and how an artifact originates from are true and that the artifact
+or its accompanying metadata have not been tampered with during the
+build or delivery processes.
+* *Trustworthiness*: assurance that a given artifact and its contents
+can be trusted to do what it is purported to do, i.e. is suitable for a
+purpose. This involves judgement on whether the code is safe to execute
+and making informed decisions about the risks associated with executing
+the code. Trustworthiness is assured by creating an attested pipeline
+execution report along with attested SBOM and attested CVE scan report
+to assure the consumers of the image that this image is in-fact created
+through secure means (pipeline) with secure components.
+* *Dependency Trust Verification*: recursive checking of an artifact’s
+dependency tree for trustworthiness and provenance of the artifacts it
+uses. Drift in SBOMs can help detect malicious activity including
+unauthorized, untrusted dependencies, infiltration attempts.
+
+The following tools can be used to generate SBOM:
+
+* https://docs.aws.amazon.com/inspector[Amazon Inspector] can be used to
+https://docs.aws.amazon.com/inspector/latest/user/sbom-export.html[create
+and export SBOMs].
+* https://github.com/anchore/syft[Syft from Anchore] can also be used
+for SBOM generation. For quicker vulnerability scans, the SBOM generated
+for a container image can be used as an input to scan. The SBOM and scan
+report are then
+https://github.com/sigstore/cosign/blob/main/doc/cosign_attach_attestation.md[attested
+and attached] to the image before pushing the image to a central OCI
+repository such as Amazon ECR for review and audit purposes.
+
+Learn more about securing your software supply chain by reviewing
+https://project.linuxfoundation.org/hubfs/CNCF_SSCP_v1.pdf[CNCF Software
+Supply Chain Best Practices guide].
+
+=== Scan images for vulnerabilities regularly
+
+Like their virtual machine counterparts, container images can contain
+binaries and application libraries with vulnerabilities or develop
+vulnerabilities over time. The best way to safeguard against exploits is
+by regularly scanning your images with an image scanner. Images that are
+stored in Amazon ECR can be scanned on push or on-demand (once during a
+24 hour period). ECR currently supports
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html[two
+types of scanning - Basic and Enhanced]. Basic scanning leverages
+https://github.com/quay/clair[Clair] an open source image scanning
+solution for no cost.
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html[Enhanced
+scanning] uses Amazon Inspector to provide automatic continuous scans
+for https://aws.amazon.com/inspector/pricing/[additional cost]. After an
+image is scanned, the results are logged to the event stream for ECR in
+EventBridge. You can also see the results of a scan from within the ECR
+console. Images with a HIGH or CRITICAL vulnerability should be deleted
+or rebuilt. If an image that has been deployed develops a vulnerability,
+it should be replaced as soon as possible.
+
+Knowing where images with vulnerabilities have been deployed is
+essential to keeping your environment secure. While you could
+conceivably build an image tracking solution yourself, there are already
+several commercial offerings that provide this and other advanced
+capabilities out of the box, including:
+
+* https://github.com/anchore/grype[Grype]
+* https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/tools/twistcli_scan_images[Palo
+Alto - Prisma Cloud (twistcli)]
+* https://www.aquasec.com/[Aqua]
+* https://github.com/Portshift/kubei[Kubei]
+* https://github.com/aquasecurity/trivy[Trivy]
+* https://support.snyk.io/hc/en-us/articles/360003946917-Test-images-with-the-Snyk-Container-CLI[Snyk]
+
+A Kubernetes validation webhook could also be used to validate that
+images are free of critical vulnerabilities. Validation webhooks are
+invoked prior to the Kubernetes API. They are typically used to reject
+requests that don’t comply with the validation criteria defined in the
+webhook.
+https://aws.amazon.com/blogs/containers/building-serverless-admission-webhooks-for-kubernetes-with-aws-sam/[This]
+is an example of a serverless webhook that calls the ECR
+describeImageScanFindings API to determine whether a pod is pulling an
+image with critical vulnerabilities. If vulnerabilities are found, the
+pod is rejected and a message with list of CVEs is returned as an Event.
+
+=== Use attestations to validate artifact integrity
+
+An attestation is a cryptographically signed "`statement`" that claims
+something - a "`predicate`" e.g. a pipeline run or the SBOM or the
+vulnerability scan report is true about another thing - a "`subject`"
+i.e. the container image.
+
+Attestations help users to validate that an artifact comes from a
+trusted source in the software supply chain. As an example, we may use a
+container image without knowing all the software components or
+dependencies that are included in that image. However, if we trust
+whatever the producer of the container image says about what software is
+present, we can use the producer’s attestation to rely on that artifact.
+This means that we can proceed to use the artifact safely in our
+workflow in place of having done the analysis ourself.
+
+* Attestations can be created using
+https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS
+Signer] or
+https://github.com/sigstore/cosign/blob/main/doc/cosign_attest.md[Sigstore
+cosign].
+* Kubernetes admission controllers such as https://kyverno.io/[Kyverno]
+can be used to
+https://kyverno.io/docs/writing-policies/verify-images/sigstore/[verify
+attestations].
+* Refer to this
+https://catalog.us-east-1.prod.workshops.aws/workshops/49343bb7-2cc5-4001-9d3b-f6a33b3c4442/en-US/0-introduction[workshop]
+to learn more about software supply chain management best practices on
+AWS using open source tools with topics including creating and attaching
+attestations to a container image.
+
+=== Create IAM policies for ECR repositories
+
+Nowadays, it is not uncommon for an organization to have multiple
+development teams operating independently within a shared AWS account.
+If these teams don’t need to share assets, you may want to create a set
+of IAM policies that restrict access to the repositories each team can
+interact with. A good way to implement this is by using ECR
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html#repository-concepts[namespaces].
+Namespaces are a way to group similar repositories together. For
+example, all of the registries for team A can be prefaced with the
+team-a/ while those for team B can use the team-b/ prefix. The policy to
+restrict access might look like the following:
+
+[source,json]
+----
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "AllowPushPull",
+      "Effect": "Allow",
+      "Action": [
+        "ecr:GetDownloadUrlForLayer",
+        "ecr:BatchGetImage",
+        "ecr:BatchCheckLayerAvailability",
+        "ecr:PutImage",
+        "ecr:InitiateLayerUpload",
+        "ecr:UploadLayerPart",
+        "ecr:CompleteLayerUpload"
+      ],
+      "Resource": [
+        "arn:aws:ecr:<region>:<account_id>:repository/team-a/*"
+      ]
+    }
+  ]
+}
+----
+
+=== Consider using ECR private endpoints
+
+The ECR API has a public endpoint. Consequently, ECR registries can be
+accessed from the Internet so long as the request has been authenticated
+and authorized by IAM. For those who need to operate in a sandboxed
+environment where the cluster VPC lacks an Internet Gateway (IGW), you
+can configure a private endpoint for ECR. Creating a private endpoint
+enables you to privately access the ECR API through a private IP address
+instead of routing traffic across the Internet. For additional
+information on this topic, see
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html[Amazon
+ECR interface VPC endpoints].
+
+=== Implement endpoint policies for ECR
+
+The default endpoint policy for allows access to all ECR repositories
+within a region. This might allow an attacker/insider to exfiltrate data
+by packaging it as a container image and pushing it to a registry in
+another AWS account. Mitigating this risk involves creating an endpoint
+policy that limits API access to ECR repositories. For example, the
+following policy allows all AWS principles in your account to perform
+all actions against your and only your ECR repositories:
+
+[source,json]
+----
+{
+  "Statement": [
+    {
+      "Sid": "LimitECRAccess",
+      "Principal": "*",
+      "Action": "*",
+      "Effect": "Allow",
+      "Resource": "arn:aws:ecr:<region>:<account_id>:repository/*"
+    }
+  ]
+}
+----
+
+You can enhance this further by setting a condition that uses the new
+`+PrincipalOrgID+` attribute which will prevent pushing/pulling of
+images by an IAM principle that is not part of your AWS Organization.
+See,
+https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid[aws:PrincipalOrgID]
+for additional details. We recommended applying the same policy to both
+the `+com.amazonaws.<region>.ecr.dkr+` and the
+`+com.amazonaws.<region>.ecr.api+` endpoints. Since EKS pulls images for
+kube-proxy, coredns, and aws-node from ECR, you will need to add the
+account ID of the registry,
+e.g. `+602401143452.dkr.ecr.us-west-2.amazonaws.com/*+` to the list of
+resources in the endpoint policy or alter the policy to allow pulls from
+“*” and restrict pushes to your account ID. The table below reveals the
+mapping between the AWS accounts where EKS images are vended from and
+cluster region.
+
+[cols=",",options="header",]
+|===
+|Account Number |Region
+|602401143452 |All commercial regions except for those listed below
+|— |—
+|800184023465 |ap-east-1 - Asia Pacific (Hong Kong)
+|558608220178 |me-south-1 - Middle East (Bahrain)
+|918309763551 |cn-north-1 - China (Beijing)
+|961992271922 |cn-northwest-1 - China (Ningxia)
+|===
+
+For further information about using endpoint policies, see
+https://aws.amazon.com/blogs/containers/using-vpc-endpoint-policies-to-control-amazon-ecr-access/[Using
+VPC endpoint policies to control Amazon ECR access].
+
+=== Implement lifecycle policies for ECR
+
+The
+https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf[NIST
+Application Container Security Guide] warns about the risk of "`stale
+images in registries`", noting that over time old images with
+vulnerable, out-of-date software packages should be removed to prevent
+accidental deployment and exposure. Each ECR repository can have a
+lifecycle policy that sets rules for when images expire. The
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html[AWS
+official documentation] describes how to set up test rules, evaluate
+them and then apply them. There are several
+https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html[lifecycle
+policy examples] in the official docs that show different ways of
+filtering the images in a repository:
+
+* Filtering by image age or count
+* Filtering by tagged or untagged images
+* Filtering by image tags, either in multiple rules or a single rule
+
+???+ warning If the image for long running application is purged from
+ECR, it can cause an image pull errors when the application is
+redeployed or scaled horizontally. When using image lifecycle policies,
+be sure you have good CI/CD practices in place to keep deployments and
+the images that they reference up to date and always create [image]
+expiry rules that account for how often you do releases/deployments.
+
+=== Create a set of curated images
+
+Rather than allowing developers to create their own images, consider
+creating a set of vetted images for the different application stacks in
+your organization. By doing so, developers can forego learning how to
+compose Dockerfiles and concentrate on writing code. As changes are
+merged into Master, a CI/CD pipeline can automatically compile the
+asset, store it in an artifact repository and copy the artifact into the
+appropriate image before pushing it to a Docker registry like ECR. At
+the very least you should create a set of base images from which
+developers to create their own Dockerfiles. Ideally, you want to avoid
+pulling images from Dockerhub because 1/ you don’t always know what is
+in the image and 2/ about
+https://www.kennasecurity.com/blog/one-fifth-of-the-most-used-docker-containers-have-at-least-one-critical-vulnerability/[a
+fifth] of the top 1000 images have vulnerabilities. A list of those
+images and their vulnerabilities can be found
+https://vulnerablecontainers.org/[here].
+
+=== Add the USER directive to your Dockerfiles to run as a non-root user
+
+As was mentioned in the pod security section, you should avoid running
+container as root. While you can configure this as part of the podSpec,
+it is a good habit to use the `+USER+` directive to your Dockerfiles.
+The `+USER+` directive sets the UID to use when running `+RUN+`,
+`+ENTRYPOINT+`, or `+CMD+` instruction that appears after the USER
+directive.
+
+=== Lint your Dockerfiles
+
+Linting can be used to verify that your Dockerfiles are adhering to a
+set of predefined guidelines, e.g. the inclusion of the `+USER+`
+directive or the requirement that all images be tagged.
+https://github.com/projectatomic/dockerfile_lint[dockerfile_lint] is an
+open source project from RedHat that verifies common best practices and
+includes a rule engine that you can use to build your own rules for
+linting Dockerfiles. It can be incorporated into a CI pipeline, in that
+builds with Dockerfiles that violate a rule will automatically fail.
+
+=== Build images from Scratch
+
+Reducing the attack surface of your container images should be primary
+aim when building images. The ideal way to do this is by creating
+minimal images that are devoid of binaries that can be used to exploit
+vulnerabilities. Fortunately, Docker has a mechanism to create images
+from
+https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch[`+scratch+`].
+With languages like Go, you can create a static linked binary and
+reference it in your Dockerfile as in this example:
+
+[source,docker]
+----
+############################
+# STEP 1 build executable binary
+############################
+FROM golang:alpine AS builder# Install git.
+# Git is required for fetching the dependencies.
+RUN apk update && apk add --no-cache gitWORKDIR $GOPATH/src/mypackage/myapp/COPY . . # Fetch dependencies.
+# Using go get.
+RUN go get -d -v# Build the binary.
+RUN go build -o /go/bin/hello
+
+############################
+# STEP 2 build a small image
+############################
+FROM scratch# Copy our static executable.
+COPY --from=builder /go/bin/hello /go/bin/hello# Run the hello binary.
+ENTRYPOINT ["/go/bin/hello"]
+----
+
+This creates a container image that consists of your application and
+nothing else, making it extremely secure.
+
+=== Use immutable tags with ECR
+
+https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/[Immutable
+tags] force you to update the image tag on each push to the image
+repository. This can thwart an attacker from overwriting an image with a
+malicious version without changing the image’s tags. Additionally, it
+gives you a way to easily and uniquely identify an image.
+
+=== Sign your images, SBOMs, pipeline runs and vulnerability reports
+
+When Docker was first introduced, there was no cryptographic model for
+verifying container images. With v2, Docker added digests to the image
+manifest. This allowed an image’s configuration to be hashed and for the
+hash to be used to generate an ID for the image. When image signing is
+enabled, the Docker engine verifies the manifest’s signature, ensuring
+that the content was produced from a trusted source and no tampering has
+occurred. After each layer is downloaded, the engine verifies the digest
+of the layer, ensuring that the content matches the content specified in
+the manifest. Image signing effectively allows you to create a secure
+supply chain, through the verification of digital signatures associated
+with the image.
+
+We can use
+https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS
+Signer] or https://github.com/sigstore/cosign[Sigstore Cosign], to sign
+container images, create attestations for SBOMs, vulnerability scan
+reports and pipeline run reports. These attestations assure the
+trustworthiness and integrity of the image, that it is in fact created
+by the trusted pipeline without any interference or tampering, and that
+it contains only the software components that are documented (in the
+SBOM) that is verified and trusted by the image publisher. These
+attestations can be attached to the container image and pushed to the
+repository.
+
+In the next section we will see how to use the attested artifacts for
+audits and admissions controller verification.
+
+=== Image integrity verification using Kubernetes admission controller
+
+We can verify image signatures, attested artifacts in an automated way
+before deploying the image to target Kubernetes cluster using
+https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/[dynamic
+admission controller] and admit deployments only when the security
+metadata of the artifacts comply with the admission controller policies.
+
+For example we can write a policy that cryptographically verifies the
+signature of an image, an attested SBOM, attested pipeline run report,
+or attested CVE scan report. We can write conditions in the policy to
+check data in the report, e.g. a CVE scan should not have any critical
+CVEs. Deployment is allowed only for images that satisfy these
+conditions and all other deployments will be rejected by the admissions
+controller.
+
+Examples of admission controller include:
+
+* https://kyverno.io/[Kyverno]
+* https://github.com/open-policy-agent/gatekeeper[OPA Gatekeeper]
+* https://github.com/IBM/portieris[Portieris]
+* https://github.com/deislabs/ratify[Ratify]
+* https://github.com/grafeas/kritis[Kritis]
+* https://github.com/kelseyhightower/grafeas-tutorial[Grafeas tutorial]
+* https://github.com/Shopify/voucher[Voucher]
+
+=== Update the packages in your container images
+
+You should include RUN `+apt-get update && apt-get upgrade+` in your
+Dockerfiles to upgrade the packages in your images. Although upgrading
+requires you to run as root, this occurs during image build phase. The
+application doesn’t need to run as root. You can install the updates and
+then switch to a different user with the USER directive. If your base
+image runs as a non-root user, switch to root and back; don’t solely
+rely on the maintainers of the base image to install the latest security
+updates.
+
+Run `+apt-get clean+` to delete the installer files from
+`+/var/cache/apt/archives/+`. You can also run
+`+rm -rf /var/lib/apt/lists/*+` after installing packages. This removes
+the index files or the lists of packages that are available to install.
+Be aware that these commands may be different for each package manager.
+For example:
+
+[source,docker]
+----
+RUN apt-get update && apt-get install -y \
+    curl \
+    git \
+    libsqlite3-dev \
+    && apt-get clean && rm -rf /var/lib/apt/lists/*
+----
+
+== Tools and resources
+
+* https://catalog.workshops.aws/eks-security-immersionday/en-US/12-image-security[Amazon
+EKS Security Immersion Workshop - Image Security]
+* https://github.com/docker-slim/docker-slim[docker-slim] Build secure
+minimal images
+* https://github.com/goodwithtech/dockle[dockle] Verifies that your
+Dockerfile aligns with best practices for creating secure images
+* https://github.com/projectatomic/dockerfile_lint[dockerfile-lint] Rule
+based linter for Dockerfiles
+* https://github.com/hadolint/hadolint[hadolint] A smart dockerfile
+linter
+* https://github.com/open-policy-agent/gatekeeper[Gatekeeper and OPA] A
+policy based admission controller
+* https://kyverno.io/[Kyverno] A Kubernetes-native policy engine
+* https://in-toto.io/[in-toto] Allows the user to verify if a step in
+the supply chain was intended to be performed, and if the step was
+performed by the right actor
+* https://github.com/theupdateframework/notary[Notary] A project for
+signing container images
+* https://github.com/notaryproject/nv2[Notary v2]
+* https://grafeas.io/[Grafeas] An open artifact metadata API to audit
+and govern your software supply chain
+* https://www.suse.com/neuvector/[NeuVector by SUSE] open source,
+zero-trust container security platform, provides container, image and
+registry scanning for vulnerabilities, secrets and compliance.
+
+:leveloffset: 1
+:leveloffset: +1
+
+= Multi Account Strategy
+
+AWS recommends using a
+https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi
+account strategy] and AWS organizations to help isolate and manage your
+business applications and data. There are
+https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html[many
+benefits] to using a multi account strategy:
+
+* Increased AWS API service quotas. Quotas are applied to AWS accounts,
+and using multiple accounts for your workloads increases the overall
+quota available to your workloads.
+* Simpler Identity and Access Management (IAM) policies. Granting
+workloads and the operators that support them access to only their own
+AWS accounts means less time crafting fine-grained IAM policies to
+achieve the principle of least privilege.
+* Improved Isolation of AWS resources. By design, all resources
+provisioned within an account are logically isolated from resources
+provisioned in other accounts. This isolation boundary provides you with
+a way to limit the risks of an application-related issue,
+misconfiguration, or malicious actions. If an issue occurs within one
+account, impacts to workloads contained in other accounts can be either
+reduced or eliminated.
+* More benefits, as described in the
+https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html#group-workloads-based-on-business-purpose-and-ownership[AWS
+Multi Account Strategy Whitepaper]
+
+The following sections will explain how to implement a multi account
+strategy for your EKS workloads using either a centralized, or
+de-centralized EKS cluster approach.
+
+== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters
+
+In a multi account AWS strategy, resources that belong to a given
+workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables
+are all created in an AWS account that contains all the resources for
+that workload. These are referred to as a workload account, and the EKS
+cluster is deployed into an account referred to as the cluster account.
+Cluster accounts will be explored in the next section. Deploying
+resources into a dedicated workload account is similar to deploying
+kubernetes resources into a dedicated namespace.
+
+Workload accounts can then be further broken down by software
+development lifecycle or other requirements if appropriate. For example
+a given workload can have a production account, a development account,
+or accounts for hosting instances of that workload in a specific region.
+https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-workload-oriented-ous.html[More
+information] is available in this AWS whitepaper.
+
+You can adopt the following approaches when implementing EKS Multi
+account strategy:
+
+== Centralized EKS Cluster
+
+In this approach, your EKS Cluster will be deployed in a single AWS
+account called the `+Cluster Account+`. Using
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM
+roles for Service Accounts (IRSA)] or
+https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS
+Pod Identities] to deliver temporary AWS credentials and
+https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to
+simplify network access, you can adopt a multi account strategy for your
+multi tenant EKS cluster. The cluster account will contain the VPC,
+subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and
+any additional networking configurations needed to run your EKS cluster.
+
+In a multi workload account strategy for multi tenant cluster, AWS
+accounts typically align with
+https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes
+namespaces] as a mechanism for isolating groups of resources.
+link:/security/docs/multitenancy/[Best practices for tenant isolation]
+within an EKS cluster should still be followed when implementing a multi
+account strategy for multi tenant EKS clusters.
+
+It is possible to have multiple `+Cluster Accounts+` in your AWS
+organization, and it is a best practice to have multiple
+`+Cluster Accounts+` that align with your software development lifecycle
+needs. For workloads operating at a very large scale, you may require
+multiple `+Cluster Accounts+` to ensure that there are enough kubernetes
+and AWS service quotas available to all your workloads.
+
+[width="100%",cols="^100%",options="header",]
+|===
+|image:./images/multi-account-eks.jpg[multi-account-eks]
+|In the above diagram, AWS RAM is used to share subnets from a cluster
+account into a workload account. Then workloads running in EKS pods use
+IRSA or EKS Pod Identities and role chaining to assume a role in their
+workload account and access their AWS resources.
+|===
+
+=== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster
+
+==== Sharing Subnets With AWS Resource Access Manager
+
+https://aws.amazon.com/ram/[AWS Resource Access Manager] (RAM) allows
+you to share resources across AWS accounts.
+
+If
+https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html#getting-started-sharing-orgs[RAM
+is enabled for your AWS Organization], you can share the VPC Subnets
+from the Cluster account to your workload accounts. This will allow AWS
+resources owned by your workload accounts, such as
+https://aws.amazon.com/elasticache/[Amazon ElastiCache] Clusters or
+https://aws.amazon.com/rds/[Amazon Relational Database Service (RDS)]
+Databases to be deployed into the same VPC as your EKS cluster, and be
+consumable by the workloads running on your EKS cluster.
+
+To share a resource via RAM, open up RAM in the AWS console of the
+cluster account and select "`Resource Shares`" and "`Create Resource
+Share`". Name your Resource Share and Select the subnets you want to
+share. Select Next again and enter the 12 digit account IDs for the
+workload accounts you wish to share the subnets with, select next again,
+and click Create resource share to finish. After this step, the workload
+account can deploy resources into those subnets.
+
+RAM shares can also be created programmatically, or with infrastructure
+as code.
+
+==== Choosing Between EKS Pod Identities and IRSA
+
+At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of
+delivering temporary AWS credentials to your pods on EKS. Both IRSA and
+EKS Pod Identities are valid methods for delivering temporary AWS
+credentials to your EKS pods and will continue to be supported. You
+should consider which method of delivering best meets your needs.
+
+When working with a EKS cluster and multiple AWS accounts, IRSA can
+directly assume roles in AWS accounts other than the account the EKS
+cluster is hosted in directly, while EKS Pod identities require you to
+configure role chaining. Refer
+https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html#service-accounts-iam[EKS
+documentation] for an in-depth comparison.
+
+===== Accessing AWS API Resources with IAM Roles For Service Accounts
+
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM
+Roles for Service Accounts (IRSA)] allows you to deliver temporary AWS
+credentials to your workloads running on EKS. IRSA can be used to get
+temporary credentials for IAM roles in the workload accounts from the
+cluster account. This allows your workloads running on your EKS clusters
+in the cluster account to consume AWS API resources, such as S3 buckets
+hosted in the workload account seemlessly, and use IAM authentication
+for resources like Amazon RDS Databases or Amazon EFS FileSystems.
+
+AWS API resources and other Resources that use IAM authentication in a
+workload account can only be accessed by credentials for IAM roles in
+that same workload account, except where cross account access is capable
+and has been explicity enabled.
+
+====== Enabling IRSA for cross account access
+
+To enable IRSA for workloads in your Cluster Account to access resources
+in your Workload accounts, you first must create an IAM OIDC identity
+provider in your workload account. This can be done with the same
+procedure for setting up
+https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html[IRSA],
+except the Identity Provider will be created in the workload account.
+
+Then when configuring IRSA for your workloads on EKS, you can
+https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html[follow
+the same steps as the documentation], but use the
+https://docs.aws.amazon.com/eks/latest/userguide/cross-account-access.html[12
+digit account id of the workload account] as mentioned in the section
+"`Example Create an identity provider from another account’s cluster`".
+
+After this is configured, your application running in EKS will be able
+to directly use its service account to assume a role in the workload
+account, and use resources within it.
+
+===== Accessing AWS API Resources with EKS Pod Identities
+
+https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS
+Pod Identities] is a new way of delivering AWS credentials to your
+workloads running on EKS. EKS pod identities simplifies the
+configuration of AWS resources as you no longer need to manage OIDC
+configurations to deliver AWS credentials to your pods on EKS.
+
+====== Enabling EKS Pod Identities for cross account access
+
+Unlike IRSA, EKS Pod Identities can only be used to directly grant
+access to a role in the same account as the EKS cluster. To access a
+role in another AWS account, pods that use EKS Pod Identities must
+perform
+https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining[Role
+Chaining].
+
+Role chaining can be configured in an applications profile with their
+aws configuration file using the
+https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process
+Credentials Provider] available in various AWS SDKs.
+`+credential_process+` can be used as a credential source when
+configuring a profile, such as:
+
+[source,bash]
+----
+# Content of the AWS Config file
+[profile account_b_role]
+source_profile = account_a_role
+role_arn = arn:aws:iam::444455556666:role/account-b-role
+
+[profile account_a_role]
+credential_process = /eks-credential-processrole.sh
+----
+
+The source of the script called by credential_process:
+
+[source,bash]
+----
+#!/bin/bash
+# Content of the eks-credential-processrole.sh
+# This will retreive the credential from the pod identities agent,
+# and return it to the AWS SDK when referenced in a profile
+curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}'
+----
+
+You can create an aws config file as shown above with both Account A and
+B roles and specify the AWS_CONFIG_FILE and AWS_PROFILE env vars in your
+pod spec. EKS Pod identity webhook does not override if the env vars
+already exists in the pod spec.
+
+[source,yaml]
+----
+# Snippet of the PodSpec
+containers:
+  - name: container-name
+    image: container-image:version
+    env:
+    - name: AWS_CONFIG_FILE
+      value: path-to-customer-provided-aws-config-file
+    - name: AWS_PROFILE
+      value: account_b_role
+----
+
+When configuring role trust policies for role chaining with EKS pod
+identities, you can reference
+https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html[EKS
+specific attributes] as session tags and use attribute based access
+control(ABAC) to limit access to your IAM roles to only specific EKS Pod
+identity sessions, such as the Kubernetes Service Account a pod belongs
+to.
+
+Please note that some of these attributes may not be universally unique,
+for example two EKS clusters may have identical namespaces, and one
+cluster may have identically named service accounts across namespaces.
+So when granting access via EKS Pod Identities and ABAC, it is a best
+practice to always consider the cluster arn and namespace when granting
+access to a service account.
+
+====== ABAC and EKS Pod Identities for cross account access
+
+When using EKS Pod Identities to assume roles (role chaining) in other
+accounts as part of a multi account strategy, you have the option to
+assign a unique IAM role for each service account that needs to access
+another account, or use a common IAM role across multiple service
+accounts and use ABAC to control what accounts it can access.
+
+To use ABAC to control what service accounts can assume a role into
+another account with role chaining, you create a role trust policy
+statement that only allows a role to be assumed by a role session when
+the expected values are present. The following role trust policy will
+only let a role from the EKS cluster account (account ID 111122223333)
+assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+`
+and `+kubernetes-namespace+` tags all have the expected value.
+
+[source,json]
+----
+{
+    "Version": "2012-10-17",
+    "Statement": [
+        {
+            "Effect": "Allow",
+            "Principal": {
+                "AWS": "arn:aws:iam::111122223333:root"
+            },
+            "Action": "sts:AssumeRole",
+            "Condition": {
+                "StringEquals": {
+                    "aws:PrincipalTag/kubernetes-service-account": "PayrollApplication",
+                    "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-east-1:111122223333:cluster/ProductionCluster",
+                    "aws:PrincipalTag/kubernetes-namespace": "PayrollNamespace"
+                }
+            }
+        }
+    ]
+}
+----
+
+When using this strategy it is a best practice to ensure that the common
+IAM role only has `+sts:AssumeRole+` permissions and no other AWS
+access.
+
+It is important when using ABAC that you control who has the ability to
+tag IAM roles and users to only those who have a strict need to do so.
+Someone with the ability to tag an IAM role or user would be able to set
+tags on roles/users identical to what would be set by EKS Pod Identities
+and may be able to escalate their privileges. You can restrict who has
+the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role
+and users using IAM policy, or Service Control Policy (SCP).
+
+== De-centralized EKS Clusters
+
+In this approach, EKS clusters are deployed to respective workload AWS
+Accounts and live along side with other AWS resources like Amazon S3
+buckets, VPCs, Amazon DynamoDB tables, etc., Each workload account is
+independent, self-sufficient, and operated by respective Business
+Unit/Application teams. This model allows the creation of reusuable
+blueprints for various cluster capabilities (AI/ML cluster, Batch
+processing, General purpose, etc.,) and vend the clusters based on the
+application team requirements. Both application and platform teams
+operate out of their respective
+https://www.weave.works/technologies/gitops/[GitOps] repositories to
+manage the deployments to the workload clusters.
+
+[width="100%",cols="^100%",options="header",]
+|===
+|image:./images/multi-account-eks-decentralized.png[De-centralized EKS
+Cluster Architecture]
+|In the above diagram, Amazon EKS clusters and other AWS resources are
+deployed to respective workload accounts. Then workloads running in EKS
+pods use IRSA or EKS Pod Identities to access their AWS resources.
+|===
+
+GitOps is a way of managing application and infrastructure deployment so
+that the whole system is described declaratively in a Git repository.
+It’s an operational model that offers you the ability to manage the
+state of multiple Kubernetes clusters using the best practices of
+version control, immutable artifacts, and automation. In this multi
+cluster model, each workload cluster is bootstrapped with multiple Git
+repos, allowing each team (application, platform, security, etc.,) to
+deploy their respective changes on the cluster.
+
+You would utilize
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM
+roles for Service Accounts (IRSA)] or
+https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS
+Pod Identities] in each account to allow your EKS workloads to get
+temporary aws credentials to securely access other AWS resources. IAM
+roles are created in respective workload AWS Accounts and map them to
+k8s service accounts to provide temporary IAM access. So, no
+cross-account access is required in this approach. Follow the
+https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM
+roles for Service Accounts] documentation on how to setup in each
+workload for IRSA, and
+https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS
+Pod Identities] documentation on how to setup EKS pod identities in each
+account.
+
+=== Centralized Networking
+
+You can also utilize AWS RAM to share the VPC Subnets to workload
+accounts and launch Amazon EKS clusters and other AWS resources in them.
+This enables centralized network managment/administration, simplified
+network connectivity, and de-centralized EKS clusters. Refer this
+https://aws.amazon.com/blogs/containers/use-shared-vpcs-in-amazon-eks/[AWS
+blog] for a detailed walkthrough and considerations of this approach.
+
+[width="100%",cols="^100%",options="header",]
+|===
+|image:./images/multi-account-eks-shared-subnets.png[De-centralized EKS
+Cluster Architecture using VPC Shared Subnets]
+|In the above diagram, AWS RAM is used to share subnets from a central
+networking account into a workload account. Then EKS cluster and other
+AWS resources are launched in those subnets in respective workload
+accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS
+resources.
+|===
+
+== Centralized vs De-centralized EKS clusters
+
+The decision to run with a Centralized or De-centralized will depend on
+your requirements. This table demonstrates the key differences with each
+strategy.
+
+[width="100%",cols="<34%,<33%,<33%",options="header",]
+|===
+|# |Centralized EKS cluster |De-centralized EKS clusters
+|Cluster Management: |Managing a single EKS cluster is easier than
+administrating multiple clusters |An Efficient cluster management
+automation is necessary to reduce the operational overhead of managing
+multiple EKS clusters
+
+|Cost Efficiency: |Allows reuse of EKS cluster and network resources,
+which promotes cost efficiency |Requires networking and cluster setups
+per workload, which requires additional resources
+
+|Resilience: |Multiple workloads on the centralized cluster may be
+impacted if a cluster becomes impaired |If a cluster becomes impaired,
+the damage is limited to only the workloads that run on that cluster.
+All other workloads are unaffected
+
+|Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using
+k8s native constructs like `+Namespaces+`. Workloads may share the
+underlying resources like CPU, memory, etc. AWS resources are isolated
+into their own workload accounts which by default are not accessible
+from other AWS accounts. |Stronger isolation on compute resources as the
+workloads run in individual clusters and nodes that don’t share any
+resources. AWS resources are isolated into their own workload accounts
+which by default are not accessible from other AWS accounts.
+
+|Performance & Scalabity: |As workloads grow to very large scales you
+may encounter kubernetes and AWS service quotas in the cluster account.
+You can deploy addtional cluster accounts to scale even further |As more
+clusters and VPCs are present, each workload has more available k8s and
+AWS service quota
+
+|Networking: |Single VPC is used per cluster, allowing for simpler
+connectivity for applications on that cluster |Routing must be
+established between the de-centralized EKS cluster VPCs
+
+|Kubernetes Access Management: |Need to maintain many different roles
+and users in the cluster to provide access to all workload teams and
+ensure kubernetes resources are properly segregated |Simplified access
+management as each cluster is dedicated to a workload/team
+
+|AWS Access Management: |AWS resources are deployed into to their own
+account which can only be accessed by default with IAM roles in the
+workload account. IAM roles in the workload accounts are assumed cross
+account either with IRSA or EKS Pod Identities. |AWS resources are
+deployed into to their own account which can only be accessed by default
+with IAM roles in the workload account. IAM roles in the workload
+accounts are delivered directly to pods with IRSA or EKS Pod Identities
+|===
+
+:leveloffset: 1
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/latest/bpg/security/multiaccount.adoc b/latest/bpg/security/multiaccount.adoc index 448bddeb6..4d18ad90d 100644 --- a/latest/bpg/security/multiaccount.adoc +++ b/latest/bpg/security/multiaccount.adoc @@ -1,4 +1,4 @@ -== Multi Account Strategy += Multi Account Strategy AWS recommends using a https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi @@ -29,7 +29,7 @@ The following sections will explain how to implement a multi account strategy for your EKS workloads using either a centralized, or de-centralized EKS cluster approach. -=== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters +== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters In a multi account AWS strategy, resources that belong to a given workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables @@ -50,7 +50,7 @@ information] is available in this AWS whitepaper. You can adopt the following approaches when implementing EKS Multi account strategy: -=== Centralized EKS Cluster +== Centralized EKS Cluster In this approach, your EKS Cluster will be deployed in a single AWS account called the `+Cluster Account+`. Using @@ -88,9 +88,9 @@ IRSA or EKS Pod Identities and role chaining to assume a role in their workload account and access their AWS resources. |=== -==== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster +=== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster -===== Sharing Subnets With AWS Resource Access Manager +==== Sharing Subnets With AWS Resource Access Manager https://aws.amazon.com/ram/[AWS Resource Access Manager] (RAM) allows you to share resources across AWS accounts. @@ -116,7 +116,7 @@ account can deploy resources into those subnets. RAM shares can also be created programmatically, or with infrastructure as code. -===== Choosing Between EKS Pod Identities and IRSA +==== Choosing Between EKS Pod Identities and IRSA At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of delivering temporary AWS credentials to your pods on EKS. Both IRSA and @@ -131,7 +131,7 @@ configure role chaining. Refer https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html#service-accounts-iam[EKS documentation] for an in-depth comparison. -====== Accessing AWS API Resources with IAM Roles For Service Accounts +===== Accessing AWS API Resources with IAM Roles For Service Accounts https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM Roles for Service Accounts (IRSA)] allows you to deliver temporary AWS @@ -147,7 +147,7 @@ workload account can only be accessed by credentials for IAM roles in that same workload account, except where cross account access is capable and has been explicity enabled. -======= Enabling IRSA for cross account access +====== Enabling IRSA for cross account access To enable IRSA for workloads in your Cluster Account to access resources in your Workload accounts, you first must create an IAM OIDC identity @@ -167,7 +167,7 @@ After this is configured, your application running in EKS will be able to directly use its service account to assume a role in the workload account, and use resources within it. -====== Accessing AWS API Resources with EKS Pod Identities +===== Accessing AWS API Resources with EKS Pod Identities https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS Pod Identities] is a new way of delivering AWS credentials to your @@ -175,7 +175,7 @@ workloads running on EKS. EKS pod identities simplifies the configuration of AWS resources as you no longer need to manage OIDC configurations to deliver AWS credentials to your pods on EKS. -======= Enabling EKS Pod Identities for cross account access +====== Enabling EKS Pod Identities for cross account access Unlike IRSA, EKS Pod Identities can only be used to directly grant access to a role in the same account as the EKS cluster. To access a @@ -246,7 +246,7 @@ So when granting access via EKS Pod Identities and ABAC, it is a best practice to always consider the cluster arn and namespace when granting access to a service account. -======= ABAC and EKS Pod Identities for cross account access +====== ABAC and EKS Pod Identities for cross account access When using EKS Pod Identities to assume roles (role chaining) in other accounts as part of a multi account strategy, you have the option to @@ -297,7 +297,7 @@ and may be able to escalate their privileges. You can restrict who has the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role and users using IAM policy, or Service Control Policy (SCP). -=== De-centralized EKS Clusters +== De-centralized EKS Clusters In this approach, EKS clusters are deployed to respective workload AWS Accounts and live along side with other AWS resources like Amazon S3 @@ -345,7 +345,7 @@ https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS Pod Identities] documentation on how to setup EKS pod identities in each account. -==== Centralized Networking +=== Centralized Networking You can also utilize AWS RAM to share the VPC Subnets to workload accounts and launch Amazon EKS clusters and other AWS resources in them. @@ -365,7 +365,7 @@ accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS resources. |=== -=== Centralized vs De-centralized EKS clusters +== Centralized vs De-centralized EKS clusters The decision to run with a Centralized or De-centralized will depend on your requirements. This table demonstrates the key differences with each diff --git a/latest/bpg/security/multitenancy.adoc b/latest/bpg/security/multitenancy.adoc index 30820dea0..8cf35ece2 100644 --- a/latest/bpg/security/multitenancy.adoc +++ b/latest/bpg/security/multitenancy.adoc @@ -1,4 +1,4 @@ -== Tenant Isolation += Tenant Isolation When we think of multi-tenancy, we often want to isolate a user or application from other users or applications running on a shared @@ -22,7 +22,7 @@ The following sections will explain how to implement tenant isolation while mitigating the risks of using a single tenant orchestrator like Kubernetes. -=== Soft multi-tenancy +== Soft multi-tenancy With soft multi-tenancy, you use native Kubernetes constructs, e.g. namespaces, roles and role bindings, and network policies, to @@ -79,7 +79,7 @@ inactivity There are three primary use cases that can be addressed by soft multi-tenancy. -==== Enterprise Setting +=== Enterprise Setting The first is in an Enterprise setting where the "`tenants`" are semi-trusted in that they are employees, contractors, or are otherwise @@ -98,7 +98,7 @@ this setting or it may need to be augmented with additional controls for pod security. It may also be necessary to restrict communication between services in different namespaces if stricter isolation is required. -==== Kubernetes as a Service +=== Kubernetes as a Service By contrast, soft multi-tenancy can be used in settings where you want to offer Kubernetes as a service (KaaS). With KaaS, your application is @@ -116,7 +116,7 @@ Sandboxing is where you run the containers of a pod inside a micro VM like Firecracker or in a user-space kernel. Today, you can create sandboxed pods with EKS Fargate. -==== Software as a Service (SaaS) +=== Software as a Service (SaaS) The final use case for soft multi-tenancy is in a Software-as-a-Service (SaaS) setting. In this environment, each tenant is associated with a @@ -129,19 +129,19 @@ directly interface with the Kubernetes API. Instead, the SaaS application is responsible for interfacing with the Kubernetes API to create the necessary objects to support each tenant. -=== Kubernetes Constructs +== Kubernetes Constructs In each of these instances the following constructs are used to isolate tenants from each other: -==== Namespaces +=== Namespaces Namespaces are fundamental to implementing soft multi-tenancy. They allow you to divide the cluster into logical partitions. Quotas, network policies, service accounts, and other objects needed to implement multi-tenancy are scoped to a namespace. -==== Network policies +=== Network policies By default, all pods in a Kubernetes cluster are allowed to communicate with each other. This behavior can be altered using network policies. @@ -169,7 +169,7 @@ are allowed to communicate with each other. enforcement of network policies requires a policy engine such as Calico or Cilium. -==== Role-based access control (RBAC) +=== Role-based access control (RBAC) Roles and role bindings are the Kubernetes objects used to enforce role-based access control (RBAC) in Kubernetes. *Roles* contain lists of @@ -178,7 +178,7 @@ bindings* specify the individuals or groups to whom the roles apply. In the enterprise and KaaS settings, RBAC can be used to permit administration of objects by selected groups or individuals. -==== Quotas +=== Quotas Quotas are used to define limits on workloads hosted in your cluster. With quotas, you can specify the maximum amount of CPU and memory that a @@ -203,7 +203,7 @@ of resources a pod can consume. You can also use quotas to apportion the cluster’s resources to align with a tenant’s spend. This is particularly useful in the KaaS scenario. -==== Pod priority and preemption +=== Pod priority and preemption Pod priority and preemption can be useful when you want to provide more importance to a Pod relative to other Pods. For example, with pod @@ -222,13 +222,13 @@ quorum of Pods, see https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#limitations-of-preemption[Limitations of preemption]. -=== Mitigating controls +== Mitigating controls Your chief concern as an administrator of a multi-tenant environment is preventing an attacker from gaining access to the underlying host. The following controls should be considered to mitigate this risk: -==== Sandboxed execution environments for containers +=== Sandboxed execution environments for containers Sandboxing is a technique by which each container is run in its own isolated virtual machine. Technologies that perform pod sandboxing @@ -239,7 +239,7 @@ For additional information about the effort to make Firecracker a supported runtime for EKS, see https://threadreaderapp.com/thread/1238496944684597248.html. -==== Open Policy Agent (OPA) & Gatekeeper +=== Open Policy Agent (OPA) & Gatekeeper https://github.com/open-policy-agent/gatekeeper[Gatekeeper] is a Kubernetes admission controller that enforces policies created with @@ -254,7 +254,7 @@ There is also an experimental https://github.com/coredns/coredns-opa[OPA plugin for CoreDNS] that allows you to use OPA to filter/control the records returned by CoreDNS. -==== Kyverno +=== Kyverno https://kyverno.io[Kyverno] is a Kubernetes native policy engine that can validate, mutate, and generate configurations with policies as @@ -269,7 +269,7 @@ https://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno[repos for this project. Many others are included in the https://kyverno.io/policies/[policy library] on the Kyverno website. -==== Isolating tenant workloads to specific nodes +=== Isolating tenant workloads to specific nodes Restricting tenant workloads to run on specific nodes can be used to increase isolation in the soft multi-tenancy model. With this approach, @@ -279,7 +279,7 @@ properties (node affinity, and taints and tolerations) are used to target specific nodes for pod scheduling, and prevent pods, from other tenants, from being scheduled on the tenant-specific nodes. -===== Part 1 - Node affinity +==== Part 1 - Node affinity Kubernetes https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity[node @@ -334,7 +334,7 @@ please see this CNCF blog post on https://www.cncf.io/blog/2021/07/27/advanced-kubernetes-pod-to-node-scheduling/[Advanced Kubernetes pod to node scheduling]. -===== Part 2 - Taints and tolerations +==== Part 2 - Taints and tolerations Attracting pods to nodes is just the first part of this three-part approach. For this approach to work, we must repel pods from scheduling @@ -392,7 +392,7 @@ as https://github.com/open-policy-agent/gatekeeper[OPA/Gatekeeper] and https://kyverno.io/[Kyverno] can be used to write validating policies that prevent unauthorized pods from using these permissive tolerations. -===== Part 3 - Policy-based management for node selection +==== Part 3 - Policy-based management for node selection There are several tools that can be used to help manage the node affinity and tolerations of pod specifications, including enforcement of @@ -565,7 +565,7 @@ important when using these policies for tenant-to-node isolation. It is also a good idea to include _Audit_ policies to routinely check your cluster for unwanted configurations. -==== References +=== References * https://github.com/cruise-automation/k-rail[k-rail] Designed to help you secure a multi-tenant environment through the enforcement of certain @@ -573,7 +573,7 @@ policies. * https://d1.awsstatic.com/whitepapers/security-practices-for-multi-tenant-saas-apps-using-eks.pdf[Security Practices for MultiTenant SaaS Applications using Amazon EKS] -=== Hard multi-tenancy +== Hard multi-tenancy Hard multi-tenancy can be implemented by provisioning separate clusters for each tenant. While this provides very strong isolation between @@ -594,7 +594,7 @@ creating a namespace. Nevertheless, a hard-tenancy approach may be necessary in highly-regulated industries or in SaaS environments where strong isolation is required. -=== Future directions +== Future directions The Kubernetes community has recognized the current shortcomings of soft multi-tenancy and the challenges with hard multi-tenancy. The @@ -619,7 +619,7 @@ namespaces for isolation and segmentation, and a command line tool https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/kubectl-mtb/README.md[kubectl-mtb] to validate conformance to the guidelines. -=== Multi-cluster management tools and resources +== Multi-cluster management tools and resources * https://banzaicloud.com/[Banzai Cloud] * https://d2iq.com/solutions/ksphere/kommander[Kommander] diff --git a/latest/bpg/security/network.adoc b/latest/bpg/security/network.adoc index c5a0b1079..c473a9a6d 100644 --- a/latest/bpg/security/network.adoc +++ b/latest/bpg/security/network.adoc @@ -1,4 +1,4 @@ -== Network security += Network security Network security has several facets. The first involves the application of rules which restrict the flow of network traffic between services. @@ -6,12 +6,12 @@ The second involves the encryption of traffic while it is in transit. The mechanisms to implement these security measures on EKS are varied but often include the following items: -=== Traffic control +== Traffic control * Network Policies * Security Groups -=== Network encryption +== Network encryption * Service Mesh * Container Network Interfaces (CNIs) @@ -19,7 +19,7 @@ but often include the following items: * Nitro Instances * ACM Private CA with cert-manager -=== Network policy +== Network policy Within a Kubernetes cluster, all Pod to Pod communication is allowed by default. While this flexibility may help promote experimentation, it is @@ -54,11 +54,11 @@ to `+true+` on the vpc-cni add-on to enable this. Refer https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html[Amazon EKS User guide] for detailed instructions. -=== Recommendations +== Recommendations -==== Getting Started with Network Policies - Follow Principle of Least Privilege +=== Getting Started with Network Policies - Follow Principle of Least Privilege -===== Create a default deny policy +==== Create a default deny policy As with RBAC policies, it is recommended to follow least privileged access principles with network policies. Start by creating a deny all @@ -85,7 +85,7 @@ image::./images/default-deny.jpg[default-deny] !!! tip The image above was created by the network policy viewer from https://orca.tufin.io/netpol/[Tufin]. -===== Create a rule to allow DNS queries +==== Create a rule to allow DNS queries Once you have the default deny all rule in place, you can begin layering on additional rules, such as a rule that allows pods to query CoreDNS @@ -119,7 +119,7 @@ spec: .allow-dns-access image::./images/allow-dns-access.jpg[allow-dns-access] -===== Incrementally add rules to selectively allow the flow of traffic between namespaces/pods +==== Incrementally add rules to selectively allow the flow of traffic between namespaces/pods Understand the application requirements and create fine-grained ingress and egress rules as needed. Below example shows how to restrict ingress @@ -152,7 +152,7 @@ spec: .allow-ingress-app-one image::./images/allow-ingress-app-one.png[allow-ingress-app-one] -==== Monitoring network policy enforcement +=== Monitoring network policy enforcement * *Use Network Policy editor* ** https://networkpolicy.io/[Network policy editor] helps with @@ -202,9 +202,9 @@ contains_label(arr, val) { } ---- -==== Troubleshooting +=== Troubleshooting -===== Monitor the vpc-network-policy-controller, node-agent logs +==== Monitor the vpc-network-policy-controller, node-agent logs Enable the EKS Control plane controller manager logs to diagnose the network policy functionality. You can stream the control plane logs to a @@ -235,7 +235,7 @@ eBPF programs and maps. sudo /opt/cni/bin/aws-eks-na-cli ebpf progs ---- -===== Log network traffic metadata +==== Log network traffic metadata https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html[AWS VPC Flow Logs] captures metadata about the traffic flowing through a VPC, @@ -247,7 +247,7 @@ change as they are replaced, Flow Logs may not be sufficient on its own. Calico Enterprise extends the Flow Logs with pod labels and other metadata, making it easier to decipher the traffic flows between pods. -=== Security groups +== Security groups EKS uses https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS @@ -331,16 +331,16 @@ option, read the three part series on https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/[egress traffic control in Istio]. -=== When to use Network Policy vs Security Group for Pods? +== When to use Network Policy vs Security Group for Pods? -==== When to use Kubernetes network policy +=== When to use Kubernetes network policy * *Controlling pod-to-pod traffic* ** Suitable for controlling network traffic between pods inside a cluster (east-west traffic) * *Control traffic at the IP address or port level (OSI layer 3 or 4)* -==== When to use AWS Security groups for pods (SGP) +=== When to use AWS Security groups for pods (SGP) * *Leverage existing AWS configurations* ** If you already have complex set of EC2 security groups that manage @@ -356,7 +356,7 @@ mechanism to control the traffic from the pods to AWS services. node traffic, use SGP in `+POD_SECURITY_GROUP_ENFORCING_MODE=strict+` mode. -==== Best practices using `+Security groups for pods+` and `+Network Policy+` +=== Best practices using `+Security groups for pods+` and `+Network Policy+` * *Layered security* ** Use a combination of SGP and kubernetes network policy for a layered @@ -387,7 +387,7 @@ effective solution. Using kubernetes network policy and SGP in combination can provide a robust defense-in-depth strategy for your applications running in EKS. -=== Service Mesh Policy Enforcement or Kubernetes network policy +== Service Mesh Policy Enforcement or Kubernetes network policy A `+service mesh+` is a dedicated infrastructure layer that you can add to your applications. It allows you to transparently add capabilities @@ -399,7 +399,7 @@ whereas kubernetes network policies operate at Layer 3 (network) and Layer 4 (transport). There are many offerings in this space like AWS AppMesh, Istio, Linkerd, etc., -==== When to use Service mesh for policy enforcement +=== When to use Service mesh for policy enforcement * Have existing investment in a service mesh * Need more advanced capabilities like traffic management, observability @@ -411,7 +411,7 @@ error rates, requests per second, request volumes etc.) ** You want to implement and leverage service mesh for security features like mTLS -==== Choose Kubernetes network policy for simpler use cases +=== Choose Kubernetes network policy for simpler use cases * Limit which pods can communicate with each other * Network policies require fewer resources than a service mesh making @@ -423,7 +423,7 @@ network policies to provide a baseline level of security and isolation between your pods and then use a service mesh to add additional capabilities like traffic management, observability and security. -=== ThirdParty Network Policy Engines +== ThirdParty Network Policy Engines Consider a Third Party Network Policy Engine when you have advanced policy requirements like Global Network Policies, support for DNS @@ -453,7 +453,7 @@ https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar set of rules for Calico are available at https://docs.projectcalico.org/security/calico-network-policy. -==== Migration to Amazon VPC CNI Network Policy Engine +=== Migration to Amazon VPC CNI Network Policy Engine To maintain consistency and avoid unexpected pod communication behavior, it is recommended to deploy only one Network Policy Engine in your @@ -465,7 +465,7 @@ cluster before applying them in you production environment. This allows you to identify and address any potential issues or inconsistencies in pod communication behavior. -===== Migration Tool +==== Migration Tool To assist in your migration process, we have developed a tool called https://github.com/awslabs/k8s-network-policy-migrator[K8s Network @@ -489,7 +489,7 @@ https://github.com/awslabs/k8s-network-policy-migrator/issues[GitHub issue]. Your feedback is invaluable to us and will assist in the continuous improvement of our services. -==== Additional Resources +=== Additional Resources * https://youtu.be/lEY2WnRHYpg[Kubernetes & Tigera: Network Policies, Security, and Audit] @@ -502,7 +502,7 @@ Editor] an interactive policy editor from Cilium Gadget advise network-policy gadget] Suggests network policies based on an analysis of network traffic -=== Encryption in transit +== Encryption in transit Applications that need to conform to PCI, HIPAA, or other regulations may need to encrypt data while it is in transit. Nowadays TLS is the de @@ -513,7 +513,7 @@ encrypt the data are generated based on a shared secret that is negotiated at the beginning of the session. The following are a few ways that you can encrypt data in a Kubernetes environment. -==== Nitro Instances +=== Nitro Instances Traffic exchanged between the following Nitro instance types, e.g. C5n, G4, I3en, M5dn, M5n, P3dn, R5dn, and R5n, is automatically encrypted by @@ -524,13 +524,13 @@ in transit] for further details on encryption in transit as well as the complete list of instances types that support network encryption by default. -==== Container Network Interfaces (CNIs) +=== Container Network Interfaces (CNIs) https://www.weave.works/oss/net/[WeaveNet] can be configured to automatically encrypt all traffic using NaCl encryption for sleeve traffic, and IPsec ESP for fast datapath traffic. -==== Service Mesh +=== Service Mesh Encryption in transit can also be implemented with a service mesh like App Mesh, Linkerd v2, and Istio. AppMesh supports @@ -564,7 +564,7 @@ TLS with File Provided TLS Certificates] * https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm[Configuring TLS with AWS Certificate Manager] -==== Ingress Controllers and Load Balancers +=== Ingress Controllers and Load Balancers Ingress controllers are a way for you to intelligently route HTTP/S traffic that emanates from outside the cluster to services running @@ -581,7 +581,7 @@ establishing the initial handshake. Overall SSL/TLS processing is very CPU intensive. Consequently, if you have the flexibility, try performing the SSL offload at the Ingress or the load balancer. -===== Use encryption with AWS Elastic load balancers +==== Use encryption with AWS Elastic load balancers The https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html[AWS @@ -658,7 +658,7 @@ do I terminate HTTPS traffic on Amazon EKS workloads with ACM?] !!! attention Some Ingresses, like the AWS LB controller, implement the SSL/TLS using Annotations instead of as part of the Ingress Spec. -==== ACM Private CA with cert-manager +=== ACM Private CA with cert-manager You can enable TLS and mTLS to secure your EKS application workloads at the ingress, on the pod, and between pods using ACM Private Certificate @@ -674,7 +674,7 @@ keys encoded in memory (less secure). A centralized CA also gives you more control and improved auditability for private certificates both inside and outside of a Kubernetes environment. -===== Short-Lived CA Mode for Mutual TLS Between Workloads +==== Short-Lived CA Mode for Mutual TLS Between Workloads When using ACM Private CA for mTLS in EKS, it is recommended that you use short lived certificates with _short-lived CA mode_. Although it is @@ -687,7 +687,7 @@ pods in your EKS cluster. https://aws.amazon.com/certificate-manager/private-certificate-authority/[Learn more about ACM Private CA and its benefits here]. -===== ACM Setup Instructions +==== ACM Setup Instructions Start by creating a Private CA by following procedures provided in the https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html[ACM @@ -760,7 +760,7 @@ guide]. https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/[See examples here]. -==== ACM Private CA with Istio and cert-manager +=== ACM Private CA with Istio and cert-manager If you are running Istio in your EKS cluster, you can disable the Istio control plane (specifically `+istiod+`) from functioning as the root @@ -772,7 +772,7 @@ section] and this https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[blog post] for more details. -===== How Certificate Signing Works in Istio (Default) +==== How Certificate Signing Works in Istio (Default) Workloads in Kubernetes are identified using service accounts. If you don’t specify a service account, Kubernetes will automatically assign @@ -803,7 +803,7 @@ the communicating services. image::./images/default-istio-csr-flow.png[Default flow for Istio Certificate Signing Requests] -===== How Certificate Signing Works in Istio with ACM Private CA +==== How Certificate Signing Works in Istio with ACM Private CA You can use a cert-manager add-on called the Istio Certificate Signing Request agent @@ -830,7 +830,7 @@ workload that initiated the CSR. image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio Certificate Signing Requests with istio-csr] -===== Istio with Private CA Setup Instructions +==== Istio with Private CA Setup Instructions [arabic] . Start by following the same @@ -943,7 +943,7 @@ mTLS]. image::./images/istio-csr-requests.png[Istio certificate signing requests] -=== Tools and resources +== Tools and resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/6-network-security[Amazon EKS Security Immersion Workshop - Network security] diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc index 48f9a2de0..c29559002 100644 --- a/latest/bpg/security/pods.adoc +++ b/latest/bpg/security/pods.adoc @@ -1,4 +1,4 @@ -== Pod Security += Pod Security The pod specification includes a variety of different attributes that can strengthen or weaken your overall security posture. As a Kubernetes @@ -6,7 +6,7 @@ practitioner your chief concern should be preventing a process that’s running in a container from escaping the isolation boundaries of the container runtime and gaining access to the underlying host. -=== Linux Capabilities +== Linux Capabilities The processes that run within a container run under the context of the [Linux] root user by default. Although the actions of root within a @@ -30,7 +30,7 @@ Fargate pods. Pods that are run as privileged, inherit _all_ of the Linux capabilities associated with root on the host. This should be avoided if possible. -==== Node Authorization +=== Node Authorization All Kubernetes worker nodes use an authorization mode called https://kubernetes.io/docs/reference/access-authn-authz/node/[Node @@ -71,9 +71,9 @@ will still be able to glean sensitive information about the environment from the Kubernetes API that could allow them to move laterally within the cluster. -=== Pod Security Solutions +== Pod Security Solutions -==== Pod Security Policy (PSP) +=== Pod Security Policy (PSP) In the past, https://kubernetes.io/docs/concepts/policy/pod-security-policy/[Pod @@ -90,7 +90,7 @@ are deprecated] in Kubernetes version 1.21. You will have until version https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation[document] explains the motivation for this deprecation. -==== Migrating to a new pod security solution +=== Migrating to a new pod security solution Since PSPs have been removed as of Kubernetes v1.25, cluster administrators and operators must replace those security controls. Two @@ -116,7 +116,7 @@ information and guidance on migration to Kyverno with respect to Pod Security Admission (PSA) has been published on the AWS blog https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/[here]. -==== Policy-as-code (PAC) +=== Policy-as-code (PAC) Policy-as-code (PAC) solutions provide guardrails to guide cluster users, and prevent unwanted behaviors, through prescribed and automated @@ -147,7 +147,7 @@ countermeasures for Kubernetes – Part 1] * https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy-based countermeasures for Kubernetes – Part 2] -==== Pod Security Standards (PSS) and Pod Security Admission (PSA) +=== Pod Security Standards (PSS) and Pod Security Admission (PSA) In response to the PSP deprecation and the ongoing need to control pod security out-of-the-box, with a built-in Kubernetes solution, the @@ -304,7 +304,7 @@ pods that satisfy the _baseline_ profile level, and then _warn_ on pods level. This is a useful approach to determine the possible impacts when changing from the _baseline_ to _restricted_ profiles. -===== Existing Pods +==== Existing Pods If a namespace with existing pods is modified to use a more restrictive PSS profile, the _audit_ and _warn_ modes will produce appropriate @@ -318,7 +318,7 @@ Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted namespace/policy-test configured ---- -===== Exemptions +==== Exemptions PSA uses _Exemptions_ to exclude enforcement of violations against pods that would have otherwise been applied. These exemptions are listed @@ -405,7 +405,7 @@ controller (mutating webhook). The instructions for installing and configuring the webhook can be found https://github.com/kubernetes/pod-security-admission/tree/master/webhook[here]. -==== Choosing between policy-as-code and Pod Security Standards +=== Choosing between policy-as-code and Pod Security Standards The Pod Security Standards (PSS) were developed to replace the Pod Security Policy (PSP), by providing a solution that was built-in to @@ -416,7 +416,7 @@ flexible. The following list of Pros and Cons is designed help you make a more informed decision about your pod security solution. -===== Policy-as-code (as compared to Pod Security Standards) +==== Policy-as-code (as compared to Pod Security Standards) Pros: @@ -452,7 +452,7 @@ Cons: * More complex to learn, configure, and support * Policy authoring may require new skills/languages/capabilities -===== Pod Security Admission (as compared to policy-as-code) +==== Pod Security Admission (as compared to policy-as-code) Pros: @@ -469,7 +469,7 @@ Cons: * Only 3 levels of restrictions * Primarily focused on pods -===== Summary +==== Summary If you currently do not have a pod security solution, beyond PSP, and your required pod security posture fits the model defined in the Pod @@ -479,9 +479,9 @@ posture does not fit the PSS model, or you envision adding additional controls, beyond that defined by PSS, then a policy-as-code solution would seem a better fit. -=== Recommendations +== Recommendations -==== Use multiple Pod Security Admission (PSA) modes for a better user experience +=== Use multiple Pod Security Admission (PSA) modes for a better user experience As mentioned earlier, PSA _enforce_ mode prevents pods with PSS violations from being applied, but does not stop higher-level @@ -512,7 +512,7 @@ _warn_ modes are also enabled, the API server client will receive a warning message and the API server audit log event will be annotated with a message as well. -==== Restrict the containers that can run as privileged +=== Restrict the containers that can run as privileged As mentioned, containers that run as privileged inherit all of the Linux capabilities assigned to root on the host. Seldom do containers need @@ -527,7 +527,7 @@ container(s) where the containers of a pod are run on infrastructure that AWS manages. With Fargate, you cannot run a privileged container or configure your pod to use hostNetwork or hostPort. -==== Do not run processes in containers as root +=== Do not run processes in containers as root All containers run as root by default. This could be problematic if an attacker is able to exploit a vulnerability in the application and get @@ -547,7 +547,7 @@ server request payloads, before they are persisted into etcd. Furthermore, policy-as-code solutions can mutate inbound requests, and in some cases, generate new requests. -==== Never run Docker in Docker or mount the socket in the container +=== Never run Docker in Docker or mount the socket in the container While this conveniently lets you to build/run images in Docker containers, you’re basically relinquishing complete control of the node @@ -564,7 +564,7 @@ Kubernetes clusters used for CICD processing, such as building container images, should be isolated from clusters running more generalized workloads. -==== Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only +=== Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only `+hostPath+` is a volume that mounts a directory from the host directly to the container. Rarely will pods need this type of access, but if they @@ -595,7 +595,7 @@ Seth Art’s blog https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation[Bad Pods: Kubernetes Pod Privilege Escalation]. -==== Set requests and limits for each container to avoid resource contention and DoS attacks +=== Set requests and limits for each container to avoid resource contention and DoS attacks A pod without requests or limits can theoretically consume all of the resources available on a host. As additional pods are scheduled onto a @@ -694,7 +694,7 @@ Policy-as-code solutions can be used enforce requests and limits. or to even create the resource quotas and limit ranges when namespaces are created. -==== Do not allow privileged escalation +=== Do not allow privileged escalation Privileged escalation allows a process to change the security context under which its running. Sudo is a good example of this as are binaries @@ -709,7 +709,7 @@ from succeeding if incorrect settings are detected. Pod Security Standards can also be used to prevent pods from using privilege escalation. -==== Disable ServiceAccount token mounts +=== Disable ServiceAccount token mounts For pods that do not need to access the Kubernetes API, you can disable the automatic mounting of a ServiceAccount token on a pod spec, or for @@ -743,7 +743,7 @@ metadata: automountServiceAccountToken: false ---- -==== Disable service discovery +=== Disable service discovery For pods that do not need to lookup or call in-cluster services, you can reduce the amount of information given to a pod. You can set the Pod’s @@ -778,7 +778,7 @@ spec: enableServiceLinks: false ---- -==== Configure your images with read-only root file system +=== Configure your images with read-only root file system Configuring your images with a read-only root file system prevents an attacker from overwriting a binary on the file system that your @@ -805,7 +805,7 @@ cannot be set to `+true+` for a container running on Windows as write access is required for registry and system processes to run inside the container. -=== Tools and resources +== Tools and resources * https://catalog.workshops.aws/eks-security-immersionday/en-US/3-pod-security[Amazon EKS Security Immersion Workshop - Pod Security] diff --git a/latest/bpg/security/process_adoc.sh b/latest/bpg/security/process_adoc.sh new file mode 100755 index 000000000..08fd9846f --- /dev/null +++ b/latest/bpg/security/process_adoc.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Loop through all .adoc files in the current directory +for file in *.adoc; do + # Skip index.adoc + if [ "$file" != "index.adoc" ]; then + echo "Processing $file" + + # Get the title from the first line of the file + title=$(head -n 1 "$file" | sed 's/^= //') + + # Create the new header (using a heredoc to preserve formatting) + read -r -d '' new_header << EOM +//!!NODE_ROOT
+**[."topic"]** +[[${title},${title}.title]] +**= ${title}** +:info_doctype: section +:info_title: ${title} +:info_abstract: ${title} +:info_titleabbrev: ${title} +:imagesdir: images/ +EOM + + # Replace the first line with the new header + awk -v header="$new_header" 'NR==1 {print header; next} 1' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" + fi +done + +echo "Processing complete." \ No newline at end of file diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc index 44abaa2c8..73f59b2f6 100644 --- a/latest/bpg/security/runtime.adoc +++ b/latest/bpg/security/runtime.adoc @@ -1,4 +1,4 @@ -== Runtime security += Runtime security Runtime security provides active protection for your containers while they’re running. The idea is to detect and/or prevent malicious activity @@ -18,7 +18,7 @@ them in your Pods because the scheduler is unaware of which nodes have profiles. See below how tools like Security Profiles Operator can help automate provisioning of profiles onto nodes. -=== Security contexts and built-in Kubernetes controls +== Security contexts and built-in Kubernetes controls Many Linux runtime security mechanisms are tightly integrated with Kubernetes and can be configured through Kubernetes @@ -29,7 +29,7 @@ the host. It is nearly always inappropriate to enable privileged mode in production workloads, but there are many more controls that can provide more granular privileges to containers as appropriate. -==== Linux capabilities +=== Linux capabilities Linux capabilities allow you to grant certain capabilities to a Pod or container without providing all the abilities of the root user. Examples @@ -37,7 +37,7 @@ include `+CAP_NET_ADMIN+`, which allows configuring network interfaces or firewalls, or `+CAP_SYS_TIME+`, which allows manipulation of the system clock. -==== Seccomp +=== Seccomp With secure computing (seccomp) you can prevent a containerized application from making certain syscalls to the underlying host @@ -81,7 +81,7 @@ privilege requirements as seccomp profiles. Security Profiles Operator further allows automating the deployment of recorded profiles to nodes for use by Pods and containers. -==== AppArmor and SELinux +=== AppArmor and SELinux AppArmor and SELinux are known as https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access @@ -105,9 +105,9 @@ can assist with deploying profiles onto nodes in the cluster. (In the future, the project also aims to generate profiles for AppArmor and SELinux as it does for seccomp.) -=== Recommendations +== Recommendations -==== Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments +=== Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments If you do not currently have a solution for continuously monitoring EKS runtimes and analyzing EKS audit logs, and scanning for malware and @@ -138,7 +138,7 @@ for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks`"] to see how to enable these additional EKS security features step-by-step in minutes. -==== Optionally: Use a 3rd party solution for runtime monitoring +=== Optionally: Use a 3rd party solution for runtime monitoring Creating and managing seccomp and Apparmor profiles can be difficult if you’re not familiar with Linux security. If you don’t have the time to @@ -150,7 +150,7 @@ link:#tools-and-resources[tools] section. Additional options can be found on the https://aws.amazon.com/marketplace/features/containers[AWS Marketplace for Containers]. -==== Consider add/dropping Linux capabilities before writing seccomp policies +=== Consider add/dropping Linux capabilities before writing seccomp policies Capabilities involve various checks in kernel functions reachable by syscalls. If the check fails, the syscall typically returns an error. @@ -167,7 +167,7 @@ capabilities gives you the control you need. See https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container[Setting capabilities for- containers] for further information. -==== See whether you can accomplish your aims by using Pod Security Policies (PSPs) +=== See whether you can accomplish your aims by using Pod Security Policies (PSPs) Pod Security Policies offer a lot of different ways to improve your security posture without introducing undue complexity. Explore the @@ -188,7 +188,7 @@ including the full collection of https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod Security Standards]. -=== Tools and Resources +== Tools and Resources * https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6[7 things you should know before you start] From 002cce60e57b08d0e651bb9ca66bf9e7df4d6083 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 26 Jun 2024 23:18:41 +0000 Subject: [PATCH 09/56] fixup --- latest/bpg/security/compliance.adoc | 8 + latest/bpg/security/data.adoc | 8 + latest/bpg/security/detective.adoc | 8 + latest/bpg/security/hosts.adoc | 8 + latest/bpg/security/iam.adoc | 12 +- latest/bpg/security/iam.adoc.backup | 1445 +++++ latest/bpg/security/image.adoc | 8 + latest/bpg/security/incidents.adoc | 8 + latest/bpg/security/index.adoc | 6 +- latest/bpg/security/index.html | 8051 +++++++++++++++---------- latest/bpg/security/multiaccount.adoc | 8 + latest/bpg/security/multitenancy.adoc | 8 + latest/bpg/security/network.adoc | 8 + latest/bpg/security/pods.adoc | 8 + latest/bpg/security/process_adoc.sh | 14 +- latest/bpg/security/runtime.adoc | 8 + latest/bpg/security/test.py | 135 + 17 files changed, 6568 insertions(+), 3183 deletions(-) create mode 100644 latest/bpg/security/iam.adoc.backup create mode 100644 latest/bpg/security/test.py diff --git a/latest/bpg/security/compliance.adoc b/latest/bpg/security/compliance.adoc index a3dbd4819..95e46df92 100644 --- a/latest/bpg/security/compliance.adoc +++ b/latest/bpg/security/compliance.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[compliance,compliance.title]] = Compliance +:info_doctype: section +:info_title: Compliance +:info_abstract: Compliance +:info_titleabbrev: Compliance +:imagesdir: images/ Compliance is a shared responsibility between AWS and the consumers of its services. Generally speaking, AWS is responsible for "`security of diff --git a/latest/bpg/security/data.adoc b/latest/bpg/security/data.adoc index 19e30b243..530b16d1a 100644 --- a/latest/bpg/security/data.adoc +++ b/latest/bpg/security/data.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[data-encryption-and-secrets-management,data-encryption-and-secrets-management.title]] = Data encryption and secrets management +:info_doctype: section +:info_title: Data encryption and secrets management +:info_abstract: Data encryption and secrets management +:info_titleabbrev: Data encryption and secrets management +:imagesdir: images/ == Encryption at rest diff --git a/latest/bpg/security/detective.adoc b/latest/bpg/security/detective.adoc index 734bb9988..2a222d53d 100644 --- a/latest/bpg/security/detective.adoc +++ b/latest/bpg/security/detective.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[auditing-and-logging,auditing-and-logging.title]] = Auditing and logging +:info_doctype: section +:info_title: Auditing and logging +:info_abstract: Auditing and logging +:info_titleabbrev: Auditing and logging +:imagesdir: images/ Collecting and analyzing [audit] logs is useful for a variety of different reasons. Logs can help with root cause analysis and diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index d2f09e394..aae930a56 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] = Protecting the infrastructure (hosts) +:info_doctype: section +:info_title: Protecting the infrastructure (hosts) +:info_abstract: Protecting the infrastructure (hosts) +:info_titleabbrev: Protecting the infrastructure (hosts) +:imagesdir: images/ Inasmuch as it’s important to secure your container images, it’s equally important to safeguard the infrastructure that runs them. This section diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index 34794e471..46db7be1f 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[identity-and-access-management,identity-and-access-management.title]] = Identity and Access Management +:info_doctype: section +:info_title: Identity and Access Management +:info_abstract: Identity and Access Management +:info_titleabbrev: Identity and Access Management +:imagesdir: images/ https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html[Identity and Access Management] (IAM) is an AWS service that performs two @@ -778,10 +786,10 @@ this: "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { - "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1", + "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", - "AccessKeyId": "XXXX36C6WWEJUMHA3L7Z" + "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } } ---- diff --git a/latest/bpg/security/iam.adoc.backup b/latest/bpg/security/iam.adoc.backup new file mode 100644 index 000000000..46db7be1f --- /dev/null +++ b/latest/bpg/security/iam.adoc.backup @@ -0,0 +1,1445 @@ +//!!NODE_ROOT
+[."topic"] +[[identity-and-access-management,identity-and-access-management.title]] += Identity and Access Management +:info_doctype: section +:info_title: Identity and Access Management +:info_abstract: Identity and Access Management +:info_titleabbrev: Identity and Access Management +:imagesdir: images/ + +https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html[Identity +and Access Management] (IAM) is an AWS service that performs two +essential functions: Authentication and Authorization. Authentication +involves the verification of a identity whereas authorization governs +the actions that can be performed by AWS resources. Within AWS, a +resource can be another AWS service, e.g. EC2, or an AWS +https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal[principal] +such as an +https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-users[IAM +User] or +https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-roles[Role]. +The rules governing the actions that a resource is allowed to perform +are expressed as +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html[IAM +policies]. + +== Controlling Access to EKS Clusters + +The Kubernetes project supports a variety of different strategies to +authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, +X.509 certificates, OIDC, etc. EKS currently has native support for +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication[webhook +token authentication], +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens[service +account tokens], and as of February 21, 2021, OIDC authentication. + +The webhook authentication strategy calls a webhook that verifies bearer +tokens. On EKS, these bearer tokens are generated by the AWS CLI or the +https://github.com/kubernetes-sigs/aws-iam-authenticator[aws-iam-authenticator] +client when you run `+kubectl+` commands. As you execute commands, the +token is passed to the kube-apiserver which forwards it to the +authentication webhook. If the request is well-formed, the webhook calls +a pre-signed URL embedded in the token’s body. This URL validates the +request’s signature and returns information about the user, e.g. the +user’s account, Arn, and UserId to the kube-apiserver. + +To manually generate a authentication token, type the following command +in a terminal window: + +[source,bash] +---- +aws eks get-token --cluster-name +---- + +You can also get a token programmatically. Below is an example written +in Go: + +[source,golang] +---- +package main + +import ( + "fmt" + "log" + "sigs.k8s.io/aws-iam-authenticator/pkg/token" +) + +func main() { + g, _ := token.NewGenerator(false, false) + tk, err := g.Get("") + if err != nil { + log.Fatal(err) + } + fmt.Println(tk) +} +---- + +The output should resemble this: + +[source,json] +---- +{ + "kind": "ExecCredential", + "apiVersion": "client.authentication.k8s.io/v1alpha1", + "spec": {}, + "status": { + "expirationTimestamp": "2020-02-19T16:08:27Z", + "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" + } +} +---- + +Each token starts with `+k8s-aws-v1.+` followed by a base64 encoded +string. The string, when decoded, should resemble to something similar +to this: + +[source,bash] +---- +https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393 +---- + +The token consists of a pre-signed URL that includes an Amazon +credential and signature. For additional details see +https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. + +The token has a time to live (TTL) of 15 minutes after which a new token +will need to be generated. This is handled automatically when you use a +client like `+kubectl+`, however, if you’re using the Kubernetes +dashboard, you will need to generate a new token and re-authenticate +each time the token expires. + +Once the user’s identity has been authenticated by the AWS IAM service, +the kube-apiserver reads the `+aws-auth+` ConfigMap in the +`+kube-system+` Namespace to determine the RBAC group to associate with +the user. The `+aws-auth+` ConfigMap is used to create a static mapping +between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC +groups. RBAC groups can be referenced in Kubernetes RoleBindings or +ClusterRoleBindings. They are similar to IAM Roles in that they define a +set of actions (verbs) that can be performed against a collection of +Kubernetes resources (objects). + +=== Cluster Access Manager + +Cluster Access Manager, now the preferred way to manage access of AWS +IAM principals to Amazon EKS clusters, is a functionality of the AWS API +and is an opt-in feature for EKS v1.23 and later clusters (new or +existing). It simplifies identity mapping between AWS IAM and Kubernetes +RBACs, eliminating the need to switch between AWS and Kubernetes APIs or +editing the `+aws-auth+` ConfigMap for access management, reducing +operational overhead, and helping address misconfigurations. The tool +also enables cluster administrators to revoke or refine +`+cluster-admin+` permissions automatically granted to the AWS IAM +principal used to create the cluster. + +This API relies on two concepts: + +* *Access Entries:* A cluster identity directly linked to an AWS IAM +principal (user or role) allowed to authenticate to an Amazon EKS +cluster. +* *Access Policies:* Are Amazon EKS specific policies that provides the +authorization for an Access Entry to perform actions in the Amazon EKS +cluster. + +____ +At launch Amazon EKS supports only predefined and AWS managed policies. +Access policies are not IAM entities and are defined and managed by +Amazon EKS. +____ + +Cluster Access Manager allows the combination of upstream RBAC with +Access Policies supporting allow and pass (but not deny) on Kubernetes +AuthZ decisions regarding API server requests. A deny decision will +happen when both, the upstream RBAC and Amazon EKS authorizers can’t +determine the outcome of a request evaluation. + +With this feature, Amazon EKS supports three modes of authentication: + +[arabic] +. `+CONFIG_MAP+` to continue using `+aws-auth+` configMap exclusively. +. `+API_AND_CONFIG_MAP+` to source authenticated IAM principals from +both EKS Access Entry APIs and the `+aws-auth+` configMap, prioritizing +the Access Entries. Ideal to migrate existing `+aws-auth+` permissions +to Access Entries. +. `+API+` to exclusively rely on EKS Access Entry APIs. This is the new +*recommended approach*. + +To get started, cluster administrators can create or update Amazon EKS +clusters, setting the preferred authentication to `+API_AND_CONFIG_MAP+` +or `+API+` method and define Access Entries to grant access the desired +AWS IAM principals. + +[source,bash] +---- +$ aws eks create-cluster \ + --name \ + --role-arn \ + --resources-vpc-config subnetIds=,endpointPublicAccess=true,endpointPrivateAccess=true \ + --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ + --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false +---- + +The above command is an example to create an Amazon EKS cluster already +without the admin permissions of the cluster creator. + +It is possible to update Amazon EKS clusters configuration to enable +`+API+` authenticationMode using the `+update-cluster-config+` command, +to do that on existing clusters using `+CONFIG_MAP+` you will have to +first update to `+API_AND_CONFIG_MAP+` and then to `+API+`. *These +operations cannot be reverted*, meaning that’s not possible to switch +from `+API+` to `+API_AND_CONFIG_MAP+` or `+CONFIG_MAP+`, and also from +`+API_AND_CONFIG_MAP+` to `+CONFIG_MAP+`. + +[source,bash] +---- +$ aws eks update-cluster-config \ + --name \ + --access-config authenticationMode=API +---- + +The API support commands to add and revoke access to the cluster, as +well as validate the existing Access Policies and Access Entries for the +specified cluster. The default policies are created to match Kubernetes +RBACs as follows. + +[cols=",",options="header",] +|=== +|EKS Access Policy |Kubernetes RBAC +|AmazonEKSClusterAdminPolicy |cluster-admin +|AmazonEKSAdminPolicy |admin +|AmazonEKSEditPolicy |edit +|AmazonEKSViewPolicy |view +|=== + +[source,bash] +---- +$ aws eks list-access-policies +{ + "accessPolicies": [ + { + "name": "AmazonEKSAdminPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" + }, + { + "name": "AmazonEKSClusterAdminPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" + }, + { + "name": "AmazonEKSEditPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" + }, + { + "name": "AmazonEKSViewPolicy", + "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" + } + ] +} + +$ aws eks list-access-entries --cluster-name + +{ + "accessEntries": [] +} +---- + +____ +No Access Entries are available when the cluster is created without the +cluster creator admin permission, which is the only entry created by +default. +____ + +=== The `+aws-auth+` ConfigMap _(deprecated)_ + +One way Kubernetes integration with AWS authentication can be done is +via the `+aws-auth+` ConfigMap, which resides in the `+kube-system+` +Namespace. It is responsible for mapping the AWS IAM Identities (Users, +Groups, and Roles) authentication, to Kubernetes role-based access +control (RBAC) authorization. The `+aws-auth+` ConfigMap is +automatically created in your Amazon EKS cluster during its provisioning +phase. It was initially created to allow nodes to join your cluster, but +as mentioned you can also use this ConfigMap to add RBACs access to IAM +principals. + +To check your cluster’s `+aws-auth+` ConfigMap, you can use the +following command. + +[source,bash] +---- +kubectl -n kube-system get configmap aws-auth -o yaml +---- + +This is a sample of a default configuration of the `+aws-auth+` +ConfigMap. + +[source,yaml] +---- +apiVersion: v1 +data: + mapRoles: | + - groups: + - system:bootstrappers + - system:nodes + - system:node-proxier + rolearn: arn:aws:iam:::role/kube-system- + username: system:node:{{SessionName}} +kind: ConfigMap +metadata: + creationTimestamp: "2023-10-22T18:19:30Z" + name: aws-auth + namespace: kube-system +---- + +The main session of this ConfigMap, is under `+data+` in the +`+mapRoles+` block, which is basically composed by 3 parameters. + +* *groups:* The Kubernetes group(s) to map the IAM Role to. This can be +a default group, or a custom group specified in a `+clusterrolebinding+` +or `+rolebinding+`. In the above example we have just system groups +declared. +* *rolearn:* The ARN of the AWS IAM Role be mapped to the Kubernetes +group(s) add, using the following format +`+arn::iam:::role/role-name+`. +* *username:* The username within Kubernetes to map to the AWS IAM role. +This can be any custom name. + +____ +It is also possible to map permissions for AWS IAM Users, defining a new +configuration block for `+mapUsers+`, under `+data+` in the `+aws-auth+` +ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a +*Best Practice* it’s always recommended to user `+mapRoles+` instead. +____ + +To manage permissions, you can edit the `+aws-auth+` ConfigMap adding or +removing access to your Amazon EKS cluster. Although it’s possible to +edit the `+aws-auth+` ConfigMap manually, it’s recommended using tools +like `+eksctl+`, since this is a very senstitive configuration, and an +inaccurate configuration can lock you outside your Amazon EKS Cluster. +Check the subsection +https://aws.github.io/aws-eks-best-practices/security/docs/iam/#use-tools-to-make-changes-to-the-aws-auth-configmap[Use +tools to make changes to the aws-auth ConfigMap] below for more details. + +== Cluster Access Recommendations + +=== Make the EKS Cluster Endpoint private + +By default when you provision an EKS cluster, the API cluster endpoint +is set to public, i.e. it can be accessed from the Internet. Despite +being accessible from the Internet, the endpoint is still considered +secure because it requires all API requests to be authenticated by IAM +and then authorized by Kubernetes RBAC. That said, if your corporate +security policy mandates that you restrict access to the API from the +Internet or prevents you from routing traffic outside the cluster VPC, +you can: + +* Configure the EKS cluster endpoint to be private. See +https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[Modifying +Cluster Endpoint Access] for further information on this topic. +* Leave the cluster endpoint public and specify which CIDR blocks can +communicate with the cluster endpoint. The blocks are effectively a +whitelisted set of public IP addresses that are allowed to access the +cluster endpoint. +* Configure public access with a set of whitelisted CIDR blocks and set +private endpoint access to enabled. This will allow public access from a +specific range of public IPs while forcing all network traffic between +the kubelets (workers) and the Kubernetes API through the cross-account +ENIs that get provisioned into the cluster VPC when the control plane is +provisioned. + +=== Don’t use a service account token for authentication + +A service account token is a long-lived, static credential. If it is +compromised, lost, or stolen, an attacker may be able to perform all the +actions associated with that token until the service account is deleted. +At times, you may need to grant an exception for applications that have +to consume the Kubernetes API from outside the cluster, e.g. a CI/CD +pipeline application. If such applications run on AWS infrastructure, +like EC2 instances, consider using an instance profile and mapping that +to a Kubernetes RBAC role. + +=== Employ least privileged access to AWS Resources + +An IAM User does not need to be assigned privileges to AWS resources to +access the Kubernetes API. If you need to grant an IAM user access to an +EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user +that maps to a specific Kubernetes RBAC group. + +=== Remove the cluster-admin permissions from the cluster creator principal + +By default Amazon EKS clusters are created with a permanent +`+cluster-admin+` permission bound to the cluster creator principal. +With the Cluster Access Manager API, it’s possible to create clusters +without this permission setting the +`+--access-config bootstrapClusterCreatorAdminPermissions+` to +`+false+`, when using `+API_AND_CONFIG_MAP+` or `+API+` authentication +mode. Revoke this access considered a best practice to avoid any +unwanted changes to the cluster configuration. The process to revoke +this access, follows the same process to revoke any other access to the +cluster. + +The API gives you flexibility to only disassociate an IAM principal from +an Access Policy, in this case the `+AmazonEKSClusterAdminPolicy+`. + +[source,bash] +---- +$ aws eks list-associated-access-policies \ + --cluster-name \ + --principal-arn + +$ aws eks disassociate-access-policy --cluster-name \ + --principal-arn + +{ + "accessEntries": [] +} + +$ aws eks delete-access-entry --cluster-name \ + --principal-arn +---- + +____ +This access can be granted again if needed during an incident, emergency +or break glass scenario where the cluster is otherwise inaccessible. +____ + +If the cluster still configured with the `+CONFIG_MAP+` authentication +method, all additional users should be granted access to the cluster +through the `+aws-auth+` ConfigMap, and after `+aws-auth+` ConfigMap is +configured, the role assigned to the entity that created the cluster, +can be deleted and only recreated in case of an incident, emergency or +break glass scenario, or where the `+aws-auth+` ConfigMap is corrupted +and the cluster is otherwise inaccessible. This can be particularly +useful in production clusters. + +=== Use IAM Roles when multiple users need identical access to the cluster + +Rather than creating an entry for each individual IAM User, allow those +users to assume an IAM Role and map that role to a Kubernetes RBAC +group. This will be easier to maintain, especially as the number of +users that require access grows. + +!!! attention When accessing the EKS cluster with the IAM entity mapped +by `+aws-auth+` ConfigMap, the username described is recorded in the +user field of the Kubernetes audit log. If you’re using an IAM role, the +actual users who assume that role aren’t recorded and can’t be audited. + +If still using the `+aws-auth+` configMap as the authentication method, +when assigning K8s RBAC permissions to an IAM role, you should include +\{\{SessionName}} in your username. That way, the audit log will record +the session name so you can track who the actual user assume this role +along with the CloudTrail log. + +[source,yaml] +---- +- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole + username: testRole:{{SessionName}} + groups: + - system:masters +---- + +____ +In Kubernetes 1.20 and above, this change is no longer required, since +`+user.extra.sessionName.0+` was added to the Kubernetes audit log. +____ + +=== Employ least privileged access when creating RoleBindings and ClusterRoleBindings + +Like the earlier point about granting access to AWS Resources, +RoleBindings and ClusterRoleBindings should only include the set of +permissions necessary to perform a specific function. Avoid using +`+["*"]+` in your Roles and ClusterRoles unless it’s absolutely +necessary. If you’re unsure what permissions to assign, consider using a +tool like https://github.com/liggitt/audit2rbac[audit2rbac] to +automatically generate Roles and binding based on the observed API calls +in the Kubernetes Audit Log. + +=== Create cluster using an automated process + +As seen in earlier steps, when creating an Amazon EKS cluster, if not +using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, +and not opting out to delegate `+cluster-admin+` permissions to the +cluster creator, the IAM entity user or role, such as a federated +user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster’s RBAC +configuration. Even being a best practice to remove this permission, as +described +link:#remove-the-cluster-admin-permissions-from-the-cluster-creator-principal[here] +if using the `+CONFIG_MAP+` authentication method, relying on +`+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a +good idea to create the cluster with an infrastructure automation +pipeline tied to dedicated IAM role, with no permissions to be assumed +by other users or entities and regularly audit this role’s permissions, +policies, and who has access to trigger the pipeline. Also, this role +should not be used to perform routine actions on the cluster, and be +exclusively used to cluster level actions triggered by the pipeline, via +SCM code changes for example. + +=== Create the cluster with a dedicated IAM role + +When you create an Amazon EKS cluster, the IAM entity user or role, such +as a federated user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster’s RBAC +configuration. This access cannot be removed and is not managed through +the `+aws-auth+` ConfigMap. Therefore it is a good idea to create the +cluster with a dedicated IAM role and regularly audit who can assume +this role. This role should not be used to perform routine actions on +the cluster, and instead additional users should be granted access to +the cluster through the `+aws-auth+` ConfigMap for this purpose. After +the `+aws-auth+` ConfigMap is configured, the role should be secured and +only used in temporary elevated privilege mode / break glass for +scenarios where the cluster is otherwise inaccessible. This can be +particularly useful in clusters which do not have direct user access +configured. + +=== Regularly audit access to the cluster + +Who requires access is likely to change over time. Plan to periodically +audit the `+aws-auth+` ConfigMap to see who has been granted access and +the rights they’ve been assigned. You can also use open source tooling +like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], +or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine +the roles bound to a particular service account, user, or group. We’ll +explore this topic further when we get to the section on +link:detective.md[auditing]. Additional ideas can be found in this +https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] +from NCC Group. + +=== If relying on `+aws-auth+` configMap use tools to make changes + +An improperly formatted aws-auth ConfigMap may cause you to lose access +to the cluster. If you need to make changes to the ConfigMap, use a +tool. + +*eksctl* The `+eksctl+` CLI includes a command for adding identity +mappings to the aws-auth ConfigMap. + +View CLI Help: + +[source,bash] +---- +$ eksctl create iamidentitymapping --help +... +---- + +Check the identities mapped to your Amazon EKS Cluster. + +[source,bash] +---- +$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION +ARN USERNAME GROUPS ACCOUNT +arn:aws:iam::788355785855:role/kube-system- system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier +---- + +Make an IAM Role a Cluster Admin: + +[source,bash] +---- +$ eksctl create iamidentitymapping --cluster --region= --arn arn:aws:iam::123456:role/testing --group system:masters --username admin +... +---- + +For more information, review +https://eksctl.io/usage/iam-identity-mappings/[`+eksctl+` docs] + +*https://github.com/keikoproj/aws-auth[aws-auth] by keikoproj* + +`+aws-auth+` by keikoproj includes both a cli and a go library. + +Download and view help CLI help: + +[source,bash] +---- +$ go get github.com/keikoproj/aws-auth +... +$ aws-auth help +... +---- + +Alternatively, install `+aws-auth+` with the +https://krew.sigs.k8s.io[krew plugin manager] for kubectl. + +[source,bash] +---- +$ kubectl krew install aws-auth +... +$ kubectl aws-auth +... +---- + +https://github.com/keikoproj/aws-auth/blob/master/README.md[Review the +aws-auth docs on GitHub] for more information, including the go library. + +*https://github.com/kubernetes-sigs/aws-iam-authenticator/tree/master/cmd/aws-iam-authenticator[AWS +IAM Authenticator CLI]* + +The `+aws-iam-authenticator+` project includes a CLI for updating the +ConfigMap. + +https://github.com/kubernetes-sigs/aws-iam-authenticator/releases[Download +a release] on GitHub. + +Add cluster permissions to an IAM Role: + +[source,bash] +---- +$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config +... +---- + +=== Alternative Approaches to Authentication and Access Management + +While IAM is the preferred way to authenticate users who need access to +an EKS cluster, it is possible to use an OIDC identity provider such as +GitHub using an authentication proxy and Kubernetes +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation[impersonation]. +Posts for two such solutions have been published on the AWS Open Source +blog: + +* https://aws.amazon.com/blogs/opensource/authenticating-eks-github-credentials-teleport/[Authenticating +to EKS Using GitHub Credentials with Teleport] +* https://aws.amazon.com/blogs/opensource/consistent-oidc-authentication-across-multiple-eks-clusters-using-kube-oidc-proxy/[Consistent +OIDC authentication across multiple EKS clusters using kube-oidc-proxy] + +!!! attention EKS natively supports OIDC authentication without using a +proxy. For further information, please read the launch blog, +https://aws.amazon.com/blogs/containers/introducing-oidc-identity-provider-authentication-amazon-eks/[Introducing +OIDC identity provider authentication for Amazon EKS]. For an example +showing how to configure EKS with Dex, a popular open source OIDC +provider with connectors for a variety of different authention methods, +see +https://aws.amazon.com/blogs/containers/using-dex-dex-k8s-authenticator-to-authenticate-to-amazon-eks/[Using +Dex & dex-k8s-authenticator to authenticate to Amazon EKS]. As described +in the blogs, the username/group of users authenticated by an OIDC +provider will appear in the Kubernetes audit log. + +You can also use +https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[AWS +SSO] to federate AWS with an external identity provider, e.g. Azure AD. +If you decide to use this, the AWS CLI v2.0 includes an option to create +a named profile that makes it easy to associate an SSO session with your +current CLI session and assume an IAM role. Know that you must assume a +role _prior_ to running `+kubectl+` as the IAM role is used to determine +the user’s Kubernetes RBAC group. + +== Identities and Credentials for EKS pods + +Certain applications that run within a Kubernetes cluster need +permission to call the Kubernetes API to function properly. For example, +the https://github.com/kubernetes-sigs/aws-load-balancer-controller[AWS +Load Balancer Controller] needs to be able to list a Service’s +Endpoints. The controller also needs to be able to invoke AWS APIs to +provision and configure an ALB. In this section we will explore the best +practices for assigning rights and privileges to Pods. + +=== Kubernetes Service Accounts + +A service account is a special type of object that allows you to assign +a Kubernetes RBAC role to a pod. A default service account is created +automatically for each Namespace within a cluster. When you deploy a pod +into a Namespace without referencing a specific service account, the +default service account for that Namespace will automatically get +assigned to the Pod and the Secret, i.e. the service account (JWT) token +for that service account, will get mounted to the pod as a volume at +`+/var/run/secrets/kubernetes.io/serviceaccount+`. Decoding the service +account token in that directory will reveal the following metadata: + +[source,json] +---- +{ + "iss": "kubernetes/serviceaccount", + "kubernetes.io/serviceaccount/namespace": "default", + "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", + "kubernetes.io/serviceaccount/service-account.name": "default", + "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", + "sub": "system:serviceaccount:default:default" +} +---- + +The default service account has the following permissions to the +Kubernetes API. + +[source,yaml] +---- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: "2020-01-30T18:13:25Z" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:discovery + resourceVersion: "43" + selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery + uid: 350d2ab8-438c-11ea-9438-063a49b60fba +rules: +- nonResourceURLs: + - /api + - /api/* + - /apis + - /apis/* + - /healthz + - /openapi + - /openapi/* + - /version + - /version/ + verbs: + - get +---- + +This role authorizes unauthenticated and authenticated users to read API +information and is deemed safe to be publicly accessible. + +When an application running within a Pod calls the Kubernetes APIs, the +Pod needs to be assigned a service account that explicitly grants it +permission to call those APIs. Similar to guidelines for user access, +the Role or ClusterRole bound to a service account should be restricted +to the API resources and methods that the application needs to function +and nothing else. To use a non-default service account simply set the +`+spec.serviceAccountName+` field of a Pod to the name of the service +account you wish to use. For additional information about creating +service accounts, see +https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions. + +!!! note Prior to Kubernetes 1.24, Kubernetes would automatically create +a secret for each a service account. This secret was mounted to the pod +at /var/run/secrets/kubernetes.io/serviceaccount and would be used by +the pod to authenticate to the Kubernetes API server. In Kubernetes +1.24, a service account token is dynamically generated when the pod runs +and is only valid for an hour by default. A secret for the service +account will not be created. If you have an application that runs +outside the cluster that needs to authenticate to the Kubernetes API, +e.g. Jenkins, you will need to create a secret of type +`+kubernetes.io/service-account-token+` along with an annotation that +references the service account such as +`+metadata.annotations.kubernetes.io/service-account.name: +`. +Secrets created in this way do not expire. + +=== IAM Roles for Service Accounts (IRSA) + +IRSA is a feature that allows you to assign an IAM role to a Kubernetes +service account. It works by leveraging a Kubernetes feature known as +https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection[Service +Account Token Volume Projection]. When Pods are configured with a +Service Account that references an IAM Role, the Kubernetes API server +will call the public OIDC discovery endpoint for the cluster on startup. +The endpoint cryptographically signs the OIDC token issued by Kubernetes +and the resulting token mounted as a volume. This signed token allows +the Pod to call the AWS APIs associated IAM role. When an AWS API is +invoked, the AWS SDKs calls `+sts:AssumeRoleWithWebIdentity+`. After +validating the token’s signature, IAM exchanges the Kubernetes issued +token for a temporary AWS role credential. + +When using IRSA, it is important to +link:#reuse-aws-sdk-sessions-with-irsa[reuse AWS SDK sessions] to avoid +unneeded calls to AWS STS. + +Decoding the (JWT) token for IRSA will produce output similar to the +example you see below: + +[source,json] +---- +{ + "aud": [ + "sts.amazonaws.com" + ], + "exp": 1582306514, + "iat": 1582220114, + "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", + "kubernetes.io": { + "namespace": "default", + "pod": { + "name": "alpine-57b5664646-rf966", + "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" + }, + "serviceaccount": { + "name": "s3-read-only", + "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" + } + }, + "nbf": 1582220114, + "sub": "system:serviceaccount:default:s3-read-only" +} +---- + +This particular token grants the Pod view-only privileges to S3 by +assuming an IAM role. When the application attempts to read from S3, the +token is exchanged for a temporary set of IAM credentials that resembles +this: + +[source,json] +---- +{ + "AssumedRoleUser": { + "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", + "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" + }, + "Audience": "sts.amazonaws.com", + "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", + "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", + "Credentials": { + "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", + "Expiration": "2020-02-20T18:49:50Z", + "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" + } +} +---- + +A mutating webhook that runs as part of the EKS control plane injects +the AWS Role ARN and the path to a web identity token file into the Pod +as environment variables. These values can also be supplied manually. + +[source,bash] +---- +AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME +AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token +---- + +The kubelet will automatically rotate the projected token when it is +older than 80% of its total TTL, or after 24 hours. The AWS SDKs are +responsible for reloading the token when it rotates. For further +information about IRSA, see +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html. + +=== EKS Pod Identities + +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] is a feature launched at re:Invent 2023 that allows you +to assign an IAM role to a kubernetes service account, without the need +to configure an Open Id Connect (OIDC) identity provider(IDP) for each +cluster in your AWS account. To use EKS Pod Identity, you must deploy an +agent which runs as a DaemonSet pod on every eligible worker node. This +agent is made available to you as an EKS Add-on and is a pre-requisite +to use EKS Pod Identity feature. Your applications must use a +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html[supported +version of the AWS SDK] to use this feature. + +When EKS Pod Identities are configured for a Pod, EKS will mount and +refresh a pod identity token at +`+/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token+`. +This token will be used by the AWS SDK to communicate with the EKS Pod +Identity Agent, which uses the pod identity token and the agent’s IAM +role to create temporary credentials for your pods by calling the +https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html[AssumeRoleForPodIdentity +API]. The pod identity token delivered to your pods is a JWT issued from +your EKS cluster and cryptographically signed, with appropriate JWT +claims for use with EKS Pod Identities. + +To learn more about EKS Pod Identities, please see +https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/[this +blog]. + +You do not have to make any modifications to your application code to +use EKS Pod Identities. Supported AWS SDK versions will automatically +discover credentials made available with EKS Pod Identities by using the +https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html[credential +provider chain]. Like IRSA, EKS pod identities sets variables within +your pods to direct them how to find AWS credentials. + +==== Working with IAM roles for EKS Pod Identities + +* EKS Pod Identities can only directly assume an IAM role that belongs +to the same AWS account as the EKS cluster. To access an IAM role in +another AWS account, you must assume that role by +https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html[configuring +a profile in your SDK configuration], or in your +https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application’s +code]. +* When EKS Pod Identities are being configured for Service Accounts, the +person or process configuring the Pod Identity Association must have the +`+iam:PassRole+` entitlement for that role. +* Each Service Account may only have one IAM role associated with it +through EKS Pod Identities, however you can associate the same IAM role +with multiple service accounts. +* IAM roles used with EKS Pod Identities must allow the +`+pods.eks.amazonaws.com+` Service Principal to assume them, _and_ set +session tags. The following is an example role trust policy which allows +EKS Pod Identities to use an IAM role: + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "pods.eks.amazonaws.com" + }, + "Action": [ + "sts:AssumeRole", + "sts:TagSession" + ], + "Condition": { + "StringEquals": { + "aws:SourceOrgId": "${aws:ResourceOrgId}" + } + } + } + ] +} +---- + +AWS recommends using condition keys like `+aws:SourceOrgId+` to help +protect against the +https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention[cross-service +confused deputy problem]. In the above example role trust policy, the +`+ResourceOrgId+` is a variable equal to the AWS Organizations +Organization ID of the AWS Organization that the AWS account belongs to. +EKS will pass in a value for `+aws:SourceOrgId+` equal to that when +assuming a role with EKS Pod Identities. + +==== ABAC and EKS Pod Identities + +When EKS Pod Identities assumes an IAM role, it sets the following +session tags: + +[width="100%",cols="<50%,<50%",options="header",] +|=== +|EKS Pod Identities Session Tag |Value +|kubernetes-namespace |The namespace the pod associated with EKS Pod +Identities runs in. + +|kubernetes-service-account |The name of the kubernetes service account +associated with EKS Pod Identities + +|eks-cluster-arn |The ARN of the EKS cluster, +e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. +The cluster ARN is unique, but if a cluster is deleted and recreated in +the same region with the same name, within the same AWS account, it will +have the same ARN. + +|eks-cluster-name |The name of the EKS cluster. Please note that EKS +cluster names can be same within your AWS account, and EKS clusters in +other AWS accounts. + +|kubernetes-pod-name |The name of the pod in EKS. + +|kubernetes-pod-uid |The UID of the pod in EKS. +|=== + +These session tags allow you to use +https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html[Attribute +Based Access Control(ABAC)] to grant access to your AWS resources to +only specific kubernetes service accounts. When doing so, it is _very +important_ to understand that kubernetes service accounts are only +unique within a namespace, and kubernetes namespaces are only unique +within an EKS cluster. These session tags can be accessed in AWS +policies by using the `+aws:PrincipalTag/+` global condition +key, such as `+aws:PrincipalTag/eks-cluster-arn+` + +For example, if you wanted to grant access to only a specific service +account to access an AWS resource in your account with an IAM or +resource policy, you would need to check `+eks-cluster-arn+` and +`+kubernetes-namespace+` tags as well as the +`+kubernetes-service-account+` to ensure that only that service accounts +from the intended cluster have access to that resource as other clusters +could have identical `+kubernetes-service-accounts+` and +`+kubernetes-namespaces+`. + +This example S3 Bucket policy only grants access to objects in the S3 +bucket it’s attached to, only if `+kubernetes-service-account+`, +`+kubernetes-namespace+`, `+eks-cluster-arn+` all meet their expected +values, where the EKS cluster is hosted in the AWS account +`+111122223333+`. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111122223333:root" + }, + "Action": "s3:*", + "Resource": [ + "arn:aws:s3:::ExampleBucket/*" + ], + "Condition": { + "StringEquals": { + "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", + "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", + "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" + } + } + } + ] +} +---- + +=== EKS Pod Identities compared to IRSA + +Both EKS Pod Identities and IRSA are preferred ways to deliver temporary +AWS credentials to your EKS pods. Unless you have specific usecases for +IRSA, we recommend you use EKS Pod Identities when using EKS. This table +helps compare the two features. + +[width="100%",cols="<34%,<33%,<33%",options="header",] +|=== +|# |EKS Pod Identities |IRSA +|Requires permission to create an OIDC IDP in your AWS accounts? |No +|Yes + +|Requires unique IDP setup per cluster |No |Yes + +|Sets relevant session tags for use with ABAC |Yes |No + +|Requires an iam:PassRole Check? |Yes |No + +|Uses AWS STS Quota from your AWS account? |No |Yes + +|Can access other AWS accounts |Indirectly with role chaining |Directly +with sts:AssumeRoleWithWebIdentity + +|Compatible with AWS SDKs |Yes |Yes + +|Requires Pod Identity Agent Daemonset on nodes? |Yes |No +|=== + +== Identities and Credentials for EKS pods Recommendations + +=== Update the aws-node daemonset to use IRSA + +At present, the aws-node daemonset is configured to use a role assigned +to the EC2 instances to assign IPs to pods. This role includes several +AWS managed policies, e.g. AmazonEKS_CNI_Policy and +EC2ContainerRegistryReadOnly that effectively allow *all* pods running +on a node to attach/detach ENIs, assign/unassign IP addresses, or pull +images from ECR. Since this presents a risk to your cluster, it is +recommended that you update the aws-node daemonset to use IRSA. A script +for doing this can be found in the +https://github.com/aws/aws-eks-best-practices/tree/master/projects/enable-irsa/src[repository] +for this guide. + +The aws-node daemonset does not support EKS Pod Identities at this time. + +=== Restrict access to the instance profile assigned to the worker node + +When you use IRSA or EKS Pod Identities, it updates the credential chain +of the pod to use IRSA or EKS Pod Identities first, however, the pod +_can still inherit the rights of the instance profile assigned to the +worker node_. When using IRSA or EKS Pod Identities, it is *strongly* +recommended that you block access +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[instance +metadata] to help ensure that your applications only have the +permissions they require, and not their nodes. + +!!! caution Blocking access to instance metadata will prevent pods that +do not use IRSA or EKS Pod Identities from inheriting the role assigned +to the worker node. + +You can block access to instance metadata by requiring the instance to +use IMDSv2 only and updating the hop count to 1 as in the example below. +You can also include these settings in the node group’s launch template. +Do *not* disable instance metadata as this will prevent components like +the node termination handler and other things that rely on instance +metadata from working properly. + +[source,bash] +---- +$ aws ec2 modify-instance-metadata-options --instance-id --http-tokens required --http-put-response-hop-limit 1 +... +---- + +If you are using Terraform to create launch templates for use with +Managed Node Groups, add the metadata block to configure the hop count +as seen in this code snippet: + +`+tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...+` + +You can also block a pod’s access to EC2 metadata by manipulating +iptables on the node. For further information about this method, see +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access[Limiting +access to the instance metadata service]. + +If you have an application that is using an older version of the AWS SDK +that doesn’t support IRSA or EKS Pod Identities, you should update the +SDK version. + +=== Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster + +The trust policy can be scoped to a Namespace or a specific service +account within a Namespace. When using IRSA it’s best to make the role +trust policy as explicit as possible by including the service account +name. This will effectively prevent other Pods within the same Namespace +from assuming the role. The CLI `+eksctl+` will do this automatically +when you use it to create service accounts/IAM roles. See +https://eksctl.io/usage/iamserviceaccounts/ for further information. + +When working with IAM directly, this is adding condition into the role’s +trust policy that uses conditions to ensure the `+:sub+` claim are the +namespace and service account you expect. As an example, before we had +an IRSA token with a sub claim of +"`system:serviceaccount:default:s3-read-only`" . This is the `+default+` +namespace and the service account is `+s3-read-only+`. You would use a +condition like the following to ensure that only your service account in +a given namespace from your cluster can assume that role: + +[source,json] +---- + "Condition": { + "StringEquals": { + "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", + "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" + } + } +---- + +=== Use one IAM role per application + +With both IRSA and EKS Pod Identity, it is a best practice to give each +application its own IAM role. This gives you improved isolation as you +can modify one application without impacting another, and allows you to +apply the principal of least privilege by only granting an application +the permissions it needs. + +When using ABAC with EKS Pod Identity, you may use a common IAM role +across multiple service accounts and rely on their session attributes +for access control. This is especially useful when operating at scale, +as ABAC allows you to operate with fewer IAM roles. + +=== When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2 + +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[IMDSv2] +requires you use a PUT request to get a session token. The initial PUT +request has to include a TTL for the session token. Newer versions of +the AWS SDKs will handle this and the renewal of said token +automatically. It’s also important to be aware that the default hop +limit on EC2 instances is intentionally set to 1 to prevent IP +forwarding. As a consequence, Pods that request a session token that are +run on EC2 instances may eventually time out and fallback to using the +IMDSv1 data flow. EKS adds support IMDSv2 by _enabling_ both v1 and v2 +and changing the hop limit to 2 on nodes provisioned by eksctl or with +the official CloudFormation templates. + +=== Disable auto-mounting of service account tokens + +If your application doesn’t need to call the Kubernetes API set the +`+automountServiceAccountToken+` attribute to `+false+` in the PodSpec +for your application or patch the default service account in each +namespace so that it’s no longer mounted to pods automatically. For +example: + +[source,bash] +---- +kubectl patch serviceaccount default -p $'automountServiceAccountToken: false' +---- + +=== Use dedicated service accounts for each application + +Each application should have its own dedicated service account. This +applies to service accounts for the Kubernetes API as well as IRSA and +EKS Pod Identity. + +!!! attention If you employ a blue/green approach to cluster upgrades +instead of performing an in-place cluster upgrade when using IRSA, you +will need to update the trust policy of each of the IRSA IAM roles with +the OIDC endpoint of the new cluster. A blue/green cluster upgrade is +where you create a cluster running a newer version of Kubernetes +alongside the old cluster and use a load balancer or a service mesh to +seamlessly shift traffic from services running on the old cluster to the +new cluster. When using blue/green cluster upgrades with EKS Pod +Identity, you would create pod identity associations between the IAM +roles and service accounts in the new cluster. And update the IAM role +trust policy if you have a `+sourceArn+` condition. + +=== Run the application as a non-root user + +Containers run as root by default. While this allows them to read the +web identity token file, running a container as root is not considered a +best practice. As an alternative, consider adding the +`+spec.securityContext.runAsUser+` attribute to the PodSpec. The value +of `+runAsUser+` is arbitrary value. + +In the following example, all processes within the Pod will run under +the user ID specified in the `+runAsUser+` field. + +[source,yaml] +---- +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo +spec: + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + containers: + - name: sec-ctx-demo + image: busybox + command: [ "sh", "-c", "sleep 1h" ] +---- + +When you run a container as a non-root user, it prevents the container +from reading the IRSA service account token because the token is +assigned 0600 [root] permissions by default. If you update the +securityContext for your container to include fsgroup=65534 [Nobody] it +will allow the container to read the token. + +[source,yaml] +---- +spec: + securityContext: + fsGroup: 65534 +---- + +In Kubernetes 1.19 and above, this change is no longer required and +applications can read the IRSA service account token without adding them +to the Nobody group. + +=== Grant least privileged access to applications + +https://github.com/princespaghetti/actionhero[Action Hero] is a utility +that you can run alongside your application to identify the AWS API +calls and corresponding IAM permissions your application needs to +function properly. It is similar to +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html[IAM +Access Advisor] in that it helps you gradually limit the scope of IAM +roles assigned to applications. Consult the documentation on granting +https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege[least +privileged access] to AWS resources for further information. + +Consider setting a +https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html[permissions +boundary] on IAM roles used with IRSA and Pod Identities. You can use +the permissions boundary to ensure that the roles used by IRSA or Pod +Identities can not exceed a maximum level of permissions. For an example +guide on getting started with permissions boundaries with an example +permissions boundary policy, please see this +https://github.com/aws-samples/example-permissions-boundary[github +repo]. + +=== Review and revoke unnecessary anonymous access to your EKS cluster + +Ideally anonymous access should be disabled for all API actions. +Anonymous access is granted by creating a RoleBinding or +ClusterRoleBinding for the Kubernetes built-in user system:anonymous. +You can use the https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] +tool to identify permissions that system:anonymous user has on your +cluster: + +[source,bash] +---- +./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' +system:anonymous cluster-wide ClusterRole/system:discovery +system:unauthenticated cluster-wide ClusterRole/system:discovery +system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer +---- + +Any role or ClusterRole other than system:public-info-viewer should not +be bound to system:anonymous user or system:unauthenticated group. + +There may be some legitimate reasons to enable anonymous access on +specific APIs. If this is the case for your cluster ensure that only +those specific APIs are accessible by anonymous user and exposing those +APIs without authentication doesn’t make your cluster vulnerable. + +Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was +associated to system:discovery and system:basic-user ClusterRoles by +default. Note that even if you have updated your cluster to version 1.14 +or higher, these permissions may still be enabled on your cluster, since +cluster updates do not revoke these permissions. To check which +ClusterRoles have "`system:unauthenticated`" except +system:public-info-viewer you can run the following command (requires jq +util): + +[source,bash] +---- +kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name' +---- + +And "`system:unauthenticated`" can be removed from all the roles except +"`system:public-info-viewer`" using: + +[source,bash] +---- +kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f - +---- + +Alternatively, you can check and remove it manually by kubectl describe +and kubectl edit. To check if system:unauthenticated group has +system:discovery permissions on your cluster run the following command: + +[source,bash] +---- +kubectl describe clusterrolebindings system:discovery + +Name: system:discovery +Labels: kubernetes.io/bootstrapping=rbac-defaults +Annotations: rbac.authorization.kubernetes.io/autoupdate: true +Role: + Kind: ClusterRole + Name: system:discovery +Subjects: + Kind Name Namespace + ---- ---- --------- + Group system:authenticated + Group system:unauthenticated +---- + +To check if system:unauthenticated group has system:basic-user +permission on your cluster run the following command: + +[source,bash] +---- +kubectl describe clusterrolebindings system:basic-user + +Name: system:basic-user +Labels: kubernetes.io/bootstrapping=rbac-defaults +Annotations: rbac.authorization.kubernetes.io/autoupdate: true +Role: + Kind: ClusterRole + Name: system:basic-user +Subjects: + Kind Name Namespace + ---- ---- --------- + Group system:authenticated + Group system:unauthenticated +---- + +If system:unauthenticated group is bound to system:discovery and/or +system:basic-user ClusterRoles on your cluster, you should disassociate +these roles from system:unauthenticated group. Edit system:discovery +ClusterRoleBinding using the following command: + +[source,bash] +---- +kubectl edit clusterrolebindings system:discovery +---- + +The above command will open the current definition of system:discovery +ClusterRoleBinding in an editor as shown below: + +[source,yaml] +---- +# Please edit the object below. Lines beginning with a '#' will be ignored, +# and an empty file will abort the edit. If an error occurs while saving this file will be +# reopened with the relevant failures. +# +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: "2021-06-17T20:50:49Z" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:discovery + resourceVersion: "24502985" + selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery + uid: b7936268-5043-431a-a0e1-171a423abeb6 +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:discovery +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:unauthenticated +---- + +Delete the entry for system:unauthenticated group from the "`subjects`" +section in the above editor screen. + +Repeat the same steps for system:basic-user ClusterRoleBinding. + +=== Reuse AWS SDK sessions with IRSA + +When you use IRSA, applications written using the AWS SDK use the token +delivered to your pods to call `+sts:AssumeRoleWithWebIdentity+` to +generate temporary AWS credentials. This is different from other AWS +compute services, where the compute service delivers temporary AWS +credentials directly to the AWS compute resource, such as a lambda +function. This means that every time an AWS SDK session is initialized, +a call to AWS STS for `+AssumeRoleWithWebIdentity+` is made. If your +application scales rapidly and initializes many AWS SDK sessions, you +may experience throttling from AWS STS as your code will be making many +calls for `+AssumeRoleWithWebIdentity+`. + +To avoid this scenario, we recommend reusing AWS SDK sessions within +your application so that unnecessary calls to +`+AssumeRoleWithWebIdentity+` are not made. + +In the following example code, a session is created using the boto3 +python SDK, and that same session is used to create clients and interact +with both Amazon S3 and Amazon SQS. `+AssumeRoleWithWebIdentity+` is +only called once, and the AWS SDK will refresh the credentials of +`+my_session+` when they expire automatically. + +```python +import boto3 + += Create your own session + +my_session = boto3.session.Session() + += Now we can create low-level clients from our session + +sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') + +s3response = s3.list_buckets() sqsresponse = sqs.list_queues() + +#print the response from the S3 and SQS APIs print("`s3 response:`") +print(s3response) print("`—`") print("`sqs response:`") +print(sqsresponse) ``` +``` + + +If you’re migrating an application from another AWS compute service, +such as EC2, to EKS with IRSA, this is a particularly important detail. +On other compute services initializing an AWS SDK session does not call +AWS STS unless you instruct it to. + +=== Alternative approaches + +While IRSA and EKS Pod Identities are the _preferred ways_ to assign an +AWS identity to a pod, they require that you include recent version of +the AWS SDKs in your application. For a complete listing of the SDKs +that currently support IRSA, see +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, +for EKS Pod Identities, see +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. +If you have an application that you can’t immediately update with a +compatible SDK, there are several community-built solutions available +for assigning IAM roles to Kubernetes pods, including +https://github.com/jtblin/kube2iam[kube2iam] and +https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse, +condone, nor support the use of these solutions, they are frequently +used by the community at large to achieve similar results as IRSA and +EKS Pod Identities. + +If you need to use one of these non-aws provided solutions, please +exercise due diligence and ensure you understand security implications +of doing so. + +== Tools and Resources + +* https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon +EKS Security Immersion Workshop - Identity and Access Management] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/fully-private-cluster[Terraform +EKS Blueprints Pattern - Fully Private Amazon EKS Cluster] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-iam-identity-center[Terraform +EKS Blueprints Pattern - IAM Identity Center Single Sign-On for Amazon +EKS Cluster] +* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-okta[Terraform +EKS Blueprints Pattern - Okta Single Sign-On for Amazon EKS Cluster] +* https://github.com/liggitt/audit2rbac[audit2rbac] +* https://github.com/mhausenblas/rbac.dev[rbac.dev] A list of additional +resources, including blogs and tools, for Kubernetes RBAC +* https://github.com/princespaghetti/actionhero[Action Hero] +* https://github.com/jtblin/kube2iam[kube2iam] +* https://github.com/uswitch/kiam[kiam] diff --git a/latest/bpg/security/image.adoc b/latest/bpg/security/image.adoc index 683266c84..db0caed13 100644 --- a/latest/bpg/security/image.adoc +++ b/latest/bpg/security/image.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[image-security,image-security.title]] = Image security +:info_doctype: section +:info_title: Image security +:info_abstract: Image security +:info_titleabbrev: Image security +:imagesdir: images/ You should consider the container image as your first line of defense against an attack. An insecure, poorly constructed image can allow an diff --git a/latest/bpg/security/incidents.adoc b/latest/bpg/security/incidents.adoc index c4ba64154..247504ef4 100644 --- a/latest/bpg/security/incidents.adoc +++ b/latest/bpg/security/incidents.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[incident-response-and-forensics,incident-response-and-forensics.title]] = Incident response and forensics +:info_doctype: section +:info_title: Incident response and forensics +:info_abstract: Incident response and forensics +:info_titleabbrev: Incident response and forensics +:imagesdir: images/ Your ability to react quickly to an incident can help minimize damage caused from a breach. Having a reliable alerting system that can warn diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 420a3fb8f..22af75f39 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -142,13 +142,13 @@ https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] include::iam.adoc[leveloffset=+1] -include::pods.adoc[leveloffset=+1] -include::multitenancy.adoc[leveloffset=+1] +//include::pods.adoc[leveloffset=+1] ISSUES +//include::multitenancy.adoc[leveloffset=+1] ISSUES include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] include::data.adoc[leveloffset=+1] include::runtime.adoc[leveloffset=+1] -include::hosts.adoc[leveloffset=+1] +//include::hosts.adoc[leveloffset=+1] ISSUES include::compliance.adoc[leveloffset=+1] include::incidents.adoc[leveloffset=+1] include::image.adoc[leveloffset=+1] diff --git a/latest/bpg/security/index.html b/latest/bpg/security/index.html index afb0606c0..a19658510 100644 --- a/latest/bpg/security/index.html +++ b/latest/bpg/security/index.html @@ -433,10 +433,113 @@ #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} + - +
@@ -453,7 +556,7 @@

Amazon EKS Best Practices Guide for Security

-

How to use this guide

+

1. How to use this guide

This guide is meant for security practitioners who are responsible for @@ -467,7 +570,7 @@

How to use this guide

-

Understanding the Shared Responsibility Model

+

2. Understanding the Shared Responsibility Model

Security and compliance are considered shared responsibilities when @@ -489,7 +592,7 @@

Understanding the Shared

-Shared Responsibility Model - Fargate +Shared Responsibility Model - Fargate
Figure 1. Shared Responsibility Model - Fargate
@@ -508,7 +611,7 @@

Understanding the Shared

-Shared Responsibility Model - MNG +Shared Responsibility Model - MNG
Figure 2. Shared Responsibility Model - MNG
@@ -524,7 +627,7 @@

Understanding the Shared

-

Introduction

+

3. Introduction

There are several security best practice areas that are pertinent when @@ -594,7 +697,7 @@

Introduction

-

Feedback

+

4. Feedback

This guide is being released on GitHub so as to collect direct feedback @@ -607,7 +710,7 @@

Feedback

-

Further Reading

+

5. Further Reading

-
-

Identity and Access Management

+
+

7. Identity and Access Management

-

Controlling Access to EKS Clusters

+

7.1. Controlling Access to EKS Clusters

The Kubernetes project supports a variety of different strategies to authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, @@ -759,7 +862,7 @@

Controlling Access to EKS Clusters< Kubernetes resources (objects).

-

Cluster Access Manager

+

7.1.1. Cluster Access Manager

Cluster Access Manager, now the preferred way to manage access of AWS IAM principals to Amazon EKS clusters, is a functionality of the AWS API @@ -939,7 +1042,7 @@

Cluster Access Manager

-

The aws-auth ConfigMap (deprecated)

+

7.1.2. The aws-auth ConfigMap (deprecated)

One way Kubernetes integration with AWS authentication can be done is via the aws-auth ConfigMap, which resides in the kube-system @@ -1028,9 +1131,9 @@

The aws-auth ConfigMap

-

Cluster Access Recommendations

+

7.2. Cluster Access Recommendations

-

Make the EKS Cluster Endpoint private

+

7.2.1. Make the EKS Cluster Endpoint private

By default when you provision an EKS cluster, the API cluster endpoint is set to public, i.e. it can be accessed from the Internet. Despite @@ -1066,7 +1169,7 @@

Make the EKS Cluster Endpoint pr

-

Don’t use a service account token for authentication

+

7.2.2. Don’t use a service account token for authentication

A service account token is a long-lived, static credential. If it is compromised, lost, or stolen, an attacker may be able to perform all the @@ -1079,7 +1182,7 @@

Don’t use a serv

-

Employ least privileged access to AWS Resources

+

7.2.3. Employ least privileged access to AWS Resources

An IAM User does not need to be assigned privileges to AWS resources to access the Kubernetes API. If you need to grant an IAM user access to an @@ -1088,7 +1191,7 @@

Employ least privilege

-

Remove the cluster-admin permissions from the cluster creator principal

+

7.2.4. Remove the cluster-admin permissions from the cluster creator principal

By default Amazon EKS clusters are created with a permanent cluster-admin permission bound to the cluster creator principal. @@ -1152,7 +1255,7 @@

-

Use IAM Roles when multiple users need identical access to the cluster

+

7.2.5. Use IAM Roles when multiple users need identical access to the cluster

Rather than creating an entry for each individual IAM User, allow those users to assume an IAM Role and map that role to a Kubernetes RBAC @@ -1190,7 +1293,7 @@

-

Employ least privileged access when creating RoleBindings and ClusterRoleBindings

+

7.2.6. Employ least privileged access when creating RoleBindings and ClusterRoleBindings

Like the earlier point about granting access to AWS Resources, RoleBindings and ClusterRoleBindings should only include the set of @@ -1203,7 +1306,7 @@

-

Create cluster using an automated process

+

7.2.7. Create cluster using an automated process

As seen in earlier steps, when creating an Amazon EKS cluster, if not using the using API_AND_CONFIG_MAP or API authentication mode, @@ -1226,7 +1329,7 @@

Create cluster using an auto

-

Create the cluster with a dedicated IAM role

+

7.2.8. Create the cluster with a dedicated IAM role

When you create an Amazon EKS cluster, the IAM entity user or role, such as a federated user that creates the cluster, is automatically @@ -1245,7 +1348,7 @@

Create the cluster with a

-

Regularly audit access to the cluster

+

7.2.9. Regularly audit access to the cluster

Who requires access is likely to change over time. Plan to periodically audit the aws-auth ConfigMap to see who has been granted access and @@ -1260,7 +1363,7 @@

Regularly audit access to the cl

-

If relying on aws-auth configMap use tools to make changes

+

7.2.10. If relying on aws-auth configMap use tools to make changes

An improperly formatted aws-auth ConfigMap may cause you to lose access to the cluster. If you need to make changes to the ConfigMap, use a @@ -1358,7 +1461,7 @@

If relying

-

Alternative Approaches to Authentication and Access Management

+

7.2.11. Alternative Approaches to Authentication and Access Management

While IAM is the preferred way to authenticate users who need access to an EKS cluster, it is possible to use an OIDC identity provider such as @@ -1405,7 +1508,7 @@

Alterna

-

Identities and Credentials for EKS pods

+

7.3. Identities and Credentials for EKS pods

Certain applications that run within a Kubernetes cluster need permission to call the Kubernetes API to function properly. For example, @@ -1416,7 +1519,7 @@

Identities and Credentials for practices for assigning rights and privileges to Pods.

-

Kubernetes Service Accounts

+

7.3.1. Kubernetes Service Accounts

A service account is a special type of object that allows you to assign a Kubernetes RBAC role to a pod. A default service account is created @@ -1506,7 +1609,7 @@

Kubernetes Service Accounts

-

IAM Roles for Service Accounts (IRSA)

+

7.3.2. IAM Roles for Service Accounts (IRSA)

IRSA is a feature that allows you to assign an IAM role to a Kubernetes service account. It works by leveraging a Kubernetes feature known as @@ -1600,7 +1703,7 @@

IAM Roles for Service Accounts (IR

-

EKS Pod Identities

+

7.3.3. EKS Pod Identities

EKS Pod Identities is a feature launched at re:Invent 2023 that allows you @@ -1639,7 +1742,7 @@

EKS Pod Identities

your pods to direct them how to find AWS credentials.

-
Working with IAM roles for EKS Pod Identities
+
Working with IAM roles for EKS Pod Identities
  • @@ -1705,7 +1808,7 @@
    Working with IAM roles f
-
ABAC and EKS Pod Identities
+
ABAC and EKS Pod Identities

When EKS Pod Identities assumes an IAM role, it sets the following session tags:

@@ -1813,7 +1916,7 @@
ABAC and EKS Pod Identities
-

EKS Pod Identities compared to IRSA

+

7.3.4. EKS Pod Identities compared to IRSA

Both EKS Pod Identities and IRSA are preferred ways to deliver temporary AWS credentials to your EKS pods. Unless you have specific usecases for @@ -1880,9 +1983,9 @@

EKS Pod Identities compared to IRS

-

Identities and Credentials for EKS pods Recommendations

+

7.4. Identities and Credentials for EKS pods Recommendations

-

Update the aws-node daemonset to use IRSA

+

7.4.1. Update the aws-node daemonset to use IRSA

At present, the aws-node daemonset is configured to use a role assigned to the EC2 instances to assign IPs to pods. This role includes several @@ -1900,7 +2003,7 @@

Update the aws-node daemonse

-

Restrict access to the instance profile assigned to the worker node

+

7.4.2. Restrict access to the instance profile assigned to the worker node

When you use IRSA or EKS Pod Identities, it updates the credential chain of the pod to use IRSA or EKS Pod Identities first, however, the pod @@ -1951,7 +2054,7 @@

Re

-

Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster

+

7.4.3. Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster

The trust policy can be scoped to a Namespace or a specific service account within a Namespace. When using IRSA it’s best to make the role @@ -1983,7 +2086,7 @@

-

Use one IAM role per application

+

7.4.4. Use one IAM role per application

With both IRSA and EKS Pod Identity, it is a best practice to give each application its own IAM role. This gives you improved isolation as you @@ -1999,7 +2102,7 @@

Use one IAM role per application

-

When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2

+

7.4.5. When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2

IMDSv2 requires you use a PUT request to get a session token. The initial PUT @@ -2015,7 +2118,7 @@

-

Disable auto-mounting of service account tokens

+

7.4.6. Disable auto-mounting of service account tokens

If your application doesn’t need to call the Kubernetes API set the automountServiceAccountToken attribute to false in the PodSpec @@ -2030,7 +2133,7 @@

Disable auto-mounting

-

Use dedicated service accounts for each application

+

7.4.7. Use dedicated service accounts for each application

Each application should have its own dedicated service account. This applies to service accounts for the Kubernetes API as well as IRSA and @@ -2051,7 +2154,7 @@

Use dedicated serv

-

Run the application as a non-root user

+

7.4.8. Run the application as a non-root user

Containers run as root by default. While this allows them to read the web identity token file, running a container as root is not considered a @@ -2100,7 +2203,7 @@

Run the application as a non-ro

-

Grant least privileged access to applications

+

7.4.9. Grant least privileged access to applications

Action Hero is a utility that you can run alongside your application to identify the AWS API @@ -2125,7 +2228,7 @@

Grant least privileged a

-

Review and revoke unnecessary anonymous access to your EKS cluster

+

7.4.10. Review and revoke unnecessary anonymous access to your EKS cluster

Ideally anonymous access should be disabled for all API actions. Anonymous access is granted by creating a RoleBinding or @@ -2274,7 +2377,7 @@

Rev

-

Reuse AWS SDK sessions with IRSA

+

7.4.11. Reuse AWS SDK sessions with IRSA

When you use IRSA, applications written using the AWS SDK use the token delivered to your pods to call sts:AssumeRoleWithWebIdentity to @@ -2301,7 +2404,7 @@

Reuse AWS SDK sessions with IRSA

-
import boto3
+
import boto3
 
 = Create your own session
 
@@ -2315,67 +2418,98 @@ 

Reuse AWS SDK sessions with IRSA

#print the response from the S3 and SQS APIs print("`s3 response:`") print(s3response) print("`—`") print("`sqs response:`") -print(sqsresponse) ``` - -If you’re migrating an application from another AWS compute service, +print(sqsresponse) ```
+
+
+
+

If you’re migrating an application from another AWS compute service, such as EC2, to EKS with IRSA, this is a particularly important detail. On other compute services initializing an AWS SDK session does not call -AWS STS unless you instruct it to. - -=== Alternative approaches - -While IRSA and EKS Pod Identities are the _preferred ways_ to assign an +AWS STS unless you instruct it to.

+
+
+
+

7.4.12. Alternative approaches

+
+

While IRSA and EKS Pod Identities are the preferred ways to assign an AWS identity to a pod, they require that you include recent version of the AWS SDKs in your application. For a complete listing of the SDKs that currently support IRSA, see -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, for EKS Pod Identities, see -https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. If you have an application that you can’t immediately update with a compatible SDK, there are several community-built solutions available for assigning IAM roles to Kubernetes pods, including -https://github.com/jtblin/kube2iam[kube2iam] and -https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse, +kube2iam and +kiam. Although AWS doesn’t endorse, condone, nor support the use of these solutions, they are frequently used by the community at large to achieve similar results as IRSA and -EKS Pod Identities. - -If you need to use one of these non-aws provided solutions, please +EKS Pod Identities.

+
+
+

If you need to use one of these non-aws provided solutions, please exercise due diligence and ensure you understand security implications -of doing so. - -== Tools and Resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon -EKS Security Immersion Workshop - Identity and Access Management] -* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/fully-private-cluster[Terraform -EKS Blueprints Pattern - Fully Private Amazon EKS Cluster] -* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-iam-identity-center[Terraform +of doing so.

+
+
+
+ +
+
+
+

8. Pod Security

+
+
+

The pod specification includes a variety of different attributes that can strengthen or weaken your overall security posture. As a Kubernetes practitioner your chief concern should be preventing a process that’s running in a container from escaping the isolation boundaries of the -container runtime and gaining access to the underlying host. - -== Linux Capabilities - -The processes that run within a container run under the context of the +container runtime and gaining access to the underlying host.

+
+
+

8.1. Linux Capabilities

+
+

The processes that run within a container run under the context of the [Linux] root user by default. Although the actions of root within a container are partially constrained by the set of Linux capabilities that the container runtime assigns to the containers, these default @@ -2384,223 +2518,328 @@

Reuse AWS SDK sessions with IRSA

Secrets and ConfigMaps. Below is a list of the default capabilities assigned to containers. For additional information about each capability, see -http://man7.org/linux/man-pages/man7/capabilities.7.html. - -`+CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT+` - -!!! Info - -EC2 and Fargate pods are assigned the aforementioned capabilities by +http://man7.org/linux/man-pages/man7/capabilities.7.html.

+
+
+

CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT

+
+
+

!!! Info

+
+
+

EC2 and Fargate pods are assigned the aforementioned capabilities by default. Additionally, Linux capabilities can only be dropped from -Fargate pods. - -Pods that are run as privileged, inherit _all_ of the Linux capabilities -associated with root on the host. This should be avoided if possible. - -=== Node Authorization - -All Kubernetes worker nodes use an authorization mode called -https://kubernetes.io/docs/reference/access-authn-authz/node/[Node -Authorization]. Node Authorization authorizes all API requests that +Fargate pods.

+
+
+

Pods that are run as privileged, inherit all of the Linux capabilities +associated with root on the host. This should be avoided if possible.

+
+
+

8.1.1. Node Authorization

+
+

All Kubernetes worker nodes use an authorization mode called +Node +Authorization. Node Authorization authorizes all API requests that originate from the kubelet and allows nodes to perform the following -actions: - -Read operations: - -* services -* endpoints -* nodes -* pods -* secrets, configmaps, persistent volume claims and persistent volumes -related to pods bound to the kubelet’s node - -Write operations: - -* nodes and node status (enable the `+NodeRestriction+` admission plugin -to limit a kubelet to modify its own node) -* pods and pod status (enable the `+NodeRestriction+` admission plugin -to limit a kubelet to modify pods bound to itself) -* events - -Auth-related operations: - -* Read/write access to the CertificateSigningRequest (CSR) API for TLS -bootstrapping -* the ability to create TokenReview and SubjectAccessReview for -delegated authentication/authorization checks - -EKS uses the -https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[node -restriction admission controller] which only allows the node to modify a +actions:

+
+
+

Read operations:

+
+
+
    +
  • +

    services

    +
  • +
  • +

    endpoints

    +
  • +
  • +

    nodes

    +
  • +
  • +

    pods

    +
  • +
  • +

    secrets, configmaps, persistent volume claims and persistent volumes +related to pods bound to the kubelet’s node

    +
  • +
+
+
+

Write operations:

+
+
+
    +
  • +

    nodes and node status (enable the NodeRestriction admission plugin +to limit a kubelet to modify its own node)

    +
  • +
  • +

    pods and pod status (enable the NodeRestriction admission plugin +to limit a kubelet to modify pods bound to itself)

    +
  • +
  • +

    events

    +
  • +
+
+
+

Auth-related operations:

+
+
+
    +
  • +

    Read/write access to the CertificateSigningRequest (CSR) API for TLS +bootstrapping

    +
  • +
  • +

    the ability to create TokenReview and SubjectAccessReview for +delegated authentication/authorization checks

    +
  • +
+
+
+

EKS uses the +node +restriction admission controller which only allows the node to modify a limited set of node attributes and pod objects that are bound to the node. Nevertheless, an attacker who manages to get access to the host will still be able to glean sensitive information about the environment from the Kubernetes API that could allow them to move laterally within -the cluster. - -== Pod Security Solutions - -=== Pod Security Policy (PSP) - -In the past, -https://kubernetes.io/docs/concepts/policy/pod-security-policy/[Pod -Security Policy (PSP)] resources were used to specify a set of +the cluster.

+
+
+
+
+

8.2. Pod Security Solutions

+
+

8.2.1. Pod Security Policy (PSP)

+
+

In the past, +Pod +Security Policy (PSP) resources were used to specify a set of requirements that pods had to meet before they could be created. As of Kubernetes version 1.21, PSP have been deprecated. They are scheduled -for removal in Kubernetes version 1.25. - -!!! Attention - -https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/[PSPs -are deprecated] in Kubernetes version 1.21. You will have until version +for removal in Kubernetes version 1.25.

+
+
+

!!! Attention

+
+
+

PSPs +are deprecated in Kubernetes version 1.21. You will have until version 1.25 or roughly 2 years to transition to an alternative. This -https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md#motivation[document] -explains the motivation for this deprecation. - -=== Migrating to a new pod security solution - -Since PSPs have been removed as of Kubernetes v1.25, cluster +document +explains the motivation for this deprecation.

+
+
+
+

8.2.2. Migrating to a new pod security solution

+
+

Since PSPs have been removed as of Kubernetes v1.25, cluster administrators and operators must replace those security controls. Two -solutions can fill this need: - -* Policy-as-code (PAC) solutions from the Kubernetes ecosystem -* Kubernetes -https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod -Security Standards (PSS)] - -Both the PAC and PSS solutions can coexist with PSP; they can be used in +solutions can fill this need:

+
+
+ +
+
+

Both the PAC and PSS solutions can coexist with PSP; they can be used in clusters before PSP is removed. This eases adoption when migrating from PSP. Please see this -https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/[document] -when considering migrating from PSP to PSS. - -Kyverno, one of the PAC solutions outlined below, has specific guidance +document +when considering migrating from PSP to PSS.

+
+
+

Kyverno, one of the PAC solutions outlined below, has specific guidance outlined in a -https://kyverno.io/blog/2023/05/24/podsecuritypolicy-migration-with-kyverno/[blog -post] when migrating from PSPs to its solution including analogous +blog +post when migrating from PSPs to its solution including analogous policies, feature comparisons, and a migration procedure. Additional information and guidance on migration to Kyverno with respect to Pod Security Admission (PSA) has been published on the AWS blog -https://aws.amazon.com/blogs/containers/managing-pod-security-on-amazon-eks-with-kyverno/[here]. - -=== Policy-as-code (PAC) - -Policy-as-code (PAC) solutions provide guardrails to guide cluster +here.

+
+
+
+

8.2.3. Policy-as-code (PAC)

+
+

Policy-as-code (PAC) solutions provide guardrails to guide cluster users, and prevent unwanted behaviors, through prescribed and automated controls. PAC uses -https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/[Kubernetes -Dynamic Admission Controllers] to intercept the Kubernetes API server +Kubernetes +Dynamic Admission Controllers to intercept the Kubernetes API server request flow, via a webhook call, and mutate and validate request payloads, based on policies written and stored as code. Mutation and validation happens before the API server request results in a change to the cluster. PAC solutions use policies to match and act on API server -request payloads, based on taxonomy and values. - -There are several open source PAC solutions available for Kubernetes. +request payloads, based on taxonomy and values.

+
+
+

There are several open source PAC solutions available for Kubernetes. These solutions are not part of the Kubernetes project; they are sourced -from the Kubernetes ecosystem. Some PAC solutions are listed below. - -* https://open-policy-agent.github.io/gatekeeper/website/docs/[OPA/Gatekeeper] -* https://www.openpolicyagent.org/[Open Policy Agent (OPA)] -* https://kyverno.io/[Kyverno] -* https://www.kubewarden.io/[Kubewarden] -* https://www.jspolicy.com/[jsPolicy] - -For further information about PAC solutions and how to help you select -the appropriate solution for your needs, see the links below. - -* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy-based -countermeasures for Kubernetes – Part 1] -* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy-based -countermeasures for Kubernetes – Part 2] - -=== Pod Security Standards (PSS) and Pod Security Admission (PSA) - -In response to the PSP deprecation and the ongoing need to control pod +from the Kubernetes ecosystem. Some PAC solutions are listed below.

+
+ +
+

For further information about PAC solutions and how to help you select +the appropriate solution for your needs, see the links below.

+
+ +
+
+

8.2.4. Pod Security Standards (PSS) and Pod Security Admission (PSA)

+
+

In response to the PSP deprecation and the ongoing need to control pod security out-of-the-box, with a built-in Kubernetes solution, the Kubernetes -https://github.com/kubernetes/community/tree/master/sig-auth[Auth -Special Interest Group] created the -https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod -Security Standards (PSS)] and -https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod -Security Admission (PSA)]. The PSA effort includes an -https://github.com/kubernetes/pod-security-admission#pod-security-admission[admission -controller webhook project] that implements the controls defined in the +Auth +Special Interest Group created the +Pod +Security Standards (PSS) and +Pod +Security Admission (PSA). The PSA effort includes an +admission +controller webhook project that implements the controls defined in the PSS. This admission controller approach resembles that used in the PAC -solutions. - -According to the Kubernetes documentation, the PSS _"`define three +solutions.

+
+
+

According to the Kubernetes documentation, the PSS "`define three different policies to broadly cover the security spectrum. These policies are cumulative and range from highly-permissive to -highly-restrictive.`"_ - -These policies are defined as: - -* *Privileged:* Unrestricted (unsecure) policy, providing the widest +highly-restrictive.`"

+
+
+

These policies are defined as:

+
+
+
    +
  • +

    Privileged: Unrestricted (unsecure) policy, providing the widest possible level of permissions. This policy allows for known privilege escalations. It is the absence of a policy. This is good for applications such as logging agents, CNIs, storage drivers, and other -system wide applications that need privileged access. -* *Baseline:* Minimally restrictive policy which prevents known +system wide applications that need privileged access.

    +
  • +
  • +

    Baseline: Minimally restrictive policy which prevents known privilege escalations. Allows the default (minimally specified) Pod configuration. The baseline policy prohibits use of hostNetwork, hostPID, hostIPC, hostPath, hostPort, the inability to add Linux -capabilities, along with several other restrictions. -* *Restricted:* Heavily restricted policy, following current Pod +capabilities, along with several other restrictions.

    +
  • +
  • +

    Restricted: Heavily restricted policy, following current Pod hardening best practices. This policy inherits from the baseline and adds further restrictions such as the inability to run as root or a root-group. Restricted policies may impact an application’s ability to function. They are primarily targeted at running security critical -applications. - -These policies define -https://kubernetes.io/docs/concepts/security/pod-security-standards/#profile-details[profiles -for pod execution], arranged into three levels of privileged -vs. restricted access. - -To implement the controls defined by the PSS, PSA operates in three -modes: - -* *enforce:* Policy violations will cause the pod to be rejected. -* *audit:* Policy violations will trigger the addition of an audit +applications.

    +
  • +
+
+
+

These policies define +profiles +for pod execution, arranged into three levels of privileged +vs. restricted access.

+
+
+

To implement the controls defined by the PSS, PSA operates in three +modes:

+
+
+
    +
  • +

    enforce: Policy violations will cause the pod to be rejected.

    +
  • +
  • +

    audit: Policy violations will trigger the addition of an audit annotation to the event recorded in the audit log, but are otherwise -allowed. -* *warn:* Policy violations will trigger a user-facing warning, but are -otherwise allowed. - -These modes and the profile (restriction) levels are configured at the -Kubernetes Namespace level, using labels, as seen in the below example. - -[source,yaml] ----- -apiVersion: v1 -kind: Namespace -metadata: - name: policy-test +allowed.

    +
  • +
  • +

    warn: Policy violations will trigger a user-facing warning, but are +otherwise allowed.

    +
  • +
+
+
+

These modes and the profile (restriction) levels are configured at the +Kubernetes Namespace level, using labels, as seen in the below example.

+
+
+
+
apiVersion: v1
+kind: Namespace
+metadata:
+  name: policy-test
   labels:
-    pod-security.kubernetes.io/enforce: restricted
-----
-
-When used independently, these operational modes have different
-responses that result in different user experiences. The _enforce_ mode
+    pod-security.kubernetes.io/enforce: restricted
+
+
+
+

When used independently, these operational modes have different +responses that result in different user experiences. The enforce mode will prevent pods from being created if respective podSpecs violate the configured restriction level. However, in this mode, non-pod Kubernetes objects that create pods, such as Deployments, will not be prevented from being applied to the cluster, even if the podSpec therein violates the applied PSS. In this case the Deployment will be applied, while the -pod(s) will be prevented from being applied. - -This is a difficult user experience, as there is no immediate indication +pod(s) will be prevented from being applied.

+
+
+

This is a difficult user experience, as there is no immediate indication that the successfully applied Deployment object belies failed pod creation. The offending podSpecs will not create pods. Inspecting the -Deployment resource with `+kubectl get deploy <DEPLOYMENT_NAME> -oyaml+` -will expose the message from the failed pod(s) `+.status.conditions+` -element, as seen below. - -[source,yaml] ----- -... +Deployment resource with kubectl get deploy <DEPLOYMENT_NAME> -oyaml +will expose the message from the failed pod(s) .status.conditions +element, as seen below.

+
+
+
+
...
 status:
   conditions:
     - lastTransitionTime: "2022-01-20T01:02:08Z"
@@ -2614,105 +2853,124 @@ 

Reuse AWS SDK sessions with IRSA

reason: FailedCreate status: "True" type: ReplicaFailure -... ----- - -In both the _audit_ and _warn_ modes, the pod restrictions do not +...
+
+
+
+

In both the audit and warn modes, the pod restrictions do not prevent violating pods from being created and started. However, in these modes audit annotations on API server audit log events and warnings to -API server clients, such as _kubectl_, are triggered, respectively, when +API server clients, such as kubectl, are triggered, respectively, when pods, as well as objects that create pods, contain podSpecs with -violations. A `+kubectl+` _Warning_ message is seen below. - -[source,bash] ----- -Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") -deployment.apps/test created ----- - -The PSA _audit_ and _warn_ modes are useful when introducing the PSS -without negatively impacting cluster operations. - -The PSA operational modes are not mutually exclusive, and can be used in +violations. A kubectl Warning message is seen below.

+
+
+
+
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
+deployment.apps/test created
+
+
+
+

The PSA audit and warn modes are useful when introducing the PSS +without negatively impacting cluster operations.

+
+
+

The PSA operational modes are not mutually exclusive, and can be used in a cumulative manner. As seen below, the multiple modes can be configured -in a single namespace. - -[source,yaml] ----- -apiVersion: v1 +in a single namespace.

+
+
+
+
apiVersion: v1
 kind: Namespace
 metadata:
   name: policy-test
   labels:
     pod-security.kubernetes.io/audit: restricted
     pod-security.kubernetes.io/enforce: restricted
-    pod-security.kubernetes.io/warn: restricted
-----
-
-In the above example, the user-friendly warnings and audit annotations
+    pod-security.kubernetes.io/warn: restricted
+
+
+
+

In the above example, the user-friendly warnings and audit annotations are provided when applying Deployments, while the enforce of violations are also provided at the pod level. In fact multiple PSA labels can use -different profile levels, as seen below. - -[source,yaml] ----- -apiVersion: v1 +different profile levels, as seen below.

+
+
+
+
apiVersion: v1
 kind: Namespace
 metadata:
   name: policy-test
   labels:
     pod-security.kubernetes.io/enforce: baseline
-    pod-security.kubernetes.io/warn: restricted
-----
-
-In the above example, PSA is configured to allow the creation of all
-pods that satisfy the _baseline_ profile level, and then _warn_ on pods
-(and objects that create pods) that violate the _restricted_ profile
+    pod-security.kubernetes.io/warn: restricted
+
+
+
+

In the above example, PSA is configured to allow the creation of all +pods that satisfy the baseline profile level, and then warn on pods +(and objects that create pods) that violate the restricted profile level. This is a useful approach to determine the possible impacts when -changing from the _baseline_ to _restricted_ profiles. - -==== Existing Pods - -If a namespace with existing pods is modified to use a more restrictive -PSS profile, the _audit_ and _warn_ modes will produce appropriate -messages; however, _enforce_ mode will not delete the pods. The warning -messages are seen below. - -[source,bash] ----- -Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest" +changing from the baseline to restricted profiles.

+
+
+
Existing Pods
+
+

If a namespace with existing pods is modified to use a more restrictive +PSS profile, the audit and warn modes will produce appropriate +messages; however, enforce mode will not delete the pods. The warning +messages are seen below.

+
+
+
+
Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest"
 Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
-namespace/policy-test configured
-----
-
-==== Exemptions
-
-PSA uses _Exemptions_ to exclude enforcement of violations against pods
+namespace/policy-test configured
+
+
+
+
+
Exemptions
+
+

PSA uses Exemptions to exclude enforcement of violations against pods that would have otherwise been applied. These exemptions are listed -below. - -* *Usernames:* requests from users with an exempt authenticated (or -impersonated) username are ignored. -* *RuntimeClassNames:* pods and workload resources specifying an exempt -runtime class name are ignored. -* *Namespaces:* pods and workload resources in an exempt namespace are -ignored. - -These exemptions are applied statically in the -https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/#configure-the-admission-controller[PSA -admission controller configuration] as part of the API server -configuration. - -In the _Validating Webhook_ implementation the exemptions can be +below.

+
+
+
    +
  • +

    Usernames: requests from users with an exempt authenticated (or +impersonated) username are ignored.

    +
  • +
  • +

    RuntimeClassNames: pods and workload resources specifying an exempt +runtime class name are ignored.

    +
  • +
  • +

    Namespaces: pods and workload resources in an exempt namespace are +ignored.

    +
  • +
+
+
+

These exemptions are applied statically in the +PSA +admission controller configuration as part of the API server +configuration.

+
+
+

In the Validating Webhook implementation the exemptions can be configured within a Kubernetes -https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/20-configmap.yaml[ConfigMap] +ConfigMap resource that gets mounted as a volume into the -https://github.com/kubernetes/pod-security-admission/blob/master/webhook/manifests/50-deployment.yaml[pod-security-webhook] -container. - -[source,yaml] ----- -apiVersion: v1 +pod-security-webhook +container.

+
+
+
+
apiVersion: v1
 kind: ConfigMap
 metadata:
   name: pod-security-webhook
@@ -2734,19 +2992,20 @@ 

Reuse AWS SDK sessions with IRSA

# Array of runtime class names to exempt. runtimeClasses: [] # Array of namespaces to exempt. - namespaces: ["kube-system","policy-test1"] ----- - -As seen in the above ConfigMap YAML the cluster-wide default PSS level -has been set to _restricted_ for all PSA modes, _audit_, _enforce_, and -_warn_. This affects all namespaces, except those exempted: -`+namespaces: ["kube-system","policy-test1"]+`. Additionally, in the -_ValidatingWebhookConfiguration_ resource, seen below, the -_pod-security-webhook_ namespace is also exempted from configured PSS. - -[source,yaml] ----- -... + namespaces: ["kube-system","policy-test1"]
+
+
+
+

As seen in the above ConfigMap YAML the cluster-wide default PSS level +has been set to restricted for all PSA modes, audit, enforce, and +warn. This affects all namespaces, except those exempted: +namespaces: ["kube-system","policy-test1"]. Additionally, in the +ValidatingWebhookConfiguration resource, seen below, the +pod-security-webhook namespace is also exempted from configured PSS.

+
+
+
+
...
 webhooks:
   # Audit annotations will be prefixed with this name
   - name: "pod-security-webhook.kubernetes.io"
@@ -2760,180 +3019,265 @@ 

Reuse AWS SDK sessions with IRSA

- key: kubernetes.io/metadata.name operator: NotIn values: ["pod-security-webhook"] -... ----- - -!!! Attention - -Pod Security Admissions graduated to stable in Kubernetes v1.25. If you +...
+
+
+
+

!!! Attention

+
+
+

Pod Security Admissions graduated to stable in Kubernetes v1.25. If you wanted to use the Pod Security Admission feature prior to it being enabled by default, you needed to install the dynamic admission controller (mutating webhook). The instructions for installing and configuring the webhook can be found -https://github.com/kubernetes/pod-security-admission/tree/master/webhook[here]. - -=== Choosing between policy-as-code and Pod Security Standards - -The Pod Security Standards (PSS) were developed to replace the Pod +here.

+
+
+
+
+

8.2.5. Choosing between policy-as-code and Pod Security Standards

+
+

The Pod Security Standards (PSS) were developed to replace the Pod Security Policy (PSP), by providing a solution that was built-in to Kubernetes and did not require solutions from the Kubernetes ecosystem. That being said, policy-as-code (PAC) solutions are considerably more -flexible. - -The following list of Pros and Cons is designed help you make a more -informed decision about your pod security solution. - -==== Policy-as-code (as compared to Pod Security Standards) - -Pros: - -* More flexible and more granular (down to attributes of resources if -need be) -* Not just focused on pods, can be used against different resources and -actions -* Not just applied at the namespace level -* More mature than the Pod Security Standards -* Decisions can be based on anything in the API server request payload, +flexible.

+
+
+

The following list of Pros and Cons is designed help you make a more +informed decision about your pod security solution.

+
+
+
Policy-as-code (as compared to Pod Security Standards)
+
+

Pros:

+
+
+
    +
  • +

    More flexible and more granular (down to attributes of resources if +need be)

    +
  • +
  • +

    Not just focused on pods, can be used against different resources and +actions

    +
  • +
  • +

    Not just applied at the namespace level

    +
  • +
  • +

    More mature than the Pod Security Standards

    +
  • +
  • +

    Decisions can be based on anything in the API server request payload, as well as existing cluster resources and external data (solution -dependent) -* Supports mutating API server requests before validation (solution -dependent) -* Can generate complementary policies and Kubernetes resources (solution +dependent)

    +
  • +
  • +

    Supports mutating API server requests before validation (solution +dependent)

    +
  • +
  • +

    Can generate complementary policies and Kubernetes resources (solution dependent - From pod policies, Kyverno can -https://kyverno.io/docs/writing-policies/autogen/[auto-gen] policies for +auto-gen policies for higher-level controllers, such as Deployments. Kyverno can also generate -additional Kubernetes resources _"`when a new resource is created or -when the source is updated`"_ by using -https://kyverno.io/docs/writing-policies/generate/[Generate Rules].) -* Can be used to shift left, into CICD pipelines, before making calls to -the Kubernetes API server (solution dependent) -* Can be used to implement behaviors that are not necessarily security -related, such as best practices, organizational standards, etc. -* Can be used in non-Kubernetes use cases (solution dependent) -* Because of flexibility, the user experience can be tuned to users’ -needs - -Cons: - -* Not built into Kubernetes -* More complex to learn, configure, and support -* Policy authoring may require new skills/languages/capabilities - -==== Pod Security Admission (as compared to policy-as-code) - -Pros: - -* Built into Kubernetes -* Simpler to configure -* No new languages to use or policies to author -* If the cluster default admission level is configured to _privileged_, +additional Kubernetes resources "`when a new resource is created or +when the source is updated`" by using +Generate Rules.)

    +
  • +
  • +

    Can be used to shift left, into CICD pipelines, before making calls to +the Kubernetes API server (solution dependent)

    +
  • +
  • +

    Can be used to implement behaviors that are not necessarily security +related, such as best practices, organizational standards, etc.

    +
  • +
  • +

    Can be used in non-Kubernetes use cases (solution dependent)

    +
  • +
  • +

    Because of flexibility, the user experience can be tuned to users’ +needs

    +
  • +
+
+
+

Cons:

+
+
+
    +
  • +

    Not built into Kubernetes

    +
  • +
  • +

    More complex to learn, configure, and support

    +
  • +
  • +

    Policy authoring may require new skills/languages/capabilities

    +
  • +
+
+
+
+
Pod Security Admission (as compared to policy-as-code)
+
+

Pros:

+
+
+
    +
  • +

    Built into Kubernetes

    +
  • +
  • +

    Simpler to configure

    +
  • +
  • +

    No new languages to use or policies to author

    +
  • +
  • +

    If the cluster default admission level is configured to privileged, namespace labels can be used to opt namespaces into the pod security -profiles. - -Cons: - -* Not as flexible or granular as policy-as-code -* Only 3 levels of restrictions -* Primarily focused on pods - -==== Summary - -If you currently do not have a pod security solution, beyond PSP, and +profiles.

    +
  • +
+
+
+

Cons:

+
+
+
    +
  • +

    Not as flexible or granular as policy-as-code

    +
  • +
  • +

    Only 3 levels of restrictions

    +
  • +
  • +

    Primarily focused on pods

    +
  • +
+
+
+
+
Summary
+
+

If you currently do not have a pod security solution, beyond PSP, and your required pod security posture fits the model defined in the Pod Security Standards (PSS), then an easier path may be to adopt the PSS, in lieu of a policy-as-code solution. However, if your pod security posture does not fit the PSS model, or you envision adding additional controls, beyond that defined by PSS, then a policy-as-code solution -would seem a better fit. - -== Recommendations - -=== Use multiple Pod Security Admission (PSA) modes for a better user experience - -As mentioned earlier, PSA _enforce_ mode prevents pods with PSS +would seem a better fit.

+
+
+
+
+
+

8.3. Recommendations

+
+

8.3.1. Use multiple Pod Security Admission (PSA) modes for a better user experience

+
+

As mentioned earlier, PSA enforce mode prevents pods with PSS violations from being applied, but does not stop higher-level controllers, such as Deployments. In fact, the Deployment will be applied successfully without any indication that the pods failed to be -applied. While you can use _kubectl_ to inspect the Deployment object, +applied. While you can use kubectl to inspect the Deployment object, and discover the failed pods message from the PSA, the user experience could be better. To make the user experience better, multiple PSA modes -(audit, enforce, warn) should be used. - -[source,yaml] ----- -apiVersion: v1 +(audit, enforce, warn) should be used.

+
+
+
+
apiVersion: v1
 kind: Namespace
 metadata:
   name: policy-test
   labels:
     pod-security.kubernetes.io/audit: restricted
     pod-security.kubernetes.io/enforce: restricted
-    pod-security.kubernetes.io/warn: restricted
-----
-
-In the above example, with _enforce_ mode defined, when a Deployment
+    pod-security.kubernetes.io/warn: restricted
+
+
+
+

In the above example, with enforce mode defined, when a Deployment manifest with PSS violations in the respective podSpec is attempted to be applied to the Kubernetes API server, the Deployment will be -successfully applied, but the pods will not. And, since the _audit_ and -_warn_ modes are also enabled, the API server client will receive a +successfully applied, but the pods will not. And, since the audit and +warn modes are also enabled, the API server client will receive a warning message and the API server audit log event will be annotated -with a message as well. - -=== Restrict the containers that can run as privileged - -As mentioned, containers that run as privileged inherit all of the Linux +with a message as well.

+
+
+
+

8.3.2. Restrict the containers that can run as privileged

+
+

As mentioned, containers that run as privileged inherit all of the Linux capabilities assigned to root on the host. Seldom do containers need these types of privileges to function properly. There are multiple methods that can be used to restrict the permissions and capabilities of -containers. - -!!! Attention - -Fargate is a launch type that enables you to run "`serverless`" +containers.

+
+
+

!!! Attention

+
+
+

Fargate is a launch type that enables you to run “serverless” container(s) where the containers of a pod are run on infrastructure that AWS manages. With Fargate, you cannot run a privileged container or -configure your pod to use hostNetwork or hostPort. - -=== Do not run processes in containers as root - -All containers run as root by default. This could be problematic if an +configure your pod to use hostNetwork or hostPort.

+
+
+
+

8.3.3. Do not run processes in containers as root

+
+

All containers run as root by default. This could be problematic if an attacker is able to exploit a vulnerability in the application and get shell access to the running container. You can mitigate this risk a variety of ways. First, by removing the shell from the container image. Second, adding the USER directive to your Dockerfile or running the containers in the pod as a non-root user. The Kubernetes podSpec -includes a set of fields, under `+spec.securityContext+`, that let you +includes a set of fields, under spec.securityContext, that let you specify the user and/or group under which to run your application. These -fields are `+runAsUser+` and `+runAsGroup+` respectively. - -To enforce the use of the `+spec.securityContext+`, and its associated +fields are runAsUser and runAsGroup respectively.

+
+
+

To enforce the use of the spec.securityContext, and its associated elements, within the Kubernetes podSpec, policy-as-code or Pod Security Standards can be added to clusters. These solutions allow you to write and/or use policies or profiles that can validate inbound Kubernetes API server request payloads, before they are persisted into etcd. Furthermore, policy-as-code solutions can mutate inbound requests, and -in some cases, generate new requests. - -=== Never run Docker in Docker or mount the socket in the container - -While this conveniently lets you to build/run images in Docker -containers, you’re basically relinquishing complete control of the node -to the process running in the container. If you need to build container +in some cases, generate new requests.

+
+
+
+

8.3.4. Never run Docker in Docker or mount the socket in the container

+
+

While this conveniently lets you to build/run images in Docker +containers, you’re basically relinquishing complete control of the node +to the process running in the container. If you need to build container images on Kubernetes use -https://github.com/GoogleContainerTools/kaniko[Kaniko], -https://github.com/containers/buildah[buildah], or a build service like -https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html[CodeBuild] -instead. - -!!! Tip - -Kubernetes clusters used for CICD processing, such as building container +Kaniko, +buildah, or a build service like +CodeBuild +instead.

+
+
+

!!! Tip

+
+
+

Kubernetes clusters used for CICD processing, such as building container images, should be isolated from clusters running more generalized -workloads. - -=== Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only - -`+hostPath+` is a volume that mounts a directory from the host directly +workloads.

+
+
+
+

8.3.5. Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only

+
+

hostPath is a volume that mounts a directory from the host directly to the container. Rarely will pods need this type of access, but if they do, you need to be aware of the risks. By default pods that run as root will have write access to the file system exposed by hostPath. This @@ -2941,113 +3285,163 @@

Reuse AWS SDK sessions with IRSA

links to directories or files not directly exposed by the hostPath, e.g. /etc/shadow, install ssh keys, read secrets mounted to the host, and other malicious things. To mitigate the risks from hostPath, -configure the `+spec.containers.volumeMounts+` as `+readOnly+`, for -example: - -[source,yaml] ----- -volumeMounts: +configure the spec.containers.volumeMounts as readOnly, for +example:

+
+
+
+
volumeMounts:
 - name: hostPath-volume
     readOnly: true
-    mountPath: /host-path
-----
-
-You should also use policy-as-code solutions to restrict the directories
-that can be used by `+hostPath+` volumes, or prevent `+hostPath+` usage
-altogether. You can use the Pod Security Standards _Baseline_ or
-_Restricted_ policies to prevent the use of `+hostPath+`.
-
-For further information about the dangers of privileged escalation, read
+    mountPath: /host-path
+
+
+
+

You should also use policy-as-code solutions to restrict the directories +that can be used by hostPath volumes, or prevent hostPath usage +altogether. You can use the Pod Security Standards Baseline or +Restricted policies to prevent the use of hostPath.

+
+
+

For further information about the dangers of privileged escalation, read Seth Art’s blog -https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation[Bad -Pods: Kubernetes Pod Privilege Escalation]. - -=== Set requests and limits for each container to avoid resource contention and DoS attacks - -A pod without requests or limits can theoretically consume all of the +Bad +Pods: Kubernetes Pod Privilege Escalation.

+
+
+
+

8.3.6. Set requests and limits for each container to avoid resource contention and DoS attacks

+
+

A pod without requests or limits can theoretically consume all of the resources available on a host. As additional pods are scheduled onto a node, the node may experience CPU or memory pressure which can cause the Kubelet to terminate or evict pods from the node. While you can’t prevent this from happening all together, setting requests and limits will help minimize resource contention and mitigate the risk from poorly -written applications that consume an excessive amount of resources. - -The `+podSpec+` allows you to specify requests and limits for CPU and +written applications that consume an excessive amount of resources.

+
+
+

The podSpec allows you to specify requests and limits for CPU and memory. CPU is considered a compressible resource because it can be oversubscribed. Memory is incompressible, i.e. it cannot be shared among -multiple containers. - -When you specify _requests_ for CPU or memory, you’re essentially -designating the amount of _memory_ that containers are guaranteed to +multiple containers.

+
+
+

When you specify requests for CPU or memory, you’re essentially +designating the amount of memory that containers are guaranteed to get. Kubernetes aggregates the requests of all the containers in a pod to determine which node to schedule the pod onto. If a container exceeds the requested amount of memory it may be subject to termination if -there’s memory pressure on the node. - -_Limits_ are the maximum amount of CPU and memory resources that a +there’s memory pressure on the node.

+
+
+

Limits are the maximum amount of CPU and memory resources that a container is allowed to consume and directly corresponds to the -`+memory.limit_in_bytes+` value of the cgroup created for the container. +memory.limit_in_bytes value of the cgroup created for the container. A container that exceeds the memory limit will be OOM killed. If a -container exceeds its CPU limit, it will be throttled. - -!!! Tip - -When using container `+resources.limits+` it is strongly recommended +container exceeds its CPU limit, it will be throttled.

+
+
+

!!! Tip

+
+
+

When using container resources.limits it is strongly recommended that container resource usage (a.k.a. Resource Footprints) be data-driven and accurate, based on load testing. Absent an accurate and -trusted resource footprint, container `+resources.limits+` can be -padded. For example, `+resources.limits.memory+` could be padded 20-30% +trusted resource footprint, container resources.limits can be +padded. For example, resources.limits.memory could be padded 20-30% higher than observable maximums, to account for potential memory -resource limit inaccuracies. - -Kubernetes uses three Quality of Service (QoS) classes to prioritize the -workloads running on a node. These include: - -* guaranteed -* burstable -* best-effort - -If limits and requests are not set, the pod is configured as -_best-effort_ (lowest priority). Best-effort pods are the first to get -killed when there is insufficient memory. If limits are set on _all_ +resource limit inaccuracies.

+
+
+

Kubernetes uses three Quality of Service (QoS) classes to prioritize the +workloads running on a node. These include:

+
+
+
    +
  • +

    guaranteed

    +
  • +
  • +

    burstable

    +
  • +
  • +

    best-effort

    +
  • +
+
+
+

If limits and requests are not set, the pod is configured as +best-effort (lowest priority). Best-effort pods are the first to get +killed when there is insufficient memory. If limits are set on all containers within the pod, or if the requests and limits are set to the -same values and not equal to 0, the pod is configured as _guaranteed_ +same values and not equal to 0, the pod is configured as guaranteed (highest priority). Guaranteed pods will not be killed unless they exceed their configured memory limits. If the limits and requests are configured with different values and not equal to 0, or one container within the pod sets limits and the others don’t or have limits set for -different resources, the pods are configured as _burstable_ (medium +different resources, the pods are configured as burstable (medium priority). These pods have some resource guarantees, but can be killed -once they exceed their requested memory. - -!!! Attention - -Requests don’t affect the `+memory_limit_in_bytes+` value of the +once they exceed their requested memory.

+
+
+

!!! Attention

+
+
+

Requests don’t affect the memory_limit_in_bytes value of the container’s cgroup; the cgroup limit is set to the amount of memory available on the host. Nevertheless, setting the requests value too low could cause the pod to be targeted for termination by the kubelet if the -node undergoes memory pressure. - -[width="100%",cols="<25%,<25%,<25%,<25%",options="header",] -|=== -|Class |Priority |Condition |Kill Condition -|Guaranteed |highest |limit = request != 0 |Only exceed memory limits - -|Burstable |medium |limit != request != 0 |Can be killed if exceed -request memory - -|Best-Effort |lowest |limit & request Not Set |First to get killed when -there’s insufficient memory -|=== - -For additional information about resource QoS, please refer to the -https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/[Kubernetes -documentation]. - -You can force the use of requests and limits by setting a -https://kubernetes.io/docs/concepts/policy/resource-quotas/[resource -quota] on a namespace or by creating a -https://kubernetes.io/docs/concepts/policy/limit-range/[limit range]. A +node undergoes memory pressure.

+
+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ClassPriorityConditionKill Condition

Guaranteed

highest

limit = request != 0

Only exceed memory limits

Burstable

medium

limit != request != 0

Can be killed if exceed +request memory

Best-Effort

lowest

limit & request Not Set

First to get killed when +there’s insufficient memory

+
+

For additional information about resource QoS, please refer to the +Kubernetes +documentation.

+
+
+

You can force the use of requests and limits by setting a +resource +quota on a namespace or by creating a +limit range. A resource quota allows you to specify the total amount of resources, e.g. CPU and RAM, allocated to a namespace. When it’s applied to a namespace, it forces you to specify requests and limits for all @@ -3055,155 +3449,195 @@

Reuse AWS SDK sessions with IRSA

you more granular control of the allocation of resources. With limit ranges you can min/max for CPU and memory resources per pod or per container within a namespace. You can also use them to set default -request/limit values if none are provided. - -Policy-as-code solutions can be used enforce requests and limits. or to +request/limit values if none are provided.

+
+
+

Policy-as-code solutions can be used enforce requests and limits. or to even create the resource quotas and limit ranges when namespaces are -created. - -=== Do not allow privileged escalation - -Privileged escalation allows a process to change the security context +created.

+
+
+
+

8.3.7. Do not allow privileged escalation

+
+

Privileged escalation allows a process to change the security context under which its running. Sudo is a good example of this as are binaries with the SUID or SGID bit. Privileged escalation is basically a way for users to execute a file with the permissions of another user or group. You can prevent a container from using privileged escalation by implementing a policy-as-code mutating policy that sets -`+allowPrivilegeEscalation+` to `+false+` or by setting -`+securityContext.allowPrivilegeEscalation+` in the `+podSpec+`. +allowPrivilegeEscalation to false or by setting +securityContext.allowPrivilegeEscalation in the podSpec. Policy-as-code policies can also be used to prevent API server requests from succeeding if incorrect settings are detected. Pod Security Standards can also be used to prevent pods from using privilege -escalation. - -=== Disable ServiceAccount token mounts - -For pods that do not need to access the Kubernetes API, you can disable +escalation.

+
+
+
+

8.3.8. Disable ServiceAccount token mounts

+
+

For pods that do not need to access the Kubernetes API, you can disable the automatic mounting of a ServiceAccount token on a pod spec, or for -all pods that use a particular ServiceAccount. - -!!! Attention - -Disabling ServiceAccount mounting does not prevent a pod from having +all pods that use a particular ServiceAccount.

+
+
+

!!! Attention

+
+
+

Disabling ServiceAccount mounting does not prevent a pod from having network access to the Kubernetes API. To prevent a pod from having any network access to the Kubernetes API, you will need to modify the -https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS -cluster endpoint access] and use a -link:../network/#network-policy[NetworkPolicy] to block pod access. - -[source,yaml] ----- -apiVersion: v1 +EKS +cluster endpoint access and use a +NetworkPolicy to block pod access.

+
+
+
+
apiVersion: v1
 kind: Pod
 metadata:
   name: pod-no-automount
 spec:
-  automountServiceAccountToken: false
-----
-
-[source,yaml]
-----
-apiVersion: v1
+  automountServiceAccountToken: false
+
+
+
+
+
apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: sa-no-automount
-automountServiceAccountToken: false
-----
-
-=== Disable service discovery
-
-For pods that do not need to lookup or call in-cluster services, you can
+automountServiceAccountToken: false
+
+
+
+
+

8.3.9. Disable service discovery

+
+

For pods that do not need to lookup or call in-cluster services, you can reduce the amount of information given to a pod. You can set the Pod’s DNS policy to not use CoreDNS, and not expose services in the pod’s namespace as environment variables. See the -https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables[Kubernetes -docs on environment variables] for more information on service links. -The default value for a pod’s DNS policy is "`ClusterFirst`" which uses -in-cluster DNS, while the non-default value "`Default`" uses the +Kubernetes +docs on environment variables for more information on service links. +The default value for a pod’s DNS policy is “ClusterFirst” which uses +in-cluster DNS, while the non-default value “Default” uses the underlying node’s DNS resolution. See the -https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy[Kubernetes -docs on Pod DNS policy] for more information. - -!!! Attention - -Disabling service links and changing the pod’s DNS policy does not +Kubernetes +docs on Pod DNS policy for more information.

+
+
+

!!! Attention

+
+
+

Disabling service links and changing the pod’s DNS policy does not prevent a pod from having network access to the in-cluster DNS service. An attacker can still enumerate services in a cluster by reaching the in-cluster DNS service. (ex: -`+dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP+`) To prevent +dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP) To prevent in-cluster service discovery, use a -link:../network/#network-policy[NetworkPolicy] to block pod access - -[source,yaml] ----- -apiVersion: v1 +NetworkPolicy to block pod access

+
+
+
+
apiVersion: v1
 kind: Pod
 metadata:
   name: pod-no-service-info
 spec:
     dnsPolicy: Default # "Default" is not the true default value
-    enableServiceLinks: false
-----
-
-=== Configure your images with read-only root file system
-
-Configuring your images with a read-only root file system prevents an
+    enableServiceLinks: false
+
+
+
+
+

8.3.10. Configure your images with read-only root file system

+
+

Configuring your images with a read-only root file system prevents an attacker from overwriting a binary on the file system that your application uses. If your application has to write to the file system, consider writing to a temporary directory or attach and mount a volume. -You can enforce this by setting the pod’s SecurityContext as follows: - -[source,yaml] ----- -... +You can enforce this by setting the pod’s SecurityContext as follows:

+
+
+
+
...
 securityContext:
   readOnlyRootFilesystem: true
-...
-----
-
-Policy-as-code and Pod Security Standards can be used to enforce this
-behavior.
-
-!!! Info
-
-As per https://kubernetes.io/docs/concepts/windows/intro/[Windows
-containers in Kubernetes] `+securityContext.readOnlyRootFilesystem+`
-cannot be set to `+true+` for a container running on Windows as write
+...
+
+
+
+

Policy-as-code and Pod Security Standards can be used to enforce this +behavior.

+
+
+

!!! Info

+
+
+

As per Windows +containers in Kubernetes securityContext.readOnlyRootFilesystem +cannot be set to true for a container running on Windows as write access is required for registry and system processes to run inside the -container. - -== Tools and resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/3-pod-security[Amazon -EKS Security Immersion Workshop - Pod Security] -* https://github.com/open-policy-agent/gatekeeper-library[open-policy-agent/gatekeeper-library: -The OPA Gatekeeper policy library] a library of OPA/Gatekeeper policies -that you can use as a substitute for PSPs. -* https://kyverno.io/policies/[Kyverno Policy Library] -* A collection of common OPA and Kyverno -https://github.com/aws/aws-eks-best-practices/tree/master/policies[policies] -for EKS. -* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-1/[Policy -based countermeasures: part 1] -* https://aws.amazon.com/blogs/containers/policy-based-countermeasures-for-kubernetes-part-2/[Policy -based countermeasures: part 2] -* https://appvia.github.io/psp-migration/[Pod Security Policy Migrator] +container.

+
+
+
+
+

8.4. Tools and resources

+
+ +
+
+
+
+
+

9. Tenant Isolation

+
+
+

When we think of multi-tenancy, we often want to isolate a user or application from other users or applications running on a shared -infrastructure. - -Kubernetes is a _single tenant orchestrator_, i.e. a single instance of +infrastructure.

+
+
+

Kubernetes is a single tenant orchestrator, i.e. a single instance of the control plane is shared among all the tenants within a cluster. There are, however, various Kubernetes objects that you can use to create the semblance of multi-tenancy. For example, Namespaces and @@ -3212,288 +3646,358 @@

Reuse AWS SDK sessions with IRSA

be used to control the amount of cluster resources each tenant can consume. Nevertheless, the cluster is the only construct that provides a strong security boundary. This is because an attacker that manages to -gain access to a host within the cluster can retrieve _all_ Secrets, +gain access to a host within the cluster can retrieve all Secrets, ConfigMaps, and Volumes, mounted on that host. They could also impersonate the Kubelet which would allow them to manipulate the -attributes of the node and/or move laterally within the cluster. - -The following sections will explain how to implement tenant isolation +attributes of the node and/or move laterally within the cluster.

+
+
+

The following sections will explain how to implement tenant isolation while mitigating the risks of using a single tenant orchestrator like -Kubernetes. - -== Soft multi-tenancy - -With soft multi-tenancy, you use native Kubernetes constructs, +Kubernetes.

+
+
+

9.1. Soft multi-tenancy

+
+

With soft multi-tenancy, you use native Kubernetes constructs, e.g. namespaces, roles and role bindings, and network policies, to create logical separation between tenants. RBAC, for example, can prevent tenants from accessing or manipulate each other’s resources. Quotas and limit ranges control the amount of cluster resources each tenant can consume while network policies can help prevent applications -deployed into different namespaces from communicating with each other. - -None of these controls, however, prevent pods from different tenants +deployed into different namespaces from communicating with each other.

+
+
+

None of these controls, however, prevent pods from different tenants from sharing a node. If stronger isolation is required, you can use a node selector, anti-affinity rules, and/or taints and tolerations to force pods from different tenants to be scheduled onto separate nodes; -often referred to as _sole tenant nodes_. This could get rather -complicated, and cost prohibitive, in an environment with many tenants. - -!!! attention Soft multi-tenancy implemented with Namespaces does not +often referred to as sole tenant nodes. This could get rather +complicated, and cost prohibitive, in an environment with many tenants.

+
+
+

!!! attention Soft multi-tenancy implemented with Namespaces does not allow you to provide tenants with a filtered list of Namespaces because Namespaces are a globally scoped Type. If a tenant has the ability to view a particular Namespace, it can view all Namespaces within the -cluster. - -!!! warning With soft-multi-tenancy, tenants retain the ability to query +cluster.

+
+
+

!!! warning With soft-multi-tenancy, tenants retain the ability to query CoreDNS for all services that run within the cluster by default. An -attacker could exploit this by running dig SRV `+*.*.svc.cluster.local+` +attacker could exploit this by running dig SRV *.*.svc.cluster.local from any pod in the cluster. If you need to restrict access to DNS records of services that run within your clusters, consider using the Firewall or Policy plugins for CoreDNS. For additional information, see -https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy. - -https://github.com/kiosk-sh/kiosk[Kiosk] is an open source project that +https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy.

+
+
+

Kiosk is an open source project that can aid in the implementation of soft multi-tenancy. It is implemented as a series of CRDs and controllers that provide the following -capabilities: - -* *Accounts & Account Users* to separate tenants in a shared Kubernetes -cluster -* *Self-Service Namespace Provisioning* for account users -* *Account Limits* to ensure quality of service and fairness when -sharing a cluster -* *Namespace Templates* for secure tenant isolation and self-service -namespace initialization - -https://loft.sh[Loft] is a commercial offering from the maintainers of -Kiosk and https://github.com/devspace-cloud/devspace[DevSpace] that adds -the following capabilities: - -* *Multi-cluster access* for granting access to spaces in different -clusters -* *Sleep mode* scales down deployments in a space during periods of -inactivity -* *Single sign-on* with OIDC authentication providers like GitHub - -There are three primary use cases that can be addressed by soft -multi-tenancy. - -=== Enterprise Setting - -The first is in an Enterprise setting where the "`tenants`" are -semi-trusted in that they are employees, contractors, or are otherwise -authorized by the organization. Each tenant will typically align to an -administrative division such as a department or team. - -In this type of setting, a cluster administrator will usually be -responsible for creating namespaces and managing policies. They may also -implement a delegated administration model where certain individuals are -given oversight of a namespace, allowing them to perform CRUD operations -for non-policy related objects like deployments, services, pods, jobs, -etc. - -The isolation provided by a container runtime may be acceptable within -this setting or it may need to be augmented with additional controls for -pod security. It may also be necessary to restrict communication between -services in different namespaces if stricter isolation is required. - -=== Kubernetes as a Service - -By contrast, soft multi-tenancy can be used in settings where you want -to offer Kubernetes as a service (KaaS). With KaaS, your application is -hosted in a shared cluster along with a collection of controllers and -CRDs that provide a set of PaaS services. Tenants interact directly with -the Kubernetes API server and are permitted to perform CRUD operations -on non-policy objects. There is also an element of self-service in that -tenants may be allowed to create and manage their own namespaces. In -this type of environment, tenants are assumed to be running untrusted -code. - -To isolate tenants in this type of environment, you will likely need to -implement strict network policies as well as _pod sandboxing_. +capabilities:

+
+
+
    +
  • +

    Accounts & Account Users to separate tenants in a shared Kubernetes +cluster

    +
  • +
  • +

    Self-Service Namespace Provisioning for account users

    +
  • +
  • +

    Account Limits to ensure quality of service and fairness when +sharing a cluster

    +
  • +
  • +

    Namespace Templates for secure tenant isolation and self-service +namespace initialization

    +
  • +
+
+
+

Loft is a commercial offering from the maintainers of +Kiosk and DevSpace that adds +the following capabilities:

+
+
+
    +
  • +

    Multi-cluster access for granting access to spaces in different +clusters

    +
  • +
  • +

    Sleep mode scales down deployments in a space during periods of +inactivity

    +
  • +
  • +

    Single sign-on with OIDC authentication providers like GitHub

    +
  • +
+
+
+

There are three primary use cases that can be addressed by soft +multi-tenancy.

+
+
+

9.1.1. Enterprise Setting

+
+

The first is in an Enterprise setting where the “tenants” are +semi-trusted in that they are employees, contractors, or are otherwise +authorized by the organization. Each tenant will typically align to an +administrative division such as a department or team.

+
+
+

In this type of setting, a cluster administrator will usually be +responsible for creating namespaces and managing policies. They may also +implement a delegated administration model where certain individuals are +given oversight of a namespace, allowing them to perform CRUD operations +for non-policy related objects like deployments, services, pods, jobs, +etc.

+
+
+

The isolation provided by a container runtime may be acceptable within +this setting or it may need to be augmented with additional controls for +pod security. It may also be necessary to restrict communication between +services in different namespaces if stricter isolation is required.

+
+
+
+

9.1.2. Kubernetes as a Service

+
+

By contrast, soft multi-tenancy can be used in settings where you want +to offer Kubernetes as a service (KaaS). With KaaS, your application is +hosted in a shared cluster along with a collection of controllers and +CRDs that provide a set of PaaS services. Tenants interact directly with +the Kubernetes API server and are permitted to perform CRUD operations +on non-policy objects. There is also an element of self-service in that +tenants may be allowed to create and manage their own namespaces. In +this type of environment, tenants are assumed to be running untrusted +code.

+
+
+

To isolate tenants in this type of environment, you will likely need to +implement strict network policies as well as pod sandboxing. Sandboxing is where you run the containers of a pod inside a micro VM like Firecracker or in a user-space kernel. Today, you can create -sandboxed pods with EKS Fargate. - -=== Software as a Service (SaaS) - -The final use case for soft multi-tenancy is in a Software-as-a-Service +sandboxed pods with EKS Fargate.

+
+
+
+

9.1.3. Software as a Service (SaaS)

+
+

The final use case for soft multi-tenancy is in a Software-as-a-Service (SaaS) setting. In this environment, each tenant is associated with a -particular _instance_ of an application that’s running within the +particular instance of an application that’s running within the cluster. Each instance often has its own data and uses separate access -controls that are usually independent of Kubernetes RBAC. - -Unlike the other use cases, the tenant in a SaaS setting does not +controls that are usually independent of Kubernetes RBAC.

+
+
+

Unlike the other use cases, the tenant in a SaaS setting does not directly interface with the Kubernetes API. Instead, the SaaS application is responsible for interfacing with the Kubernetes API to -create the necessary objects to support each tenant. - -== Kubernetes Constructs - -In each of these instances the following constructs are used to isolate -tenants from each other: - -=== Namespaces - -Namespaces are fundamental to implementing soft multi-tenancy. They +create the necessary objects to support each tenant.

+
+
+
+
+

9.2. Kubernetes Constructs

+
+

In each of these instances the following constructs are used to isolate +tenants from each other:

+
+
+

9.2.1. Namespaces

+
+

Namespaces are fundamental to implementing soft multi-tenancy. They allow you to divide the cluster into logical partitions. Quotas, network policies, service accounts, and other objects needed to implement -multi-tenancy are scoped to a namespace. - -=== Network policies - -By default, all pods in a Kubernetes cluster are allowed to communicate -with each other. This behavior can be altered using network policies. - -Network policies restrict communication between pods using labels or IP +multi-tenancy are scoped to a namespace.

+
+
+
+

9.2.2. Network policies

+
+

By default, all pods in a Kubernetes cluster are allowed to communicate +with each other. This behavior can be altered using network policies.

+
+
+

Network policies restrict communication between pods using labels or IP address ranges. In a multi-tenant environment where strict network isolation between tenants is required, we recommend starting with a default rule that denies communication between pods, and another rule that allows all pods to query the DNS server for name resolution. With that in place, you can begin adding more permissive rules that allow for communication within a namespace. This can be further refined as -required. - -!!! note Amazon -https://aws.amazon.com/blogs/containers/amazon-vpc-cni-now-supports-kubernetes-network-policies/[VPC -CNI now supports Kubernetes Network Policies] to create policies that +required.

+
+
+

!!! note Amazon +VPC +CNI now supports Kubernetes Network Policies to create policies that can isolate sensitive workloads and protect them from unauthorized access when running Kubernetes on AWS. This means that you can use all the capabilities of the Network Policy API within your Amazon EKS cluster. This level of granular control enables you to implement the principle of least privilege, which ensures that only authorized pods -are allowed to communicate with each other. - -!!! attention Network policies are necessary but not sufficient. The +are allowed to communicate with each other.

+
+
+

!!! attention Network policies are necessary but not sufficient. The enforcement of network policies requires a policy engine such as Calico -or Cilium. - -=== Role-based access control (RBAC) - -Roles and role bindings are the Kubernetes objects used to enforce -role-based access control (RBAC) in Kubernetes. *Roles* contain lists of -actions that can be performed against objects in your cluster. *Role -bindings* specify the individuals or groups to whom the roles apply. In +or Cilium.

+
+
+
+

9.2.3. Role-based access control (RBAC)

+
+

Roles and role bindings are the Kubernetes objects used to enforce +role-based access control (RBAC) in Kubernetes. Roles contain lists of +actions that can be performed against objects in your cluster. Role +bindings specify the individuals or groups to whom the roles apply. In the enterprise and KaaS settings, RBAC can be used to permit -administration of objects by selected groups or individuals. - -=== Quotas - -Quotas are used to define limits on workloads hosted in your cluster. +administration of objects by selected groups or individuals.

+
+
+
+

9.2.4. Quotas

+
+

Quotas are used to define limits on workloads hosted in your cluster. With quotas, you can specify the maximum amount of CPU and memory that a pod can consume, or you can limit the number of resources that can be -allocated in a cluster or namespace. *Limit ranges* allow you to declare -minimum, maximum, and default values for each limit. - -Overcommitting resources in a shared cluster is often beneficial because +allocated in a cluster or namespace. Limit ranges allow you to declare +minimum, maximum, and default values for each limit.

+
+
+

Overcommitting resources in a shared cluster is often beneficial because it allows you maximize your resources. However, unbounded access to a cluster can cause resource starvation, which can lead to performance degradation and loss of application availability. If a pod’s requests are set too low and the actual resource utilization exceeds the capacity of the node, the node will begin to experience CPU or memory pressure. -When this happens, pods may be restarted and/or evicted from the node. - -To prevent this from happening, you should plan to impose quotas on +When this happens, pods may be restarted and/or evicted from the node.

+
+
+

To prevent this from happening, you should plan to impose quotas on namespaces in a multi-tenant environment to force tenants to specify requests and limits when scheduling their pods on the cluster. It will also mitigate a potential denial of service by constraining the amount -of resources a pod can consume. - -You can also use quotas to apportion the cluster’s resources to align -with a tenant’s spend. This is particularly useful in the KaaS scenario. - -=== Pod priority and preemption - -Pod priority and preemption can be useful when you want to provide more +of resources a pod can consume.

+
+
+

You can also use quotas to apportion the cluster’s resources to align +with a tenant’s spend. This is particularly useful in the KaaS scenario.

+
+
+
+

9.2.5. Pod priority and preemption

+
+

Pod priority and preemption can be useful when you want to provide more importance to a Pod relative to other Pods. For example, with pod priority you can configure pods from customer A to run at a higher priority than customer B. When there’s insufficient capacity available, the scheduler will evict the lower-priority pods from customer B to accommodate the higher-priority pods from customer A. This can be especially handy in a SaaS environment where customers willing to pay a -premium receive a higher priority. - -!!! attention Pods priority can have an undesired effect on other Pods +premium receive a higher priority.

+
+
+

!!! attention Pods priority can have an undesired effect on other Pods with lower priority. For example, although the victim pods are terminated gracefully but the PodDisruptionBudget is not guaranteed, which could break a application with lower priority that relies on a quorum of Pods, see -https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#limitations-of-preemption[Limitations -of preemption]. - -== Mitigating controls - -Your chief concern as an administrator of a multi-tenant environment is +Limitations +of preemption.

+
+
+
+
+

9.3. Mitigating controls

+
+

Your chief concern as an administrator of a multi-tenant environment is preventing an attacker from gaining access to the underlying host. The -following controls should be considered to mitigate this risk: - -=== Sandboxed execution environments for containers - -Sandboxing is a technique by which each container is run in its own +following controls should be considered to mitigate this risk:

+
+
+

9.3.1. Sandboxed execution environments for containers

+
+

Sandboxing is a technique by which each container is run in its own isolated virtual machine. Technologies that perform pod sandboxing -include https://firecracker-microvm.github.io/[Firecracker] and Weave’s -https://www.weave.works/blog/firekube-fast-and-secure-kubernetes-clusters-using-weave-ignite[Firekube]. - -For additional information about the effort to make Firecracker a +include Firecracker and Weave’s +Firekube.

+
+
+

For additional information about the effort to make Firecracker a supported runtime for EKS, see -https://threadreaderapp.com/thread/1238496944684597248.html. - -=== Open Policy Agent (OPA) & Gatekeeper - -https://github.com/open-policy-agent/gatekeeper[Gatekeeper] is a +https://threadreaderapp.com/thread/1238496944684597248.html.

+
+
+
+

9.3.2. Open Policy Agent (OPA) & Gatekeeper

+
+

Gatekeeper is a Kubernetes admission controller that enforces policies created with -https://www.openpolicyagent.org/[OPA]. With OPA you can create a policy +OPA. With OPA you can create a policy that runs pods from tenants on separate instances or at a higher priority than other tenants. A collection of common OPA policies can be found in the GitHub -https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository] -for this project. - -There is also an experimental https://github.com/coredns/coredns-opa[OPA -plugin for CoreDNS] that allows you to use OPA to filter/control the -records returned by CoreDNS. - -=== Kyverno - -https://kyverno.io[Kyverno] is a Kubernetes native policy engine that +repository +for this project.

+
+
+

There is also an experimental OPA +plugin for CoreDNS that allows you to use OPA to filter/control the +records returned by CoreDNS.

+
+
+
+

9.3.3. Kyverno

+
+

Kyverno is a Kubernetes native policy engine that can validate, mutate, and generate configurations with policies as Kubernetes resources. Kyverno uses Kustomize-style overlays for validation, supports JSON Patch and strategic merge patch for mutation, -and can clone resources across namespaces based on flexible triggers. - -You can use Kyverno to isolate namespaces, enforce pod security and +and can clone resources across namespaces based on flexible triggers.

+
+
+

You can use Kyverno to isolate namespaces, enforce pod security and other best practices, and generate default configurations such as network policies. Several examples are included in the GitHub -https://github.com/aws/aws-eks-best-practices/tree/master/policies/kyverno[repository] +repository for this project. Many others are included in the -https://kyverno.io/policies/[policy library] on the Kyverno website. - -=== Isolating tenant workloads to specific nodes - -Restricting tenant workloads to run on specific nodes can be used to +policy library on the Kyverno website.

+
+
+
+

9.3.4. Isolating tenant workloads to specific nodes

+
+

Restricting tenant workloads to run on specific nodes can be used to increase isolation in the soft multi-tenancy model. With this approach, tenant-specific workloads are only run on nodes provisioned for the respective tenants. To achieve this isolation, native Kubernetes properties (node affinity, and taints and tolerations) are used to target specific nodes for pod scheduling, and prevent pods, from other -tenants, from being scheduled on the tenant-specific nodes. - -==== Part 1 - Node affinity - -Kubernetes -https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity[node -affinity] is used to target nodes for scheduling, based on node -https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/[labels]. +tenants, from being scheduled on the tenant-specific nodes.

+
+
+
Part 1 - Node affinity
+
+

Kubernetes +node +affinity is used to target nodes for scheduling, based on node +labels. With node affinity rules, the pods are attracted to specific nodes that match the selector terms. In the below pod specification, the -`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity is +requiredDuringSchedulingIgnoredDuringExecution node affinity is applied to the respective pod. The result is that the pod will target nodes that are labeled with the following key/value: -`+node-restriction.kubernetes.io/tenant: tenants-x+`. - -[source,yaml] ----- -... +node-restriction.kubernetes.io/tenant: tenants-x.

+
+
+
+
...
 spec:
   affinity:
     nodeAffinity:
@@ -3504,116 +4008,127 @@ 

Reuse AWS SDK sessions with IRSA

operator: In values: - tenants-x -... ----- - -With this node affinity, the label is required during scheduling, but +...
+
+
+
+

With this node affinity, the label is required during scheduling, but not during execution; if the underlying nodes’ labels change, the pods will not be evicted due solely to that label change. However, future -scheduling could be impacted. - -!!! Warning The label prefix of `+node-restriction.kubernetes.io/+` has +scheduling could be impacted.

+
+
+

!!! Warning The label prefix of node-restriction.kubernetes.io/ has special meaning in Kubernetes. -https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[NodeRestriction] -which is enabled for EKS clusters prevents `+kubelet+` from +NodeRestriction +which is enabled for EKS clusters prevents kubelet from adding/removing/updating labels with this prefix. Attackers aren’t able -to use the `+kubelet+`’s credentials to update the node object or modify -the system setup to pass these labels into `+kubelet+` as `+kubelet+` +to use the kubelet’s credentials to update the node object or modify +the system setup to pass these labels into kubelet as kubelet isn’t allowed to modify these labels. If this prefix is used for all pod to node scheduling, it prevents scenarios where an attacker may want to attract a different set of workloads to a node by modifying the node -labels. - -!!! Info Instead of node affinity, we could have used the -https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector[node -selector]. However, node affinity is more expressive and allows for more +labels.

+
+
+

!!! Info Instead of node affinity, we could have used the +node +selector. However, node affinity is more expressive and allows for more conditions to be considered during pod scheduling. For additional information about the differences and more advanced scheduling choices, please see this CNCF blog post on -https://www.cncf.io/blog/2021/07/27/advanced-kubernetes-pod-to-node-scheduling/[Advanced -Kubernetes pod to node scheduling]. - -==== Part 2 - Taints and tolerations - -Attracting pods to nodes is just the first part of this three-part +Advanced +Kubernetes pod to node scheduling.

+
+
+
+
Part 2 - Taints and tolerations
+
+

Attracting pods to nodes is just the first part of this three-part approach. For this approach to work, we must repel pods from scheduling onto nodes for which the pods are not authorized. To repel unwanted or unauthorized pods, Kubernetes uses node -https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[taints]. +taints. Taints are used to place conditions on nodes that prevent pods from being scheduled. The below taint uses a key-value pair of -`+tenant: tenants-x+`. - -[source,yaml] ----- -... +tenant: tenants-x.

+
+
+
+
...
     taints:
       - key: tenant
         value: tenants-x
         effect: NoSchedule
-...
-----
-
-Given the above node `+taint+`, only pods that _tolerate_ the taint will
+...
+
+
+
+

Given the above node taint, only pods that tolerate the taint will be allowed to be scheduled on the node. To allow authorized pods to be scheduled onto the node, the respective pod specifications must include -a `+toleration+` to the taint, as seen below. - -[source,yaml] ----- -... +a toleration to the taint, as seen below.

+
+
+
+
...
   tolerations:
   - effect: NoSchedule
     key: tenant
     operator: Equal
     value: tenants-x
-...
-----
-
-Pods with the above `+toleration+` will not be stopped from scheduling
+...
+
+
+
+

Pods with the above toleration will not be stopped from scheduling on the node, at least not because of that specific taint. Taints are also used by Kubernetes to temporarily stop pod scheduling during certain conditions, like node resource pressure. With node affinity, and taints and tolerations, we can effectively attract the desired pods to -specific nodes and repel unwanted pods. - -!!! attention Certain Kubernetes pods are required to run on all nodes. +specific nodes and repel unwanted pods.

+
+
+

!!! attention Certain Kubernetes pods are required to run on all nodes. Examples of these pods are those started by the -https://github.com/containernetworking/cni[Container Network Interface -(CNI)] and -https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/[kube-proxy] -https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[daemonsets]. +Container Network Interface +(CNI) and +kube-proxy +daemonsets. To that end, the specifications for these pods contain very permissive tolerations, to tolerate different taints. Care should be taken to not change these tolerations. Changing these tolerations could result in incorrect cluster operation. Additionally, policy-management tools, such -as https://github.com/open-policy-agent/gatekeeper[OPA/Gatekeeper] and -https://kyverno.io/[Kyverno] can be used to write validating policies -that prevent unauthorized pods from using these permissive tolerations. - -==== Part 3 - Policy-based management for node selection - -There are several tools that can be used to help manage the node +as OPA/Gatekeeper and +Kyverno can be used to write validating policies +that prevent unauthorized pods from using these permissive tolerations.

+
+
+
+
Part 3 - Policy-based management for node selection
+
+

There are several tools that can be used to help manage the node affinity and tolerations of pod specifications, including enforcement of rules in CICD pipelines. However, enforcement of isolation should also be done at the Kubernetes cluster level. For this purpose, -policy-management tools can be used to _mutate_ inbound Kubernetes API +policy-management tools can be used to mutate inbound Kubernetes API server requests, based on request payloads, to apply the respective node -affinity rules and tolerations mentioned above. - -For example, pods destined for the _tenants-x_ namespace can be -_stamped_ with the correct node affinity and toleration to permit -scheduling on the _tenants-x_ nodes. Utilizing policy-management tools +affinity rules and tolerations mentioned above.

+
+
+

For example, pods destined for the tenants-x namespace can be +stamped with the correct node affinity and toleration to permit +scheduling on the tenants-x nodes. Utilizing policy-management tools configured using the Kubernetes -https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook[Mutating -Admission Webhook], policies can be used to mutate the inbound pod +Mutating +Admission Webhook, policies can be used to mutate the inbound pod specifications. The mutations add the needed elements to allow desired scheduling. An example OPA/Gatekeeper policy that adds a node affinity -is seen below. - -[source,yaml] ----- -apiVersion: mutations.gatekeeper.sh/v1alpha1 +is seen below.

+
+
+
+
apiVersion: mutations.gatekeeper.sh/v1alpha1
 kind: Assign
 metadata:
   name: mutator-add-nodeaffinity-pod
@@ -3635,22 +4150,24 @@ 

Reuse AWS SDK sessions with IRSA

- key: "tenant" operator: In values: - - "tenants-x" ----- - -The above policy is applied to a Kubernetes API server request, to apply -a pod to the _tenants-x_ namespace. The policy adds the -`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity rule, -so that pods are attracted to nodes with the `+tenant: tenants-x+` -label. - -A second policy, seen below, adds the toleration to the same pod + - "tenants-x"
+
+
+
+

The above policy is applied to a Kubernetes API server request, to apply +a pod to the tenants-x namespace. The policy adds the +requiredDuringSchedulingIgnoredDuringExecution node affinity rule, +so that pods are attracted to nodes with the tenant: tenants-x +label.

+
+
+

A second policy, seen below, adds the toleration to the same pod specification, using the same matching criteria of target namespace and -groups, kinds, and versions. - -[source,yaml] ----- -apiVersion: mutations.gatekeeper.sh/v1alpha1 +groups, kinds, and versions.

+
+
+
+
apiVersion: mutations.gatekeeper.sh/v1alpha1
 kind: Assign
 metadata:
   name: mutator-add-toleration-pod
@@ -3671,26 +4188,28 @@ 

Reuse AWS SDK sessions with IRSA

- key: "tenant" operator: "Equal" value: "tenants-x" - effect: "NoSchedule" ----- - -The above policies are specific to pods; this is due to the paths to the -mutated elements in the policies’ `+location+` elements. Additional + effect: "NoSchedule"
+
+
+
+

The above policies are specific to pods; this is due to the paths to the +mutated elements in the policies’ location elements. Additional policies could be written to handle resources that create pods, like Deployment and Job resources. The listed policies and other examples can been seen in the companion -https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa/gatekeeper/node-selector[GitHub -project] for this guide. - -The result of these two mutations is that pods are attracted to the +GitHub +project for this guide.

+
+
+

The result of these two mutations is that pods are attracted to the desired node, while at the same time, not repelled by the specific node taint. To verify this, we can see the snippets of output from two -`+kubectl+` calls to get the nodes labeled with `+tenant=tenants-x+`, -and get the pods in the `+tenants-x+` namespace. - -[source,bash] ----- -kubectl get nodes -l tenant=tenants-x +kubectl calls to get the nodes labeled with tenant=tenants-x, +and get the pods in the tenants-x namespace.

+
+
+
+
kubectl get nodes -l tenant=tenants-x
 NAME
 ip-10-0-11-255...
 ip-10-0-28-81...
@@ -3702,21 +4221,23 @@ 

Reuse AWS SDK sessions with IRSA

tenant-test-deploy-58b895ff87-9b6hg 1/1 Running 0 13s 10.0.18.145 ip-10-0-28-81... tenant-test-deploy-58b895ff87-nxvw5 1/1 Running 0 13s 10.0.30.117 ip-10-0-28-81... tenant-test-deploy-58b895ff87-vw796 1/1 Running 0 13s 10.0.3.113 ip-10-0-11-255... -tenant-test-pod 1/1 Running 0 13s 10.0.35.83 ip-10-0-43-107... ----- - -As we can see from the above outputs, all the pods are scheduled on the -nodes labeled with `+tenant=tenants-x+`. Simply put, the pods will only +tenant-test-pod 1/1 Running 0 13s 10.0.35.83 ip-10-0-43-107...
+
+
+
+

As we can see from the above outputs, all the pods are scheduled on the +nodes labeled with tenant=tenants-x. Simply put, the pods will only run on the desired nodes, and the other pods (without the required affinity and tolerations) will not. The tenant workloads are effectively -isolated. - -An example mutated pod specification is seen below. - -[source,yaml] ----- -apiVersion: v1 -kind: Pod +isolated.

+
+
+

An example mutated pod specification is seen below.

+
+
+
+
apiVersion: v1
+kind: Pod
 metadata:
   name: tenant-test-pod
   namespace: tenants-x
@@ -3736,10 +4257,11 @@ 

Reuse AWS SDK sessions with IRSA

key: tenant operator: Equal value: tenants-x -... ----- - -!!! attention Policy-management tools that are integrated to the +...
+
+
+
+

!!! attention Policy-management tools that are integrated to the Kubernetes API server request flow, using mutating and validating admission webhooks, are designed to respond to the API server’s request within a specified timeframe. This is usually 3 seconds or less. If the @@ -3747,102 +4269,144 @@

Reuse AWS SDK sessions with IRSA

mutation and/or validation of the inbound API sever request may or may not occur. This behavior is based on whether the admission webhook configurations are set to -https://open-policy-agent.github.io/gatekeeper/website/docs/#admission-webhook-fail-open-by-default[Fail -Open or Fail Close]. - -In the above examples, we used policies written for OPA/Gatekeeper. +Fail +Open or Fail Close.

+
+
+

In the above examples, we used policies written for OPA/Gatekeeper. However, there are other policy management tools that handle our node-selection use case as well. For example, this -https://kyverno.io/policies/other/add_node_affinity/add_node_affinity/[Kyverno -policy] could be used to handle the node affinity mutation. - -!!! tip If operating correctly, mutating policies will effect the +Kyverno +policy could be used to handle the node affinity mutation.

+
+
+

!!! tip If operating correctly, mutating policies will effect the desired changes to inbound API server request payloads. However, validating policies should also be included to verify that the desired changes occur, before changes are allowed to persist. This is especially important when using these policies for tenant-to-node isolation. It is -also a good idea to include _Audit_ policies to routinely check your -cluster for unwanted configurations. - -=== References - -* https://github.com/cruise-automation/k-rail[k-rail] Designed to help +also a good idea to include Audit policies to routinely check your +cluster for unwanted configurations.

+
+
+
+
+

9.3.5. References

+
+
    +
  • +

    k-rail Designed to help you secure a multi-tenant environment through the enforcement of certain -policies. -* https://d1.awsstatic.com/whitepapers/security-practices-for-multi-tenant-saas-apps-using-eks.pdf[Security -Practices for MultiTenant SaaS Applications using Amazon EKS] - -== Hard multi-tenancy - -Hard multi-tenancy can be implemented by provisioning separate clusters +policies.

    +
  • +
  • +

    Security +Practices for MultiTenant SaaS Applications using Amazon EKS

    +
  • +
+
+
+
+
+

9.4. Hard multi-tenancy

+
+

Hard multi-tenancy can be implemented by provisioning separate clusters for each tenant. While this provides very strong isolation between -tenants, it has several drawbacks. - -First, when you have many tenants, this approach can quickly become +tenants, it has several drawbacks.

+
+
+

First, when you have many tenants, this approach can quickly become expensive. Not only will you have to pay for the control plane costs for each cluster, you will not be able to share compute resources between clusters. This will eventually cause fragmentation where a subset of -your clusters are underutilized while others are overutilized. - -Second, you will likely need to buy or build special tooling to manage +your clusters are underutilized while others are overutilized.

+
+
+

Second, you will likely need to buy or build special tooling to manage all of these clusters. In time, managing hundreds or thousands of -clusters may simply become too unwieldy. - -Finally, creating a cluster per tenant will be slow relative to a +clusters may simply become too unwieldy.

+
+
+

Finally, creating a cluster per tenant will be slow relative to a creating a namespace. Nevertheless, a hard-tenancy approach may be necessary in highly-regulated industries or in SaaS environments where -strong isolation is required. - -== Future directions - -The Kubernetes community has recognized the current shortcomings of soft +strong isolation is required.

+
+
+
+

9.5. Future directions

+
+

The Kubernetes community has recognized the current shortcomings of soft multi-tenancy and the challenges with hard multi-tenancy. The -https://github.com/kubernetes-sigs/multi-tenancy[Multi-Tenancy Special -Interest Group (SIG)] is attempting to address these shortcomings +Multi-Tenancy Special +Interest Group (SIG) is attempting to address these shortcomings through several incubation projects, including Hierarchical Namespace -Controller (HNC) and Virtual Cluster. - -The HNC proposal (KEP) describes a way to create parent-child +Controller (HNC) and Virtual Cluster.

+
+
+

The HNC proposal (KEP) describes a way to create parent-child relationships between namespaces with [policy] object inheritance along -with an ability for tenant administrators to create sub-namespaces. - -The Virtual Cluster proposal describes a mechanism for creating separate +with an ability for tenant administrators to create sub-namespaces.

+
+
+

The Virtual Cluster proposal describes a mechanism for creating separate instances of the control plane services, including the API server, the controller manager, and scheduler, for each tenant within the cluster -(also known as "`Kubernetes on Kubernetes`"). - -The -https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/README.md[Multi-Tenancy -Benchmarks] proposal provides guidelines for sharing clusters using +(also known as “Kubernetes on Kubernetes”).

+
+
+

The +Multi-Tenancy +Benchmarks proposal provides guidelines for sharing clusters using namespaces for isolation and segmentation, and a command line tool -https://github.com/kubernetes-sigs/multi-tenancy/blob/master/benchmarks/kubectl-mtb/README.md[kubectl-mtb] -to validate conformance to the guidelines. - -== Multi-cluster management tools and resources - -* https://banzaicloud.com/[Banzai Cloud] -* https://d2iq.com/solutions/ksphere/kommander[Kommander] -* https://github.com/lensapp/lens[Lens] -* https://nirmata.com[Nirmata] -* https://rafay.co/[Rafay] -* https://rancher.com/products/rancher/[Rancher] -* https://www.weave.works/oss/flux/[Weave Flux] - -:leveloffset: 1 -:leveloffset: +1 - -= Auditing and logging - -Collecting and analyzing [audit] logs is useful for a variety of +kubectl-mtb +to validate conformance to the guidelines.

+
+
+
+

9.6. Multi-cluster management tools and resources

+
+ +
+
+
+
+
+

10. Auditing and logging

+
+
+

Collecting and analyzing [audit] logs is useful for a variety of different reasons. Logs can help with root cause analysis and attribution, i.e. ascribing a change to a particular user. When enough logs have been collected, they can be used to detect anomalous behaviors too. On EKS, the audit logs are sent to Amazon Cloudwatch Logs. The -audit policy for EKS is as follows: - -[source,yaml] ----- -apiVersion: audit.k8s.io/v1beta1 +audit policy for EKS is as follows:

+
+
+
+
apiVersion: audit.k8s.io/v1beta1
 kind: Policy
 rules:
   # Log aws-auth configmap changes
@@ -3988,228 +4552,299 @@ 

Reuse AWS SDK sessions with IRSA

# Default level for all other requests. - level: Metadata omitStages: - - "RequestReceived" ----- - -== Recommendations - -=== Enable audit logs - -The audit logs are part of the EKS managed Kubernetes control plane logs + - "RequestReceived"
+
+
+
+

10.1. Recommendations

+
+

10.1.1. Enable audit logs

+
+

The audit logs are part of the EKS managed Kubernetes control plane logs that are managed by EKS. Instructions for enabling/disabling the control plane logs, which includes the logs for the Kubernetes API server, the controller manager, and the scheduler, along with the audit log, can be found here, -https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export. - -!!! info When you enable control plane logging, you will incur -https://aws.amazon.com/cloudwatch/pricing/[costs] for storing the logs +https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export.

+
+
+

!!! info When you enable control plane logging, you will incur +costs for storing the logs in CloudWatch. This raises a broader issue about the ongoing cost of security. Ultimately you will have to weigh those costs against the cost of a security breach, e.g. financial loss, damage to your reputation, etc. You may find that you can adequately secure your environment by -implementing only some of the recommendations in this guide. - -!!! warning The maximum size for a CloudWatch Logs entry is -https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html[256KB] +implementing only some of the recommendations in this guide.

+
+
+

!!! warning The maximum size for a CloudWatch Logs entry is +256KB whereas the maximum Kubernetes API request size is 1.5MiB. Log entries greater than 256KB will either be truncated or only include the request -metadata. - -=== Utilize audit metadata - -Kubernetes audit logs include two annotations that indicate whether or -not a request was authorized `+authorization.k8s.io/decision+` and the -reason for the decision `+authorization.k8s.io/reason+`. Use these -attributes to ascertain why a particular API call was allowed. - -=== Create alarms for suspicious events - -Create an alarm to automatically alert you where there is an increase in +metadata.

+
+
+
+

10.1.2. Utilize audit metadata

+
+

Kubernetes audit logs include two annotations that indicate whether or +not a request was authorized authorization.k8s.io/decision and the +reason for the decision authorization.k8s.io/reason. Use these +attributes to ascertain why a particular API call was allowed.

+
+
+
+

10.1.3. Create alarms for suspicious events

+
+

Create an alarm to automatically alert you where there is an increase in 403 Forbidden and 401 Unauthorized responses, and then use attributes -like `+host+`, `+sourceIPs+`, and `+k8s_user.username+` to find out -where those requests are coming from. - -=== Analyze logs with Log Insights - -Use CloudWatch Log Insights to monitor changes to RBAC objects, +like host, sourceIPs, and k8s_user.username to find out +where those requests are coming from.

+
+
+
+

10.1.4. Analyze logs with Log Insights

+
+

Use CloudWatch Log Insights to monitor changes to RBAC objects, e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few -sample queries appear below: - -Lists updates to the `+aws-auth+` ConfigMap: - -[source,bash] ----- -fields @timestamp, @message +sample queries appear below:

+
+
+

Lists updates to the aws-auth ConfigMap:

+
+
+
+
fields @timestamp, @message
 | filter @logStream like "kube-apiserver-audit"
 | filter verb in ["update", "patch"]
 | filter objectRef.resource = "configmaps" and objectRef.name = "aws-auth" and objectRef.namespace = "kube-system"
-| sort @timestamp desc
-----
-
-Lists creation of new or changes to validation webhooks:
-
-[source,bash]
-----
-fields @timestamp, @message
+| sort @timestamp desc
+
+
+
+

Lists creation of new or changes to validation webhooks:

+
+
+
+
fields @timestamp, @message
 | filter @logStream like "kube-apiserver-audit"
 | filter verb in ["create", "update", "patch"] and responseStatus.code = 201
 | filter objectRef.resource = "validatingwebhookconfigurations"
-| sort @timestamp desc
-----
-
-Lists create, update, delete operations to Roles:
-
-[source,bash]
-----
-fields @timestamp, @message
+| sort @timestamp desc
+
+
+
+

Lists create, update, delete operations to Roles:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
-| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"]
-----
-
-Lists create, update, delete operations to RoleBindings:
-
-[source,bash]
-----
-fields @timestamp, @message
+| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"]
+
+
+
+

Lists create, update, delete operations to RoleBindings:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
-| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"]
-----
-
-Lists create, update, delete operations to ClusterRoles:
-
-[source,bash]
-----
-fields @timestamp, @message
+| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"]
+
+
+
+

Lists create, update, delete operations to ClusterRoles:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
-| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"]
-----
-
-Lists create, update, delete operations to ClusterRoleBindings:
-
-[source,bash]
-----
-fields @timestamp, @message
+| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"]
+
+
+
+

Lists create, update, delete operations to ClusterRoleBindings:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
-| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"]
-----
-
-Plots unauthorized read operations against Secrets:
-
-[source,bash]
-----
-fields @timestamp, @message
+| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"]
+
+
+
+

Plots unauthorized read operations against Secrets:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
 | filter objectRef.resource="secrets" and verb in ["get", "watch", "list"] and responseStatus.code="401"
-| stats count() by bin(1m)
-----
-
-List of failed anonymous requests:
-
-[source,bash]
-----
-fields @timestamp, @message, sourceIPs.0
+| stats count() by bin(1m)
+
+
+
+

List of failed anonymous requests:

+
+
+
+
fields @timestamp, @message, sourceIPs.0
 | sort @timestamp desc
 | limit 100
-| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"]
-----
-
-=== Audit your CloudTrail logs
-
-AWS APIs called by pods that are utilizing IAM Roles for Service
+| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"]
+
+
+
+
+

10.1.5. Audit your CloudTrail logs

+
+

AWS APIs called by pods that are utilizing IAM Roles for Service Accounts (IRSA) are automatically logged to CloudTrail along with the name of the service account. If the name of a service account that wasn’t explicitly authorized to call an API appears in the log, it may be an indication that the IAM role’s trust policy was misconfigured. Generally speaking, Cloudtrail is a great way to ascribe AWS API calls -to specific IAM principals. - -=== Use CloudTrail Insights to unearth suspicious activity - -CloudTrail insights automatically analyzes write management events from +to specific IAM principals.

+
+
+
+

10.1.6. Use CloudTrail Insights to unearth suspicious activity

+
+

CloudTrail insights automatically analyzes write management events from CloudTrail trails and alerts you of unusual activity. This can help you identify when there’s an increase in call volume on write APIs in your AWS account, including from pods that use IRSA to assume an IAM role. See -https://aws.amazon.com/blogs/aws/announcing-cloudtrail-insights-identify-and-respond-to-unusual-api-activity/[Announcing -CloudTrail Insights: Identify and Response to Unusual API Activity] for -further information. - -=== Additional resources - -As the volume of logs increases, parsing and filtering them with Log +Announcing +CloudTrail Insights: Identify and Response to Unusual API Activity for +further information.

+
+
+
+

10.1.7. Additional resources

+
+

As the volume of logs increases, parsing and filtering them with Log Insights or another log analysis tool may become ineffective. As an alternative, you might want to consider running -https://github.com/falcosecurity/falco[Sysdig Falco] and -https://github.com/sysdiglabs/ekscloudwatch[ekscloudwatch]. Falco +Sysdig Falco and +ekscloudwatch. Falco analyzes audit logs and flags anomalies or abuse over an extended period of time. The ekscloudwatch project forwards audit log events from CloudWatch to Falco for analysis. Falco provides a set of -https://github.com/falcosecurity/plugins/blob/master/plugins/k8saudit/rules/k8s_audit_rules.yaml[default -audit rules] along with the ability to add your own. - -Yet another option might be to store the audit logs in S3 and use the +default +audit rules along with the ability to add your own.

+
+
+

Yet another option might be to store the audit logs in S3 and use the SageMaker -https://docs.aws.amazon.com/sagemaker/latest/dg/randomcutforest.html[Random -Cut Forest] algorithm to anomalous behaviors that warrant further -investigation. - -== Tools and resources - -The following commercial and open source projects can be used to assess -your cluster’s alignment with established best practices: - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/5-detective-controls[Amazon -EKS Security Immersion Workshop - Detective Controls] -* https://github.com/Shopify/kubeaudit[kubeaudit] -* https://github.com/octarinesec/kube-scan[kube-scan] Assigns a risk +Random +Cut Forest algorithm to anomalous behaviors that warrant further +investigation.

+
+
+
+
+

10.2. Tools and resources

+
+

The following commercial and open source projects can be used to assess +your cluster’s alignment with established best practices:

+
+
+
    +
  • +

    Amazon +EKS Security Immersion Workshop - Detective Controls

    +
  • +
  • +

    kubeaudit

    +
  • +
  • +

    kube-scan Assigns a risk score to the workloads running in your cluster in accordance with the -Kubernetes Common Configuration Scoring System framework -* https://kubesec.io/[kubesec.io] -* https://github.com/FairwindsOps/polaris[polaris] -* https://github.com/aquasecurity/starboard[Starboard] -* https://support.snyk.io/hc/en-us/articles/360003916138-Kubernetes-integration-overview[Snyk] -* https://github.com/kubescape/kubescape[Kubescape] Kubescape is an open +Kubernetes Common Configuration Scoring System framework

    +
  • +
  • +

    kubesec.io

    +
  • +
  • +

    polaris

    +
  • +
  • +

    Starboard

    +
  • +
  • +

    Snyk

    +
  • +
  • +

    Kubescape Kubescape is an open source kubernetes security tool that scans clusters, YAML files, and Helm charts. It detects misconfigurations according to multiple frameworks (including -https://www.armosec.io/blog/kubernetes-hardening-guidance-summary-by-armo/?utm_source=github&utm_medium=repository[NSA-CISA] +NSA-CISA and -https://www.microsoft.com/security/blog/2021/03/23/secure-containerized-environments-with-updated-threat-matrix-for-kubernetes/[MITRE -ATT&CK®].) - -:leveloffset: 1 -:leveloffset: +1 - -= Network security - -Network security has several facets. The first involves the application +MITRE +ATT&CK®.)

    +
  • +
+
+
+
+
+
+

11. Network security

+
+
+

Network security has several facets. The first involves the application of rules which restrict the flow of network traffic between services. The second involves the encryption of traffic while it is in transit. The mechanisms to implement these security measures on EKS are varied -but often include the following items: - -== Traffic control - -* Network Policies -* Security Groups - -== Network encryption - -* Service Mesh -* Container Network Interfaces (CNIs) -* Ingress Controllers and Load Balancers -* Nitro Instances -* ACM Private CA with cert-manager - -== Network policy - -Within a Kubernetes cluster, all Pod to Pod communication is allowed by +but often include the following items:

+
+
+

11.1. Traffic control

+
+
    +
  • +

    Network Policies

    +
  • +
  • +

    Security Groups

    +
  • +
+
+
+
+

11.2. Network encryption

+
+
    +
  • +

    Service Mesh

    +
  • +
  • +

    Container Network Interfaces (CNIs)

    +
  • +
  • +

    Ingress Controllers and Load Balancers

    +
  • +
  • +

    Nitro Instances

    +
  • +
  • +

    ACM Private CA with cert-manager

    +
  • +
+
+
+
+

11.3. Network policy

+
+

Within a Kubernetes cluster, all Pod to Pod communication is allowed by default. While this flexibility may help promote experimentation, it is not considered secure. Kubernetes network policies give you a mechanism to restrict network traffic between Pods (often referred to as East/West @@ -4219,43 +4854,47 @@

Reuse AWS SDK sessions with IRSA

destination pods, but can also include IP addresses, port numbers, protocols, or a combination of these. Network Policies can be applied to both Inbound or Outbound connections to the pod, often called Ingress -and Egress rules. - -With native network policy support of Amazon VPC CNI Plugin, you can +and Egress rules.

+
+
+

With native network policy support of Amazon VPC CNI Plugin, you can implement network policies to secure network traffic in kubernetes clusters. This integrates with the upstream Kubernetes Network Policy API, ensuring compatibility and adherence to Kubernetes standards. You can define policies using different -https://kubernetes.io/docs/concepts/services-networking/network-policies/[identifiers] +identifiers supported by the upstream API. By default, all ingress and egress traffic is allowed to a pod. When a network policy with a policyType Ingress is specified, only allowed connections into the pod are those from the pod’s node and those allowed by the ingress rules. Same applies for egress rules. If multiple rules are defined, then union of all rules are taken into account when making the decision. Thus, order of -evaluation does not affect the policy result. - -!!! attention When you first provision an EKS cluster, VPC CNI Network +evaluation does not affect the policy result.

+
+
+

!!! attention When you first provision an EKS cluster, VPC CNI Network Policy functionality is not enabled by default. Ensure you deployed -supported VPC CNI Add-on version and set `+ENABLE_NETWORK_POLICY+` flag -to `+true+` on the vpc-cni add-on to enable this. Refer -https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html[Amazon -EKS User guide] for detailed instructions. - -== Recommendations - -=== Getting Started with Network Policies - Follow Principle of Least Privilege - -==== Create a default deny policy - -As with RBAC policies, it is recommended to follow least privileged +supported VPC CNI Add-on version and set ENABLE_NETWORK_POLICY flag +to true on the vpc-cni add-on to enable this. Refer +Amazon +EKS User guide for detailed instructions.

+
+
+
+

11.4. Recommendations

+
+

11.4.1. Getting Started with Network Policies - Follow Principle of Least Privilege

+
+
Create a default deny policy
+
+

As with RBAC policies, it is recommended to follow least privileged access principles with network policies. Start by creating a deny all policy that restricts all inbound and outbound traffic with in a -namespace. - -[source,yaml] ----- -apiVersion: networking.k8s.io/v1 +namespace.

+
+
+
+
apiVersion: networking.k8s.io/v1
 kind: NetworkPolicy
 metadata:
   name: default-deny
@@ -4264,24 +4903,30 @@ 

Reuse AWS SDK sessions with IRSA

podSelector: {} policyTypes: - Ingress - - Egress ----- - -.default-deny -image::./images/default-deny.jpg[default-deny] - -!!! tip The image above was created by the network policy viewer from -https://orca.tufin.io/netpol/[Tufin]. - -==== Create a rule to allow DNS queries - -Once you have the default deny all rule in place, you can begin layering + - Egress
+
+
+
+
+default-deny +
+
Figure 3. default-deny
+
+
+

!!! tip The image above was created by the network policy viewer from +Tufin.

+
+
+
+
Create a rule to allow DNS queries
+
+

Once you have the default deny all rule in place, you can begin layering on additional rules, such as a rule that allows pods to query CoreDNS -for name resolution. - -[source,yaml] ----- -apiVersion: networking.k8s.io/v1 +for name resolution.

+
+
+
+
apiVersion: networking.k8s.io/v1
 kind: NetworkPolicy
 metadata:
   name: allow-dns-access
@@ -4301,22 +4946,27 @@ 

Reuse AWS SDK sessions with IRSA

k8s-app: kube-dns ports: - protocol: UDP - port: 53 ----- - -.allow-dns-access -image::./images/allow-dns-access.jpg[allow-dns-access] - -==== Incrementally add rules to selectively allow the flow of traffic between namespaces/pods - -Understand the application requirements and create fine-grained ingress + port: 53
+
+
+
+
+allow-dns-access +
+
Figure 4. allow-dns-access
+
+
+
+
Incrementally add rules to selectively allow the flow of traffic between namespaces/pods
+
+

Understand the application requirements and create fine-grained ingress and egress rules as needed. Below example shows how to restrict ingress -traffic on port 80 to `+app-one+` from `+client-one+`. This helps -minimize the attack surface and reduces the risk of unauthorized access. - -[source,yaml] ----- -apiVersion: networking.k8s.io/v1 +traffic on port 80 to app-one from client-one. This helps +minimize the attack surface and reduces the risk of unauthorized access.

+
+
+
+
apiVersion: networking.k8s.io/v1
 kind: NetworkPolicy
 metadata:
   name: allow-ingress-app-one
@@ -4334,47 +4984,109 @@ 

Reuse AWS SDK sessions with IRSA

k8s-app: client-one ports: - protocol: TCP - port: 80 ----- - -.allow-ingress-app-one -image::./images/allow-ingress-app-one.png[allow-ingress-app-one] - -=== Monitoring network policy enforcement - -* *Use Network Policy editor* -** https://networkpolicy.io/[Network policy editor] helps with -visualizations, security score, autogenerates from network flow logs -** Build network policies in an interactive way -* *Audit Logs* -** Regularly review audit logs of your EKS cluster -** Audit logs provide wealth of information about what actions have been -performed on your cluster including changes to network policies -** Use this information to track changes to your network policies over -time and detect any unauthorized or unexpected changes -* *Automated testing* -** Implement automated testing by creating a test environment that + port: 80
+
+
+
+
+allow-ingress-app-one +
+
Figure 5. allow-ingress-app-one
+
+
+
+
+

11.4.2. Monitoring network policy enforcement

+
+
    +
  • +

    Use Network Policy editor

    +
    +
      +
    • +

      Network policy editor helps with +visualizations, security score, autogenerates from network flow logs

      +
    • +
    • +

      Build network policies in an interactive way

      +
    • +
    +
    +
  • +
  • +

    Audit Logs

    +
    +
      +
    • +

      Regularly review audit logs of your EKS cluster

      +
    • +
    • +

      Audit logs provide wealth of information about what actions have been +performed on your cluster including changes to network policies

      +
    • +
    • +

      Use this information to track changes to your network policies over +time and detect any unauthorized or unexpected changes

      +
    • +
    +
    +
  • +
  • +

    Automated testing

    +
    +
      +
    • +

      Implement automated testing by creating a test environment that mirrors your production environment and periodically deploy workloads -that attempt to violate your network policies. -* *Monitoring metrics* -** Configure your observability agents to scrape the prometheus metrics +that attempt to violate your network policies.

      +
    • +
    +
    +
  • +
  • +

    Monitoring metrics

    +
    +
      +
    • +

      Configure your observability agents to scrape the prometheus metrics from the VPC CNI node agents, that allows to monitor the agent health, -and sdk errors. -* *Audit Network Policies regularly* -** Periodically audit your Network Policies to make sure that they meet +and sdk errors.

      +
    • +
    +
    +
  • +
  • +

    Audit Network Policies regularly

    +
    +
      +
    • +

      Periodically audit your Network Policies to make sure that they meet your current application requirements. As your application evolves, an audit gives you the opportunity to remove redundant ingress, egress rules and make sure that your applications don’t have excessive -permissions. -* *Ensure Network Policies exists using Open Policy Agent (OPA)* -** Use OPA Policy like shown below to ensure Network Policy always +permissions.

      +
    • +
    +
    +
  • +
  • +

    Ensure Network Policies exists using Open Policy Agent (OPA)

    +
    +
      +
    • +

      Use OPA Policy like shown below to ensure Network Policy always exists before onboarding application pods. This policy denies onboarding -k8s pods with a label `+k8s-app: sample-app+` if corresponding network -policy does not exist. - -[source,javascript] ----- -package kubernetes.admission +k8s pods with a label k8s-app: sample-app if corresponding network +policy does not exist.

      +
    • +
    +
    +
  • +
+
+
+
+
package kubernetes.admission
 import data.kubernetes.networkpolicies
 
 deny[msg] {
@@ -4387,59 +5099,69 @@ 

Reuse AWS SDK sessions with IRSA

} contains_label(arr, val) { arr[_] == val -} ----- - -=== Troubleshooting - -==== Monitor the vpc-network-policy-controller, node-agent logs - -Enable the EKS Control plane controller manager logs to diagnose the +}
+
+
+
+
+

11.4.3. Troubleshooting

+
+
Monitor the vpc-network-policy-controller, node-agent logs
+
+

Enable the EKS Control plane controller manager logs to diagnose the network policy functionality. You can stream the control plane logs to a CloudWatch log group and use -https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html[CloudWatch -Log insights] to perform advanced queries. From the logs, you can view +CloudWatch +Log insights to perform advanced queries. From the logs, you can view what pod endpoint objects are resolved to a Network Policy, reconcilation status of the policies, and debug if the policy is working -as expected. - -In addition, Amazon VPC CNI allows you to enable the collection and +as expected.

+
+
+

In addition, Amazon VPC CNI allows you to enable the collection and export of policy enforcement logs to -https://aws.amazon.com/cloudwatch/[Amazon Cloudwatch] from the EKS +Amazon Cloudwatch from the EKS worker nodes. Once enabled, you can leverage -https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html[CloudWatch -Container Insights] to provide insights on your usage related to Network -Policies. - -Amazon VPC CNI also ships an SDK that provides an interface to interact +CloudWatch +Container Insights to provide insights on your usage related to Network +Policies.

+
+
+

Amazon VPC CNI also ships an SDK that provides an interface to interact with eBPF programs on the node. The SDK is installed when the -`+aws-node+` is deployed onto the nodes. You can find the SDK binary -installed under `+/opt/cni/bin+` directory on the node. At launch, the +aws-node is deployed onto the nodes. You can find the SDK binary +installed under /opt/cni/bin directory on the node. At launch, the SDK provides support for fundamental functionalities such as inspecting -eBPF programs and maps. - -[source,shell] ----- -sudo /opt/cni/bin/aws-eks-na-cli ebpf progs ----- - -==== Log network traffic metadata - -https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html[AWS VPC -Flow Logs] captures metadata about the traffic flowing through a VPC, +eBPF programs and maps.

+
+
+
+
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
+
+
+
+
+
Log network traffic metadata
+
+

AWS VPC +Flow Logs captures metadata about the traffic flowing through a VPC, such as source and destination IP address and port along with accepted/dropped packets. This information could be analyzed to look for suspicious or unusual activity between resources within the VPC, including Pods. However, since the IP addresses of pods frequently change as they are replaced, Flow Logs may not be sufficient on its own. Calico Enterprise extends the Flow Logs with pod labels and other -metadata, making it easier to decipher the traffic flows between pods. - -== Security groups - -EKS uses -https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS -VPC Security Groups] (SGs) to control the traffic between the Kubernetes +metadata, making it easier to decipher the traffic flows between pods.

+
+
+
+
+
+

11.5. Security groups

+
+

EKS uses +AWS +VPC Security Groups (SGs) to control the traffic between the Kubernetes control plane and the cluster’s worker nodes. Security groups are also used to control the traffic between worker nodes, and other VPC resources, and external IP addresses. When you provision an EKS cluster @@ -4447,67 +5169,76 @@

Reuse AWS SDK sessions with IRSA

group is automatically created for you. This security group allows unfettered communication between the EKS control plane and the nodes from managed node groups. For simplicity, it is recommended that you add -the cluster SG to all node groups, including unmanaged node groups. - -Prior to Kubernetes version 1.14 and EKS version eks.3, there were +the cluster SG to all node groups, including unmanaged node groups.

+
+
+

Prior to Kubernetes version 1.14 and EKS version eks.3, there were separate security groups configured for the EKS control plane and node groups. The minimum and suggested rules for the control plane and node group security groups can be found at -https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html. -The minimum rules for the _control plane security group_ allows port 443 +https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html. +The minimum rules for the control plane security group allows port 443 inbound from the worker node SG. This rule is what allows the kubelets to communicate with the Kubernetes API server. It also includes port 10250 for outbound traffic to the worker node SG; 10250 is the port that -the kubelets listen on. Similarly, the minimum _node group_ rules allow +the kubelets listen on. Similarly, the minimum node group rules allow port 10250 inbound from the control plane SG and 443 outbound to the control plane SG. Finally there is a rule that allows unfettered -communication between nodes within a node group. - -If you need to control communication between services that run within +communication between nodes within a node group.

+
+
+

If you need to control communication between services that run within the cluster and service the run outside the cluster such as an RDS database, consider -https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html[security -groups for pods]. With security groups for pods, you can assign an -*existing* security group to a collection of pods. - -!!! warning If you reference a security group that does not exist prior -to the creation of the pods, the pods will not get scheduled. - -You can control which pods are assigned to a security group by creating -a `+SecurityGroupPolicy+` object and specifying a `+PodSelector+` or a -`+ServiceAccountSelector+`. Setting the selectors to `+{}+` will assign -the SGs referenced in the `+SecurityGroupPolicy+` to all pods in a +security +groups for pods. With security groups for pods, you can assign an +existing security group to a collection of pods.

+
+
+

!!! warning If you reference a security group that does not exist prior +to the creation of the pods, the pods will not get scheduled.

+
+
+

You can control which pods are assigned to a security group by creating +a SecurityGroupPolicy object and specifying a PodSelector or a +ServiceAccountSelector. Setting the selectors to {} will assign +the SGs referenced in the SecurityGroupPolicy to all pods in a namespace or all Service Accounts in a namespace. Be sure you’ve familiarized yourself with all the -https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations[considerations] -before implementing security groups for pods. - -!!! important If you use SGs for pods you *must* create SGs that allow -port 53 outbound to the cluster security group. Similarly, you *must* +considerations +before implementing security groups for pods.

+
+
+

!!! important If you use SGs for pods you must create SGs that allow +port 53 outbound to the cluster security group. Similarly, you must update the cluster security group to accept port 53 inbound traffic from -the pod security group. - -!!! important The -https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups[limits -for security groups] still apply when using security groups for pods so -use them judiciously. - -!!! important You *must* create rules for inbound traffic from the +the pod security group.

+
+
+

!!! important The +limits +for security groups still apply when using security groups for pods so +use them judiciously.

+
+
+

!!! important You must create rules for inbound traffic from the cluster security group (kubelet) for all of the probes configured for -pod. - -!!! important Security groups for pods relies on a feature known as -https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html[ENI -trunking] which was created to increase the ENI density of an EC2 +pod.

+
+
+

!!! important Security groups for pods relies on a feature known as +ENI +trunking which was created to increase the ENI density of an EC2 instance. When a pod is assigned to an SG, a VPC controller associates a branch ENI from the node group with the pod. If there aren’t enough branch ENIs available in a node group at the time the pod is scheduled, the pod will stay in pending state. The number of branch ENIs an instance can support varies by instance type/family. See -https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types -for further details. - -While security groups for pods offers an AWS-native way to control +https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types +for further details.

+
+
+

While security groups for pods offers an AWS-native way to control network traffic within and outside of your cluster without the overhead of a policy daemon, other options are available. For example, the Cilium policy engine allows you to reference a DNS name in a network policy. @@ -4516,109 +5247,232 @@

Reuse AWS SDK sessions with IRSA

can use an egress gateway to restrict network egress to specific, fully qualified domains or IP addresses. For further information about this option, read the three part series on -https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/[egress -traffic control in Istio]. - -== When to use Network Policy vs Security Group for Pods? - -=== When to use Kubernetes network policy - -* *Controlling pod-to-pod traffic* -** Suitable for controlling network traffic between pods inside a -cluster (east-west traffic) -* *Control traffic at the IP address or port level (OSI layer 3 or 4)* - -=== When to use AWS Security groups for pods (SGP) - -* *Leverage existing AWS configurations* -** If you already have complex set of EC2 security groups that manage -access to AWS services and you are migrating applications from EC2 -instances to EKS, SGPs can be a very good choice allowing you to reuse -security group resources and apply them to your pods. -* *Control access to AWS services* -** Your applications running within an EKS cluster wants to communicate -with other AWS services (RDS database), use SGPs as an efficient -mechanism to control the traffic from the pods to AWS services. -* *Isolation of Pod & Node traffic* -** If you want to completely separate pod traffic from the rest of the -node traffic, use SGP in `+POD_SECURITY_GROUP_ENFORCING_MODE=strict+` -mode. - -=== Best practices using `+Security groups for pods+` and `+Network Policy+` - -* *Layered security* -** Use a combination of SGP and kubernetes network policy for a layered -security approach -** Use SGPs to limit network level access to AWS services that are not -part of a cluster, while kubernetes network policies can restrict -network traffic between pods inside the cluster -* *Principle of least privilege* -** Only allow necessary traffic between pods or namespaces -* *Segment your applications* -** Wherever possible, segment applications by the network policy to -reduce the blast radius if an application is compromised -* *Keep policies simple and clear* -** Kubernetes network policies can be quite granular and complex, its -best to keep them as simple as possible to reduce the risk of -misconfiguration and ease the management overhead -* *Reduce the attack surface* -** Minimize the attack surface by limiting the exposure of your -applications - -!!! attention Security Groups for pods provides two enforcing modes: -`+strict+` and `+standard+`. You must use `+standard+` mode when using -both Network Policy and Security Groups for pods features in an EKS -cluster. - -When it comes to network security, a layered approach is often the most -effective solution. Using kubernetes network policy and SGP in -combination can provide a robust defense-in-depth strategy for your -applications running in EKS. - -== Service Mesh Policy Enforcement or Kubernetes network policy - -A `+service mesh+` is a dedicated infrastructure layer that you can add -to your applications. It allows you to transparently add capabilities -like observability, traffic management, and security, without adding -them to your own code. - -Service mesh enforces policies at Layer 7 (application) of OSI model -whereas kubernetes network policies operate at Layer 3 (network) and -Layer 4 (transport). There are many offerings in this space like AWS -AppMesh, Istio, Linkerd, etc., - -=== When to use Service mesh for policy enforcement - -* Have existing investment in a service mesh -* Need more advanced capabilities like traffic management, observability -& security -** Traffic control, load balancing, circuit breaking, rate limiting, -timeouts etc. -** Detailed insights into how your services are performing (latency, -error rates, requests per second, request volumes etc.) -** You want to implement and leverage service mesh for security features -like mTLS - -=== Choose Kubernetes network policy for simpler use cases - -* Limit which pods can communicate with each other -* Network policies require fewer resources than a service mesh making -them a good fit for simpler use cases or for smaller clusters where the -overhead of running and managing a service mesh might not be justified - -!!! tip Network policies and Service mesh can also be used together. Use +egress +traffic control in Istio.

+
+
+
+

11.6. When to use Network Policy vs Security Group for Pods?

+
+

11.6.1. When to use Kubernetes network policy

+
+
    +
  • +

    Controlling pod-to-pod traffic

    +
    +
      +
    • +

      Suitable for controlling network traffic between pods inside a +cluster (east-west traffic)

      +
    • +
    +
    +
  • +
  • +

    Control traffic at the IP address or port level (OSI layer 3 or 4)

    +
  • +
+
+
+
+

11.6.2. When to use AWS Security groups for pods (SGP)

+
+
    +
  • +

    Leverage existing AWS configurations

    +
    +
      +
    • +

      If you already have complex set of EC2 security groups that manage +access to AWS services and you are migrating applications from EC2 +instances to EKS, SGPs can be a very good choice allowing you to reuse +security group resources and apply them to your pods.

      +
    • +
    +
    +
  • +
  • +

    Control access to AWS services

    +
    +
      +
    • +

      Your applications running within an EKS cluster wants to communicate +with other AWS services (RDS database), use SGPs as an efficient +mechanism to control the traffic from the pods to AWS services.

      +
    • +
    +
    +
  • +
  • +

    Isolation of Pod & Node traffic

    +
    +
      +
    • +

      If you want to completely separate pod traffic from the rest of the +node traffic, use SGP in POD_SECURITY_GROUP_ENFORCING_MODE=strict +mode.

      +
    • +
    +
    +
  • +
+
+
+
+

11.6.3. Best practices using Security groups for pods and Network Policy

+
+
    +
  • +

    Layered security

    +
    +
      +
    • +

      Use a combination of SGP and kubernetes network policy for a layered +security approach

      +
    • +
    • +

      Use SGPs to limit network level access to AWS services that are not +part of a cluster, while kubernetes network policies can restrict +network traffic between pods inside the cluster

      +
    • +
    +
    +
  • +
  • +

    Principle of least privilege

    +
    +
      +
    • +

      Only allow necessary traffic between pods or namespaces

      +
    • +
    +
    +
  • +
  • +

    Segment your applications

    +
    +
      +
    • +

      Wherever possible, segment applications by the network policy to +reduce the blast radius if an application is compromised

      +
    • +
    +
    +
  • +
  • +

    Keep policies simple and clear

    +
    +
      +
    • +

      Kubernetes network policies can be quite granular and complex, its +best to keep them as simple as possible to reduce the risk of +misconfiguration and ease the management overhead

      +
    • +
    +
    +
  • +
  • +

    Reduce the attack surface

    +
    +
      +
    • +

      Minimize the attack surface by limiting the exposure of your +applications

      +
    • +
    +
    +
  • +
+
+
+

!!! attention Security Groups for pods provides two enforcing modes: +strict and standard. You must use standard mode when using +both Network Policy and Security Groups for pods features in an EKS +cluster.

+
+
+

When it comes to network security, a layered approach is often the most +effective solution. Using kubernetes network policy and SGP in +combination can provide a robust defense-in-depth strategy for your +applications running in EKS.

+
+
+
+
+

11.7. Service Mesh Policy Enforcement or Kubernetes network policy

+
+

A service mesh is a dedicated infrastructure layer that you can add +to your applications. It allows you to transparently add capabilities +like observability, traffic management, and security, without adding +them to your own code.

+
+
+

Service mesh enforces policies at Layer 7 (application) of OSI model +whereas kubernetes network policies operate at Layer 3 (network) and +Layer 4 (transport). There are many offerings in this space like AWS +AppMesh, Istio, Linkerd, etc.,

+
+
+

11.7.1. When to use Service mesh for policy enforcement

+
+
    +
  • +

    Have existing investment in a service mesh

    +
  • +
  • +

    Need more advanced capabilities like traffic management, observability +& security

    +
    +
      +
    • +

      Traffic control, load balancing, circuit breaking, rate limiting, +timeouts etc.

      +
    • +
    • +

      Detailed insights into how your services are performing (latency, +error rates, requests per second, request volumes etc.)

      +
    • +
    • +

      You want to implement and leverage service mesh for security features +like mTLS

      +
    • +
    +
    +
  • +
+
+
+
+

11.7.2. Choose Kubernetes network policy for simpler use cases

+
+
    +
  • +

    Limit which pods can communicate with each other

    +
  • +
  • +

    Network policies require fewer resources than a service mesh making +them a good fit for simpler use cases or for smaller clusters where the +overhead of running and managing a service mesh might not be justified

    +
  • +
+
+
+

!!! tip Network policies and Service mesh can also be used together. Use network policies to provide a baseline level of security and isolation between your pods and then use a service mesh to add additional -capabilities like traffic management, observability and security. - -== ThirdParty Network Policy Engines - -Consider a Third Party Network Policy Engine when you have advanced +capabilities like traffic management, observability and security.

+
+
+
+
+

11.8. ThirdParty Network Policy Engines

+
+

Consider a Third Party Network Policy Engine when you have advanced policy requirements like Global Network Policies, support for DNS Hostname based rules, Layer 7 rules, ServiceAccount based rules, and explicit deny/log actions, etc., -https://docs.projectcalico.org/introduction/[Calico], is an open source -policy engine from https://tigera.io[Tigera] that works well with EKS. +Calico, is an open source +policy engine from Tigera that works well with EKS. In addition to implementing the full set of Kubernetes network policy features, Calico supports extended network polices with a richer set of features, including support for layer 7 rules, e.g. HTTP, when @@ -4628,22 +5482,24 @@

Reuse AWS SDK sessions with IRSA

service account. With the proper RBAC rules in place, you can prevent teams from overriding these rules, allowing IT security professionals to safely delegate administration of namespaces. Isovalent, the maintainers -of https://cilium.readthedocs.io/en/stable/intro/[Cilium], have also +of Cilium, have also extended the network policies to include partial support for layer 7 rules, e.g. HTTP. Cilium also has support for DNS hostnames which can be useful for restricting traffic between Kubernetes Services/Pods and resources that run within or outside of your VPC. By contrast, Calico Enterprise includes a feature that allows you to map a Kubernetes -network policy to an AWS security group, as well as DNS hostnames. - -You can find a list of common Kubernetes network policies at -https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar +network policy to an AWS security group, as well as DNS hostnames.

+
+
+

You can find a list of common Kubernetes network policies at +https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar set of rules for Calico are available at -https://docs.projectcalico.org/security/calico-network-policy. - -=== Migration to Amazon VPC CNI Network Policy Engine - -To maintain consistency and avoid unexpected pod communication behavior, +https://docs.projectcalico.org/security/calico-network-policy.

+
+
+

11.8.1. Migration to Amazon VPC CNI Network Policy Engine

+
+

To maintain consistency and avoid unexpected pod communication behavior, it is recommended to deploy only one Network Policy Engine in your cluster. If you want to migrate from 3P to VPC CNI Network Policy Engine, we recommend converting your existing 3P NetworkPolicy CRDs to @@ -4651,110 +5507,155 @@

Reuse AWS SDK sessions with IRSA

policy support. And, test the migrated policies in a separate test cluster before applying them in you production environment. This allows you to identify and address any potential issues or inconsistencies in -pod communication behavior. - -==== Migration Tool - -To assist in your migration process, we have developed a tool called -https://github.com/awslabs/k8s-network-policy-migrator[K8s Network -Policy Migrator] that converts your existing Calico/Cilium network +pod communication behavior.

+
+
+
Migration Tool
+
+

To assist in your migration process, we have developed a tool called +K8s Network +Policy Migrator that converts your existing Calico/Cilium network policy CRDs to Kubernetes native network policies. After conversion you can directly test the converted network policies on your new clusters running VPC CNI network policy controller. The tool is designed to help -you streamline the migration process and ensure a smooth transition. - -!!! Important Migration tool will only convert 3P policies that are +you streamline the migration process and ensure a smooth transition.

+
+
+

!!! Important Migration tool will only convert 3P policies that are compatible with native kubernetes network policy api. If you are using advanced network policy features offered by 3P plugins, Migration tool -will skip and report them. - -Please note that migration tool is currently not supported by AWS VPC +will skip and report them.

+
+
+

Please note that migration tool is currently not supported by AWS VPC CNI Network policy engineering team, it is made available to customers on a best-effort basis. We encourage you to utilize this tool to facilitate your migration process. In the event that you encounter any issues or bugs with the tool, we kindly ask you create a -https://github.com/awslabs/k8s-network-policy-migrator/issues[GitHub -issue]. Your feedback is invaluable to us and will assist in the -continuous improvement of our services. - -=== Additional Resources - -* https://youtu.be/lEY2WnRHYpg[Kubernetes & Tigera: Network -Policies&#44; Security&#44; and Audit] -* https://www.tigera.io/tigera-products/calico-enterprise/[Calico -Enterprise] -* https://cilium.readthedocs.io/en/stable/intro/[Cilium] -* https://cilium.io/blog/2021/02/10/network-policy-editor[NetworkPolicy -Editor] an interactive policy editor from Cilium -* https://www.inspektor-gadget.io/docs/latest/gadgets/advise/network-policy/[Inspektor -Gadget advise network-policy gadget] Suggests network policies based on -an analysis of network traffic - -== Encryption in transit - -Applications that need to conform to PCI, HIPAA, or other regulations +GitHub +issue. Your feedback is invaluable to us and will assist in the +continuous improvement of our services.

+
+
+
+
+

11.8.2. Additional Resources

+
+ +
+
+
+
+

11.9. Encryption in transit

+
+

Applications that need to conform to PCI, HIPAA, or other regulations may need to encrypt data while it is in transit. Nowadays TLS is the de facto choice for encrypting traffic on the wire. TLS, like it’s predecessor SSL, provides secure communications over a network using cryptographic protocols. TLS uses symmetric encryption where the keys to encrypt the data are generated based on a shared secret that is negotiated at the beginning of the session. The following are a few ways -that you can encrypt data in a Kubernetes environment. - -=== Nitro Instances - -Traffic exchanged between the following Nitro instance types, e.g. C5n, +that you can encrypt data in a Kubernetes environment.

+
+
+

11.9.1. Nitro Instances

+
+

Traffic exchanged between the following Nitro instance types, e.g. C5n, G4, I3en, M5dn, M5n, P3dn, R5dn, and R5n, is automatically encrypted by default. When there’s an intermediate hop, like a transit gateway or a load balancer, the traffic is not encrypted. See -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/data-protection.html#encryption-transit[Encryption -in transit] for further details on encryption in transit as well as the +Encryption +in transit for further details on encryption in transit as well as the complete list of instances types that support network encryption by -default. - -=== Container Network Interfaces (CNIs) - -https://www.weave.works/oss/net/[WeaveNet] can be configured to +default.

+
+
+
+

11.9.2. Container Network Interfaces (CNIs)

+
+

WeaveNet can be configured to automatically encrypt all traffic using NaCl encryption for sleeve -traffic, and IPsec ESP for fast datapath traffic. - -=== Service Mesh - -Encryption in transit can also be implemented with a service mesh like +traffic, and IPsec ESP for fast datapath traffic.

+
+
+
+

11.9.3. Service Mesh

+
+

Encryption in transit can also be implemented with a service mesh like App Mesh, Linkerd v2, and Istio. AppMesh supports -https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html[mTLS] +mTLS with X.509 certificates or Envoy’s Secret Discovery Service(SDS). -Linkerd and Istio both have support for mTLS. - -The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples] +Linkerd and Istio both have support for mTLS.

+
+
+

The aws-app-mesh-examples GitHub repository provides walkthroughs for configuring mTLS using X.509 -certificates and SPIRE as SDS provider with your Envoy container: - -* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-file-based[Configuring -mTLS using X.509 certificates] -* https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-sds-based[Configuring -TLS using SPIRE (SDS)] - -App Mesh also supports -https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html[TLS -encryption] with a private certificate issued by -https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS -Certificate Manager] (ACM) or a certificate stored on the local file -system of the virtual node. - -The https://github.com/aws/aws-app-mesh-examples[aws-app-mesh-examples] +certificates and SPIRE as SDS provider with your Envoy container:

+
+ +
+

App Mesh also supports +TLS +encryption with a private certificate issued by +AWS +Certificate Manager (ACM) or a certificate stored on the local file +system of the virtual node.

+
+
+

The aws-app-mesh-examples GitHub repository provides walkthroughs for configuring TLS using certificates issued by ACM and certificates that are packaged with your -Envoy container: - -* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/howto-tls-file-provided[Configuring -TLS with File Provided TLS Certificates] -* https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm[Configuring -TLS with AWS Certificate Manager] - -=== Ingress Controllers and Load Balancers - -Ingress controllers are a way for you to intelligently route HTTP/S +Envoy container:

+
+ +
+
+

11.9.4. Ingress Controllers and Load Balancers

+
+

Ingress controllers are a way for you to intelligently route HTTP/S traffic that emanates from outside the cluster to services running inside the cluster. Oftentimes, these Ingresses are fronted by a layer 4 load balancer, like the Classic Load Balancer or the Network Load @@ -4767,28 +5668,29 @@

Reuse AWS SDK sessions with IRSA

additional burden on your Pod as it will have to spend cycles establishing the initial handshake. Overall SSL/TLS processing is very CPU intensive. Consequently, if you have the flexibility, try performing -the SSL offload at the Ingress or the load balancer. - -==== Use encryption with AWS Elastic load balancers - -The -https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html[AWS -Application Load Balancer] (ALB) and -https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html[Network -Load Balancer] (NLB) both have support for transport encryption (SSL and -TLS). The `+alb.ingress.kubernetes.io/certificate-arn+` annotation for +the SSL offload at the Ingress or the load balancer.

+
+
+
Use encryption with AWS Elastic load balancers
+
+

The +AWS +Application Load Balancer (ALB) and +Network +Load Balancer (NLB) both have support for transport encryption (SSL and +TLS). The alb.ingress.kubernetes.io/certificate-arn annotation for the ALB lets you to specify which certificates to add to the ALB. If you omit the annotation the controller will attempt to add certificates to listeners that require it by matching the available -https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS -Certificate Manager (ACM)] certificates using the host field. Starting +AWS +Certificate Manager (ACM) certificates using the host field. Starting with EKS v1.15 you can use the -`+service.beta.kubernetes.io/aws-load-balancer-ssl-cert+` annotation -with the NLB as shown in the example below. - -[source,yaml] ----- -apiVersion: v1 +service.beta.kubernetes.io/aws-load-balancer-ssl-cert annotation +with the NLB as shown in the example below.

+
+
+
+
apiVersion: v1
 kind: Service
 metadata:
   name: demo-app
@@ -4833,24 +5735,36 @@ 

Reuse AWS SDK sessions with IRSA

- containerPort: 443 protocol: TCP - containerPort: 80 - protocol: TCP ----- - -Following are additional examples for SSL/TLS termination. - -* https://aws.amazon.com/blogs/containers/securing-eks-ingress-contour-lets-encrypt-gitops/[Securing -EKS Ingress With Contour And Let’s Encrypt The GitOps Way] -* https://aws.amazon.com/premiumsupport/knowledge-center/terminate-https-traffic-eks-acm/[How -do I terminate HTTPS traffic on Amazon EKS workloads with ACM?] - -!!! attention Some Ingresses, like the AWS LB controller, implement the -SSL/TLS using Annotations instead of as part of the Ingress Spec. - -=== ACM Private CA with cert-manager - -You can enable TLS and mTLS to secure your EKS application workloads at + protocol: TCP
+
+
+
+

Following are additional examples for SSL/TLS termination.

+
+ +
+

!!! attention Some Ingresses, like the AWS LB controller, implement the +SSL/TLS using Annotations instead of as part of the Ingress Spec.

+
+
+
+
+

11.9.5. ACM Private CA with cert-manager

+
+

You can enable TLS and mTLS to secure your EKS application workloads at the ingress, on the pod, and between pods using ACM Private Certificate -Authority (CA) and https://cert-manager.io/[cert-manager], a popular +Authority (CA) and cert-manager, a popular Kubernetes add-on to distribute, renew, and revoke certificates. ACM Private CA is a highly-available, secure, managed CA without the upfront and maintenance costs of managing your own CA. If you are using the @@ -4860,42 +5774,46 @@

Reuse AWS SDK sessions with IRSA

security modules (very secure), compared with the default CA storing keys encoded in memory (less secure). A centralized CA also gives you more control and improved auditability for private certificates both -inside and outside of a Kubernetes environment. - -==== Short-Lived CA Mode for Mutual TLS Between Workloads - -When using ACM Private CA for mTLS in EKS, it is recommended that you -use short lived certificates with _short-lived CA mode_. Although it is +inside and outside of a Kubernetes environment.

+
+
+
Short-Lived CA Mode for Mutual TLS Between Workloads
+
+

When using ACM Private CA for mTLS in EKS, it is recommended that you +use short lived certificates with short-lived CA mode. Although it is possible to issue out short-lived certificates in the general-purpose CA mode, using short-lived CA mode works out more cost-effective (~75% cheaper than general mode) for use cases where new certificates need to be issued frequently. In addition to this, you should try to align the validity period of the private certificates with the lifetime of the pods in your EKS cluster. -https://aws.amazon.com/certificate-manager/private-certificate-authority/[Learn -more about ACM Private CA and its benefits here]. - -==== ACM Setup Instructions - -Start by creating a Private CA by following procedures provided in the -https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html[ACM -Private CA tech docs]. Once you have a Private CA, install cert-manager -using https://cert-manager.io/docs/installation/[regular installation -instructions]. After installing cert-manager, install the Private CA +Learn +more about ACM Private CA and its benefits here.

+
+
+
+
ACM Setup Instructions
+
+

Start by creating a Private CA by following procedures provided in the +ACM +Private CA tech docs. Once you have a Private CA, install cert-manager +using regular installation +instructions. After installing cert-manager, install the Private CA Kubernetes cert-manager plugin by following the -https://github.com/cert-manager/aws-privateca-issuer#setup[setup -instructions in GitHub]. The plugin lets cert-manager request private -certificates from ACM Private CA. - -Now that you have a Private CA and an EKS cluster with cert-manager and +setup +instructions in GitHub. The plugin lets cert-manager request private +certificates from ACM Private CA.

+
+
+

Now that you have a Private CA and an EKS cluster with cert-manager and the plugin installed, it’s time to set permissions and create the issuer. Update IAM permissions of the EKS node role to allow access to -ACM Private CA. Replace the `+<CA_ARN>+` with the value from your -Private CA: - -[source,json] ----- -{ +ACM Private CA. Replace the <CA_ARN> with the value from your +Private CA:

+
+
+
+
{
     "Version": "2012-10-17",
     "Statement": [
         {
@@ -4909,60 +5827,68 @@ 

Reuse AWS SDK sessions with IRSA

"Resource": "<CA_ARN>" } ] -} ----- - -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[Service -Roles for IAM Accounts&#44; or IRSA] can also be used. Please see the -Additional Resources section below for complete examples. - -Create an Issuer in Amazon EKS by creating a Custom Resource Definition +}
+
+
+
+

Service +Roles for IAM Accounts, or IRSA can also be used. Please see the +Additional Resources section below for complete examples.

+
+
+

Create an Issuer in Amazon EKS by creating a Custom Resource Definition file named cluster-issuer.yaml with the following text in it, replacing -`+<CA_ARN>+` and `+<Region>+` information with your Private CA. - -[source,yaml] ----- -apiVersion: awspca.cert-manager.io/v1beta1 +<CA_ARN> and <Region> information with your Private CA.

+
+
+
+
apiVersion: awspca.cert-manager.io/v1beta1
 kind: AWSPCAClusterIssuer
 metadata:
           name: demo-test-root-ca
 spec:
-          arn: <CA_ARN>
-          region: <Region>
-----
-
-Deploy the Issuer you created.
-
-[source,bash]
-----
-kubectl apply -f cluster-issuer.yaml
-----
-
-Your EKS cluster is configured to request certificates from Private CA.
-You can now use cert-manager’s `+Certificate+` resource to issue
-certificates by changing the `+issuerRef+` field’s values to the Private
+          arn: <CA_ARN>
+          region: <Region>
+
+
+
+

Deploy the Issuer you created.

+
+
+
+
kubectl apply -f cluster-issuer.yaml
+
+
+
+

Your EKS cluster is configured to request certificates from Private CA. +You can now use cert-manager’s Certificate resource to issue +certificates by changing the issuerRef field’s values to the Private CA Issuer you created above. For more details on how to specify and request Certificate resources, please check cert-manager’s -https://cert-manager.io/docs/usage/certificate/[Certificate Resources -guide]. -https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/[See -examples here]. - -=== ACM Private CA with Istio and cert-manager - -If you are running Istio in your EKS cluster, you can disable the Istio -control plane (specifically `+istiod+`) from functioning as the root +Certificate Resources +guide. +See +examples here.

+
+
+
+
+

11.9.6. ACM Private CA with Istio and cert-manager

+
+

If you are running Istio in your EKS cluster, you can disable the Istio +control plane (specifically istiod) from functioning as the root Certificate Authority (CA), and configure ACM Private CA as the root CA for mTLS between workloads. If you’re going with this approach, consider -using the _short-lived CA mode_ in ACM Private CA. Refer to the -link:#short-lived-ca-mode-for-mutual-tls-between-workloads[previous -section] and this -https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[blog -post] for more details. - -==== How Certificate Signing Works in Istio (Default) - -Workloads in Kubernetes are identified using service accounts. If you +using the short-lived CA mode in ACM Private CA. Refer to the +previous +section and this +blog +post for more details.

+
+
+
How Certificate Signing Works in Istio (Default)
+
+

Workloads in Kubernetes are identified using service accounts. If you don’t specify a service account, Kubernetes will automatically assign one to your workload. Also, service accounts automatically mount an associated token. This token is used by the service account for @@ -4971,75 +5897,95 @@

Reuse AWS SDK sessions with IRSA

its own identity management system and CA. When a workload starts up with its envoy sidecar proxy, it needs an identity assigned from Istio in order for it to be deemed as trustworthy and allowed to communicate -with other services in the mesh. - -To get this identity from Istio, the `+istio-agent+` sends a request +with other services in the mesh.

+
+
+

To get this identity from Istio, the istio-agent sends a request known as a certificate signing request (or CSR) to the Istio control plane. This CSR contains the service account token so that the workload’s identity can be verified before being processed. This -verification process is handled by `+istiod+`, which acts as both the +verification process is handled by istiod, which acts as both the Registration Authority (or RA) and the CA. The RA serves as a gatekeeper that makes sure only verified CSR makes it through to the CA. Once the CSR is verified, it will be forwarded to the CA which will then issue a -certificate containing a https://spiffe.io/[SPIFFE] identity with the +certificate containing a SPIFFE identity with the service account. This certificate is called a SPIFFE verifiable identity document (or SVID). The SVID is assigned to the requesting service for identification purposes and to encrypt the traffic in transit between -the communicating services. - -.Default flow for Istio Certificate Signing Requests -image::./images/default-istio-csr-flow.png[Default flow for Istio -Certificate Signing Requests] - -==== How Certificate Signing Works in Istio with ACM Private CA - -You can use a cert-manager add-on called the Istio Certificate Signing +the communicating services.

+
+
+
Default flow for Istio Certificate Signing Requests
+

image::./images/default-istio-csr-flow.png[Default flow for Istio +Certificate Signing Requests]

+
+
+
+
How Certificate Signing Works in Istio with ACM Private CA
+
+

You can use a cert-manager add-on called the Istio Certificate Signing Request agent -(https://cert-manager.io/docs/projects/istio-csr/[istio-csr]) to +(istio-csr) to integrate Istio with ACM Private CA. This agent allows Istio workloads and control plane components to be secured with cert manager issuers, in -this case ACM Private CA. The _istio-csr_ agent exposes the same service -that _istiod_ serves in the default config of validating incoming CSRs. +this case ACM Private CA. The istio-csr agent exposes the same service +that istiod serves in the default config of validating incoming CSRs. Except, after verification, it will convert the requests into resources -that cert manager supports (i.e. integrations with external CA issuers). - -Whenever there’s a CSR from a workload, it will be forwarded to -_istio-csr_, which will request certificates from ACM Private CA. This -communication between _istio-csr_ and ACM Private CA is enabled by the -https://github.com/cert-manager/aws-privateca-issuer[AWS Private CA -issuer plugin]. Cert manager uses this plugin to request TLS +that cert manager supports (i.e. integrations with external CA issuers).

+
+
+

Whenever there’s a CSR from a workload, it will be forwarded to +istio-csr, which will request certificates from ACM Private CA. This +communication between istio-csr and ACM Private CA is enabled by the +AWS Private CA +issuer plugin. Cert manager uses this plugin to request TLS certificates from ACM Private CA. The issuer plugin will communicate with the ACM Private CA service to request a signed certificate for the workload. Once the certificate has been signed, it will be returned to -_istio-csr_, which will read the signed request, and return it to the -workload that initiated the CSR. - -.Flow for Istio Certificate Signing Requests with istio-csr -image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio -Certificate Signing Requests with istio-csr] - -==== Istio with Private CA Setup Instructions - -[arabic] -. Start by following the same -link:#acm-private-ca-with-cert-manager[setup instructions in this -section] to complete the following: -. Create a Private CA -. Install cert-manager -. Install the issuer plugin -. Set permissions and create an issuer. The issuer represents the CA and -is used to sign `+istiod+` and mesh workload certificates. It will -communicate with ACM Private CA. -. Create an `+istio-system+` namespace. This is where the -`+istiod certificate+` and other Istio resources will be deployed. -. Install Istio CSR configured with AWS Private CA Issuer Plugin. You +istio-csr, which will read the signed request, and return it to the +workload that initiated the CSR.

+
+
+
Flow for Istio Certificate Signing Requests with istio-csr
+

image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio +Certificate Signing Requests with istio-csr]

+
+
+
+
Istio with Private CA Setup Instructions
+
+
    +
  1. +

    Start by following the same +setup instructions in this +section to complete the following:

    +
  2. +
  3. +

    Create a Private CA

    +
  4. +
  5. +

    Install cert-manager

    +
  6. +
  7. +

    Install the issuer plugin

    +
  8. +
  9. +

    Set permissions and create an issuer. The issuer represents the CA and +is used to sign istiod and mesh workload certificates. It will +communicate with ACM Private CA.

    +
  10. +
  11. +

    Create an istio-system namespace. This is where the +istiod certificate and other Istio resources will be deployed.

    +
  12. +
  13. +

    Install Istio CSR configured with AWS Private CA Issuer Plugin. You can preserve the certificate signing requests for workloads to verify that they get approved and signed -(`+preserveCertificateRequests=true+`). -+ -[source,bash] ----- -helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \ +(preserveCertificateRequests=true).

    +
    +
    +
    helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \
     --set "app.certmanager.issuer.group=awspca.cert-manager.io" \
     --set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \
     --set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \
    @@ -5051,16 +5997,18 @@ 

    Reuse AWS SDK sessions with IRSA

    --set "volumeMounts[0].name=root-ca" \ --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ --set "volumes[0].name=root-ca" \ ---set "volumes[0].secret.secretName=istio-root-ca" ----- -. Install Istio with custom configurations to replace `+istiod+` with -`+cert-manager istio-csr+` as the certificate provider for the mesh. +--set "volumes[0].secret.secretName=istio-root-ca"
    +
    +
    +
  14. +
  15. +

    Install Istio with custom configurations to replace istiod with +cert-manager istio-csr as the certificate provider for the mesh. This process can be carried out using the -https://tetrate.io/blog/what-is-istio-operator/[Istio Operator]. -+ -[source,yaml] ----- -apiVersion: install.istio.io/v1alpha1 +Istio Operator.

    +
    +
    +
    apiVersion: install.istio.io/v1alpha1
     kind: IstioOperator
     metadata:
       name: istio
    @@ -5114,84 +6062,120 @@ 

    Reuse AWS SDK sessions with IRSA

    name: ca-root-cert configMap: defaultMode: 420 - name: istio-ca-root-cert ----- -. Deploy the above custom resource you created. -+ -[source,bash] ----- -istioctl operator init -kubectl apply -f istio-custom-config.yaml ----- -. Now you can deploy a workload to the mesh in your EKS cluster and -https://istio.io/latest/docs/reference/config/security/peer_authentication/[enforce -mTLS]. - -.Istio certificate signing requests -image::./images/istio-csr-requests.png[Istio certificate signing -requests] - -== Tools and resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/6-network-security[Amazon -EKS Security Immersion Workshop - Network security] -* https://aws.amazon.com/blogs/security/tls-enabled-kubernetes-clusters-with-acm-private-ca-and-amazon-eks-2/[How + name: istio-ca-root-cert
    +
    +
    +
  16. +
  17. +

    Deploy the above custom resource you created.

    +
    +
    +
    istioctl operator init
    +kubectl apply -f istio-custom-config.yaml
    +
    +
    +
  18. +
  19. +

    Now you can deploy a workload to the mesh in your EKS cluster and +enforce +mTLS.

    +
  20. +
+
+
+
Istio certificate signing requests
+

image::./images/istio-csr-requests.png[Istio certificate signing +requests]

+
+
+
+
+
+

11.10. Tools and resources

+
+ +
+
+
+
+
+

12. Data encryption and secrets management

+
+
+

12.1. Encryption at rest

+
+

There are three different AWS-native storage options you can use with Kubernetes: -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html[EBS], -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEFS.html[EFS], -and https://docs.aws.amazon.com/fsx/latest/LustreGuide/what-is.html[FSx -for Lustre]. All three offer encryption at rest using a service managed +EBS, +EFS, +and FSx +for Lustre. All three offer encryption at rest using a service managed key or a customer master key (CMK). For EBS you can use the in-tree storage driver or the -https://github.com/kubernetes-sigs/aws-ebs-csi-driver[EBS CSI driver]. +EBS CSI driver. Both include parameters for encrypting volumes and supplying a CMK. For EFS, you can use the -https://github.com/kubernetes-sigs/aws-efs-csi-driver[EFS CSI driver], +EFS CSI driver, however, unlike EBS, the EFS CSI driver does not support dynamic provisioning. If you want to use EFS with EKS, you will need to provision and configure at-rest encryption for the file system prior to creating a PV. For further information about EFS file encryption, please refer to -https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html[Encrypting -Data at Rest]. Besides offering at-rest encryption, EFS and FSx for +Encrypting +Data at Rest. Besides offering at-rest encryption, EFS and FSx for Lustre include an option for encrypting data in transit. FSx for Lustre does this by default. For EFS, you can add transport encryption by -adding the `+tls+` parameter to `+mountOptions+` in your PV as in this -example: - -[source,yaml] ----- -apiVersion: v1 +adding the tls parameter to mountOptions in your PV as in this +example:

+
+
+
+
apiVersion: v1
 kind: PersistentVolume
 metadata:
   name: efs-pv
@@ -5207,17 +6191,18 @@ 

Reuse AWS SDK sessions with IRSA

- tls csi: driver: efs.csi.aws.com - volumeHandle: <file_system_id> ----- - -The https://github.com/kubernetes-sigs/aws-fsx-csi-driver[FSx CSI -driver] supports dynamic provisioning of Lustre file systems. It + volumeHandle: <file_system_id>
+
+
+
+

The FSx CSI +driver supports dynamic provisioning of Lustre file systems. It encrypts data with a service managed key by default, although there is -an option to provide your own CMK as in this example: - -[source,yaml] ----- -kind: StorageClass +an option to provide your own CMK as in this example:

+
+
+
+
kind: StorageClass
 apiVersion: storage.k8s.io/v1
 metadata:
   name: fsx-sc
@@ -5226,194 +6211,239 @@ 

Reuse AWS SDK sessions with IRSA

subnetId: subnet-056da83524edbe641 securityGroupIds: sg-086f61ea73388fb6b deploymentType: PERSISTENT_1 - kmsKeyId: <kms_arn> ----- - -!!! attention As of May 28, 2020 all data written to the ephemeral + kmsKeyId: <kms_arn>
+
+
+
+

!!! attention As of May 28, 2020 all data written to the ephemeral volume in EKS Fargate pods is encrypted by default using an industry-standard AES-256 cryptographic algorithm. No modifications to your application are necessary as encryption and decryption are handled -seamlessly by the service. - -=== Encrypt data at rest - -Encrypting data at rest is considered a best practice. If you’re unsure -whether encryption is necessary, encrypt your data. - -=== Rotate your CMKs periodically - -Configure KMS to automatically rotate your CMKs. This will rotate your +seamlessly by the service.

+
+
+

12.1.1. Encrypt data at rest

+
+

Encrypting data at rest is considered a best practice. If you’re unsure +whether encryption is necessary, encrypt your data.

+
+
+
+

12.1.2. Rotate your CMKs periodically

+
+

Configure KMS to automatically rotate your CMKs. This will rotate your keys once a year while saving old keys indefinitely so that your data can still be decrypted. For additional information see -https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html[Rotating -customer master keys] - -=== Use EFS access points to simplify access to shared datasets - -If you have shared datasets with different POSIX file permissions or +Rotating +customer master keys

+
+
+
+

12.1.3. Use EFS access points to simplify access to shared datasets

+
+

If you have shared datasets with different POSIX file permissions or want to restrict access to part of the shared file system by creating different mount points, consider using EFS access points. To learn more about working with access points, see -https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today, +https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today, if you want to use an access point (AP) you’ll need to reference the AP -in the PV’s `+volumeHandle+` parameter. - -!!! attention As of March 23, 2021 the EFS CSI driver supports dynamic +in the PV’s volumeHandle parameter.

+
+
+

!!! attention As of March 23, 2021 the EFS CSI driver supports dynamic provisioning of EFS Access Points. Access points are application-specific entry points into an EFS file system that make it easier to share a file system between multiple pods. Each EFS file system can have up to 120 PVs. See -https://aws.amazon.com/blogs/containers/introducing-efs-csi-dynamic-provisioning/[Introducing -Amazon EFS CSI dynamic provisioning] for additional information. - -== Secrets management - -Kubernetes secrets are used to store sensitive information, such as user +Introducing +Amazon EFS CSI dynamic provisioning for additional information.

+
+
+
+
+

12.2. Secrets management

+
+

Kubernetes secrets are used to store sensitive information, such as user certificates, passwords, or API keys. They are persisted in etcd as base64 encoded strings. On EKS, the EBS volumes for etcd nodes are encrypted with -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html[EBS -encryption]. A pod can retrieve a Kubernetes secrets objects by -referencing the secret in the `+podSpec+`. These secrets can either be +EBS +encryption. A pod can retrieve a Kubernetes secrets objects by +referencing the secret in the podSpec. These secrets can either be mapped to an environment variable or mounted as volume. For additional information on creating secrets, see -https://kubernetes.io/docs/concepts/configuration/secret/. - -!!! caution Secrets in a particular namespace can be referenced by all -pods in the secret’s namespace. - -!!! caution The node authorizer allows the Kubelet to read all of the -secrets mounted to the node. - -=== Use AWS KMS for envelope encryption of Kubernetes secrets - -This allows you to encrypt your secrets with a unique data encryption +https://kubernetes.io/docs/concepts/configuration/secret/.

+
+
+

!!! caution Secrets in a particular namespace can be referenced by all +pods in the secret’s namespace.

+
+
+

!!! caution The node authorizer allows the Kubelet to read all of the +secrets mounted to the node.

+
+
+

12.2.1. Use AWS KMS for envelope encryption of Kubernetes secrets

+
+

This allows you to encrypt your secrets with a unique data encryption key (DEK). The DEK is then encrypted using a key encryption key (KEK) from AWS KMS which can be automatically rotated on a recurring schedule. With the KMS plugin for Kubernetes, all Kubernetes secrets are stored in etcd in ciphertext instead of plain text and can only be decrypted by the Kubernetes API server. For additional details, see -https://aws.amazon.com/blogs/containers/using-eks-encryption-provider-support-for-defense-in-depth/[using -EKS encryption provider support for defense in depth] - -=== Audit the use of Kubernetes Secrets - -On EKS, turn on audit logging and create a CloudWatch metrics filter and +using +EKS encryption provider support for defense in depth

+
+
+
+

12.2.2. Audit the use of Kubernetes Secrets

+
+

On EKS, turn on audit logging and create a CloudWatch metrics filter and alarm to alert you when a secret is used (optional). The following is an example of a metrics filter for the Kubernetes audit log, -`+{($.verb="get") && ($.objectRef.resource="secret")}+`. You can also -use the following queries with CloudWatch Log Insights: - -[source,bash] ----- -fields @timestamp, @message +{($.verb="get") && ($.objectRef.resource="secret")}. You can also +use the following queries with CloudWatch Log Insights:

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
 | stats count(*) by objectRef.name as secret
-| filter verb="get" and objectRef.resource="secrets"
-----
-
-The above query will display the number of times a secret has been
-accessed within a specific timeframe.
-
-[source,bash]
-----
-fields @timestamp, @message
+| filter verb="get" and objectRef.resource="secrets"
+
+
+
+

The above query will display the number of times a secret has been +accessed within a specific timeframe.

+
+
+
+
fields @timestamp, @message
 | sort @timestamp desc
 | limit 100
 | filter verb="get" and objectRef.resource="secrets"
-| display objectRef.namespace, objectRef.name, user.username, responseStatus.code
-----
-
-This query will display the secret, along with the namespace and
+| display objectRef.namespace, objectRef.name, user.username, responseStatus.code
+
+
+
+

This query will display the secret, along with the namespace and username of the user who attempted to access the secret and the response -code. - -=== Rotate your secrets periodically - -Kubernetes doesn’t automatically rotate secrets. If you have to rotate +code.

+
+
+
+

12.2.3. Rotate your secrets periodically

+
+

Kubernetes doesn’t automatically rotate secrets. If you have to rotate secrets, consider using an external secret store, e.g. Vault or AWS -Secrets Manager. - -=== Use separate namespaces as a way to isolate secrets from different applications - -If you have secrets that cannot be shared between applications in a -namespace, create a separate namespace for those applications. - -=== Use volume mounts instead of environment variables - -The values of environment variables can unintentionally appear in logs. +Secrets Manager.

+
+
+
+

12.2.4. Use separate namespaces as a way to isolate secrets from different applications

+
+

If you have secrets that cannot be shared between applications in a +namespace, create a separate namespace for those applications.

+
+
+
+

12.2.5. Use volume mounts instead of environment variables

+
+

The values of environment variables can unintentionally appear in logs. Secrets mounted as volumes are instantiated as tmpfs volumes (a RAM backed file system) that are automatically removed from the node when -the pod is deleted. - -=== Use an external secrets provider - -There are several viable alternatives to using Kubernetes secrets, -including https://aws.amazon.com/secrets-manager/[AWS Secrets Manager] +the pod is deleted.

+
+
+
+

12.2.6. Use an external secrets provider

+
+

There are several viable alternatives to using Kubernetes secrets, +including AWS Secrets Manager and Hashicorp’s -https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar/[Vault]. +Vault. These services offer features such as fine grained access controls, strong encryption, and automatic rotation of secrets that are not available with Kubernetes Secrets. Bitnami’s -https://github.com/bitnami-labs/sealed-secrets[Sealed Secrets] is -another approach that uses asymmetric encryption to create "`sealed -secrets`". A public key is used to encrypt the secret while the private +Sealed Secrets is +another approach that uses asymmetric encryption to create “sealed +secrets”. A public key is used to encrypt the secret while the private key used to decrypt the secret is kept within the cluster, allowing you to safely store sealed secrets in source control systems like Git. See -https://aws.amazon.com/blogs/opensource/managing-secrets-deployment-in-kubernetes-using-sealed-secrets/[Managing -secrets deployment in Kubernetes using Sealed Secrets] for further -information. - -As the use of external secrets stores has grown, so has need for +Managing +secrets deployment in Kubernetes using Sealed Secrets for further +information.

+
+
+

As the use of external secrets stores has grown, so has need for integrating them with Kubernetes. The -https://github.com/kubernetes-sigs/secrets-store-csi-driver[Secret Store -CSI Driver] is a community project that uses the CSI driver model to +Secret Store +CSI Driver is a community project that uses the CSI driver model to fetch secrets from external secret stores. Currently, the Driver has support for -https://github.com/aws/secrets-store-csi-driver-provider-aws[AWS Secrets -Manager], Azure, Vault, and GCP. The AWS provider supports both AWS -Secrets Manager *and* AWS Parameter Store. It can also be configured to +AWS Secrets +Manager, Azure, Vault, and GCP. The AWS provider supports both AWS +Secrets Manager and AWS Parameter Store. It can also be configured to rotate secrets when they expire and can synchronize AWS Secrets Manager secrets to Kubernetes Secrets. Synchronization of secrets can be useful when you need to reference a secret as an environment variable instead -of reading them from a volume. - -!!! note When the the secret store CSI driver has to fetch a secret, it +of reading them from a volume.

+
+
+

!!! note When the the secret store CSI driver has to fetch a secret, it assumes the IRSA role assigned to the pod that references a secret. The code for this operation can be found -https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go[here]. - -For additional information about the AWS Secrets & Configuration -Provider (ASCP) refer to the following resources: - -* https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-configuration-provider-with-kubernetes-secrets-store-csi-driver/[How +here.

+
+
+

For additional information about the AWS Secrets & Configuration +Provider (ASCP) refer to the following resources:

+
+ +
+

external-secrets is yet another way to use an external secret store with Kubernetes. Like the CSI Driver, external-secrets works against a variety of different backends, including AWS Secrets Manager. The difference is, rather than retrieving secrets from the external secret store, external-secrets copies secrets from these backends to Kubernetes as Secrets. This lets you manage secrets using your preferred secret store and interact with -secrets in a Kubernetes-native way. - -== Tools and resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/13-data-encryption-and-secret-management[Amazon +secrets in a Kubernetes-native way.

+
+
+
+ +
+
+
+

13. Runtime security

+
+
+

Runtime security provides active protection for your containers while they’re running. The idea is to detect and/or prevent malicious activity from occurring inside the container. This can be achieved with a number of mechanisms in the Linux kernel or kernel extensions that are @@ -5421,111 +6451,126 @@

Reuse AWS SDK sessions with IRSA

(seccomp), AppArmor, or SELinux. There are also options like Amazon GuardDuty and third party tools that can assist with establishing baselines and detecting anomalous activity with less manual -configuration of Linux kernel mechanisms. - -!!! attention Kubernetes does not currently provide any native +configuration of Linux kernel mechanisms.

+
+
+

!!! attention Kubernetes does not currently provide any native mechanisms for loading seccomp, AppArmor, or SELinux profiles onto Nodes. They either have to be loaded manually or installed onto Nodes when they are bootstrapped. This has to be done prior to referencing them in your Pods because the scheduler is unaware of which nodes have profiles. See below how tools like Security Profiles Operator can help -automate provisioning of profiles onto nodes. - -== Security contexts and built-in Kubernetes controls - -Many Linux runtime security mechanisms are tightly integrated with +automate provisioning of profiles onto nodes.

+
+
+

13.1. Security contexts and built-in Kubernetes controls

+
+

Many Linux runtime security mechanisms are tightly integrated with Kubernetes and can be configured through Kubernetes -https://kubernetes.io/docs/tasks/configure-pod-container/security-context/[security -contexts]. One such option is the `+privileged+` flag, which is -`+false+` by default and if enabled is essentially equivalent to root on +security +contexts. One such option is the privileged flag, which is +false by default and if enabled is essentially equivalent to root on the host. It is nearly always inappropriate to enable privileged mode in production workloads, but there are many more controls that can provide -more granular privileges to containers as appropriate. - -=== Linux capabilities - -Linux capabilities allow you to grant certain capabilities to a Pod or +more granular privileges to containers as appropriate.

+
+
+

13.1.1. Linux capabilities

+
+

Linux capabilities allow you to grant certain capabilities to a Pod or container without providing all the abilities of the root user. Examples -include `+CAP_NET_ADMIN+`, which allows configuring network interfaces -or firewalls, or `+CAP_SYS_TIME+`, which allows manipulation of the -system clock. - -=== Seccomp - -With secure computing (seccomp) you can prevent a containerized +include CAP_NET_ADMIN, which allows configuring network interfaces +or firewalls, or CAP_SYS_TIME, which allows manipulation of the +system clock.

+
+
+
+

13.1.2. Seccomp

+
+

With secure computing (seccomp) you can prevent a containerized application from making certain syscalls to the underlying host operating system’s kernel. While the Linux operating system has a few hundred system calls, the lion’s share of them are not necessary for running containers. By restricting what syscalls can be made by a container, you can effectively decrease your application’s attack -surface. - -Seccomp works by intercepting syscalls and only allowing those that have +surface.

+
+
+

Seccomp works by intercepting syscalls and only allowing those that have been allowlisted to pass through. Docker has a -https://github.com/moby/moby/blob/master/profiles/seccomp/default.json[default] +default seccomp profile which is suitable for a majority of general purpose workloads, and other container runtimes like containerd provide comparable defaults. You can configure your container or Pod to use the container runtime’s default seccomp profile by adding the following to -the `+securityContext+` section of the Pod spec: - -[source,yaml] ----- -securityContext: +the securityContext section of the Pod spec:

+
+
+
+
securityContext:
   seccompProfile:
-    type: RuntimeDefault
-----
-
-As of 1.22 (in alpha, stable as of 1.27), the above `+RuntimeDefault+`
+    type: RuntimeDefault
+
+
+
+

As of 1.22 (in alpha, stable as of 1.27), the above RuntimeDefault can be used for all Pods on a Node using a -https://kubernetes.io/docs/tutorials/security/seccomp/#enable-the-use-of-runtimedefault-as-the-default-seccomp-profile-for-all-workloads[single -kubelet flag], `+--seccomp-default+`. Then the profile specified in -`+securityContext+` is only needed for other profiles. - -It’s also possible to create your own profiles for things that require +single +kubelet flag, --seccomp-default. Then the profile specified in +securityContext is only needed for other profiles.

+
+
+

It’s also possible to create your own profiles for things that require additional privileges. This can be very tedious to do manually, but there are tools like -https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget] -(also recommended in the link:../network/[network security section] for +Inspektor Gadget +(also recommended in the network security section for generating network policies) and -https://github.com/inspektor-gadget/inspektor-gadget[Security Profiles -Operator] that support using tools like eBPF or logs to record baseline +Security Profiles +Operator that support using tools like eBPF or logs to record baseline privilege requirements as seccomp profiles. Security Profiles Operator further allows automating the deployment of recorded profiles to nodes -for use by Pods and containers. - -=== AppArmor and SELinux - -AppArmor and SELinux are known as -https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access -control or MAC systems]. They are similar in concept to seccomp but with +for use by Pods and containers.

+
+
+
+

13.1.3. AppArmor and SELinux

+
+

AppArmor and SELinux are known as +mandatory access +control or MAC systems. They are similar in concept to seccomp but with different APIs and abilities, allowing access control for e.g. specific filesystem paths or network ports. Support for these tools depends on the Linux distribution, with Debian/Ubuntu supporting AppArmor and RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see -the link:../hosts/#run-selinux[infrastructure security section] for -further discussion of SELinux. - -Both AppArmor and SELinux are integrated with Kubernetes, but as of +the infrastructure security section for +further discussion of SELinux.

+
+
+

Both AppArmor and SELinux are integrated with Kubernetes, but as of Kubernetes 1.28 AppArmor profiles must be specified via -https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod[annotations] +annotations while SELinux labels can be set through the -https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#selinuxoptions-v1-core[SELinuxOptions] -field on the security context directly. - -As with seccomp profiles, the Security Profiles Operator mentioned above +SELinuxOptions +field on the security context directly.

+
+
+

As with seccomp profiles, the Security Profiles Operator mentioned above can assist with deploying profiles onto nodes in the cluster. (In the future, the project also aims to generate profiles for AppArmor and -SELinux as it does for seccomp.) - -== Recommendations - -=== Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments - -If you do not currently have a solution for continuously monitoring EKS +SELinux as it does for seccomp.)

+
+
+
+
+

13.2. Recommendations

+
+

13.2.1. Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments

+
+

If you do not currently have a solution for continuously monitoring EKS runtimes and analyzing EKS audit logs, and scanning for malware and other suspicious activity, Amazon strongly recommends the use of -https://aws.amazon.com/guardduty/[Amazon GuardDuty] for customers who +Amazon GuardDuty for customers who want a simple, fast, secure, scalable, and cost-effective one-click way to protect their AWS environments. Amazon GuardDuty is a security monitoring service that analyzes and processes foundational data @@ -5543,29 +6588,34 @@

Reuse AWS SDK sessions with IRSA

security findings that you can view in the GuardDuty console or through Amazon EventBridge. GuardDuty also provides support for you to export your findings to an Amazon Simple Storage Service (S3) bucket, and -integrate with other services such as AWS Security Hub and Detective. - -Watch this AWS Online Tech Talk -https://www.youtube.com/watch?v=oNHGRRroJuE["`Enhanced threat detection -for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks`"] to see +integrate with other services such as AWS Security Hub and Detective.

+
+
+

Watch this AWS Online Tech Talk +“Enhanced threat detection +for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks” to see how to enable these additional EKS security features step-by-step in -minutes. - -=== Optionally: Use a 3rd party solution for runtime monitoring - -Creating and managing seccomp and Apparmor profiles can be difficult if +minutes.

+
+
+
+

13.2.2. Optionally: Use a 3rd party solution for runtime monitoring

+
+

Creating and managing seccomp and Apparmor profiles can be difficult if you’re not familiar with Linux security. If you don’t have the time to become proficient, consider using a 3rd party commercial solution. A lot of them have moved beyond static profiles like Apparmor and seccomp and have begun using machine learning to block or alert on suspicious activity. A handful of these solutions can be found below in the -link:#tools-and-resources[tools] section. Additional options can be -found on the https://aws.amazon.com/marketplace/features/containers[AWS -Marketplace for Containers]. - -=== Consider add/dropping Linux capabilities before writing seccomp policies - -Capabilities involve various checks in kernel functions reachable by +tools section. Additional options can be +found on the AWS +Marketplace for Containers.

+
+
+
+

13.2.3. Consider add/dropping Linux capabilities before writing seccomp policies

+
+

Capabilities involve various checks in kernel functions reachable by syscalls. If the check fails, the syscall typically returns an error. The check can be done either right at the beginning of a specific syscall, or deeper in the kernel in areas that might be reachable @@ -5573,110 +6623,155 @@

Reuse AWS SDK sessions with IRSA

privileged file). Seccomp, on the other hand, is a syscall filter which is applied to all syscalls before they are run. A process can set up a filter which allows them to revoke their right to run certain syscalls, -or specific arguments for certain syscalls. - -Before using seccomp, consider whether adding/removing Linux +or specific arguments for certain syscalls.

+
+
+

Before using seccomp, consider whether adding/removing Linux capabilities gives you the control you need. See -https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container[Setting -capabilities for- containers] for further information. - -=== See whether you can accomplish your aims by using Pod Security Policies (PSPs) - -Pod Security Policies offer a lot of different ways to improve your +Setting +capabilities for- containers for further information.

+
+
+
+

13.2.4. See whether you can accomplish your aims by using Pod Security Policies (PSPs)

+
+

Pod Security Policies offer a lot of different ways to improve your security posture without introducing undue complexity. Explore the options available in PSPs before venturing into building seccomp and -Apparmor profiles. - -!!! warning As of Kubernetes 1.25, PSPs have been removed and replaced +Apparmor profiles.

+
+
+

!!! warning As of Kubernetes 1.25, PSPs have been removed and replaced with the -https://kubernetes.io/docs/concepts/security/pod-security-admission/[Pod -Security Admission] controller. Third-party alternatives which exist +Pod +Security Admission controller. Third-party alternatives which exist include OPA/Gatekeeper and Kyverno. A collection of Gatekeeper constraints and constraint templates for implementing policies commonly found in PSPs can be pulled from the -https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/pod-security-policy[Gatekeeper -library] repository on GitHub. And many replacements for PSPs can be -found in the https://main.kyverno.io/policies/[Kyverno policy library] +Gatekeeper +library repository on GitHub. And many replacements for PSPs can be +found in the Kyverno policy library including the full collection of -https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod -Security Standards]. - -== Tools and Resources - -* https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6[7 -things you should know before you start] -* https://github.com/kubernetes/kubernetes/tree/master/test/images/apparmor-loader[AppArmor -Loader] -* https://kubernetes.io/docs/tutorials/clusters/apparmor/#setting-up-nodes-with-profiles[Setting -up nodes with profiles] -* https://github.com/kubernetes-sigs/security-profiles-operator[Security -Profiles Operator] is a Kubernetes enhancement which aims to make it +Pod +Security Standards.

+
+
+
+
+

13.3. Tools and Resources

+
+
    +
  • +

    7 +things you should know before you start

    +
  • +
  • +

    AppArmor +Loader

    +
  • +
  • +

    Setting +up nodes with profiles

    +
  • +
  • +

    Security +Profiles Operator is a Kubernetes enhancement which aims to make it easier for users to use SELinux, seccomp and AppArmor in Kubernetes clusters. It provides capabilities for both generating profiles from running workloads and loading profiles onto Kubernetes nodes for use in -Pods. -* https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget] +Pods.

    +
  • +
  • +

    Inspektor Gadget allows inspecting, tracing, and profiling many aspects of runtime behavior on Kubernetes, including assisting in the generation of seccomp -profiles. -* https://www.aquasec.com/products/aqua-cloud-native-security-platform/[Aqua] -* https://www.qualys.com/apps/container-security/[Qualys] -* https://www.stackrox.com/use-cases/threat-detection/[Stackrox] -* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] -* https://docs.paloaltonetworks.com/cn-series[Prisma] -* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +profiles.

    +
  • +
  • +

    Aqua

    +
  • +
  • +

    Qualys

    +
  • +
  • +

    Stackrox

    +
  • +
  • +

    Sysdig Secure

    +
  • +
  • +

    Prisma

    +
  • +
  • +

    NeuVector by SUSE open source, zero-trust container security platform, provides process profile rules -and file access rules. - -:leveloffset: 1 -:leveloffset: +1 - +and file access rules.

    +
  • +
+
+
+

[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] = Protecting the infrastructure (hosts) - -Inasmuch as it’s important to secure your container images, it’s equally +:info_doctype: section +:info_title: Protecting the infrastructure (hosts) +:info_abstract: Protecting the infrastructure (hosts) +:info_titleabbrev: Protecting the infrastructure (hosts) +:imagesdir: images/

+
+
+

Inasmuch as it’s important to secure your container images, it’s equally important to safeguard the infrastructure that runs them. This section explores different ways to mitigate risks from attacks launched directly against the host. These guidelines should be used in conjunction with -those outlined in the link:runtime.md[Runtime Security] section. - -== Recommendations - -=== Use an OS optimized for running containers - -Consider using Flatcar Linux, Project Atomic, RancherOS, and -https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a +those outlined in the Runtime Security section.

+
+
+
+

13.4. Recommendations

+
+

13.4.1. Use an OS optimized for running containers

+
+

Consider using Flatcar Linux, Project Atomic, RancherOS, and +Bottlerocket, a special purpose OS from AWS designed for running Linux containers. It includes a reduced attack surface, a disk image that is verified on -boot, and enforced permission boundaries using SELinux. - -Alternately, use the -https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html[EKS -optimized AMI] for your Kubernetes worker nodes. The EKS optimized AMI +boot, and enforced permission boundaries using SELinux.

+
+
+

Alternately, use the +EKS +optimized AMI for your Kubernetes worker nodes. The EKS optimized AMI is released regularly and contains a minimal set of OS packages and -binaries necessary to run your containerized workloads. - -Please refer https://github.com/aws-samples/amazon-eks-ami-rhel[Amazon -EKS AMI RHEL Build Specification] for a sample configuration script +binaries necessary to run your containerized workloads.

+
+
+

Please refer Amazon +EKS AMI RHEL Build Specification for a sample configuration script which can be used for building a custom Amazon EKS AMI running on Red Hat Enterprise Linux using Hashicorp Packer. This script can be further -leveraged to build STIG compliant EKS custom AMIs. - -=== Keep your worker node OS updated - -Regardless of whether you use a container-optimized host OS like +leveraged to build STIG compliant EKS custom AMIs.

+
+
+
+

13.4.2. Keep your worker node OS updated

+
+

Regardless of whether you use a container-optimized host OS like Bottlerocket or a larger, but still minimalist, Amazon Machine Image like the EKS optimized AMIs, it is best practice to keep these host OS -images up to date with the latest security patches. - -For the EKS optimized AMIs, regularly check the -https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md[CHANGELOG] -and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes -channel] and automate the rollout of updated worker node images into -your cluster. - -=== Treat your infrastructure as immutable and automate the replacement of your worker nodes - -Rather than performing in-place upgrades, replace your workers when a +images up to date with the latest security patches.

+
+
+

For the EKS optimized AMIs, regularly check the +CHANGELOG +and/or release notes +channel and automate the rollout of updated worker node images into +your cluster.

+
+
+
+

13.4.3. Treat your infrastructure as immutable and automate the replacement of your worker nodes

+
+

Rather than performing in-place upgrades, replace your workers when a new patch or update becomes available. This can be approached a couple of ways. You can either add instances to an existing autoscaling group using the latest AMI as you sequentially cordon and drain nodes until @@ -5684,75 +6779,84 @@

Reuse AWS SDK sessions with IRSA

Alternatively, you can add instances to a new node group while you sequentially cordon and drain nodes from the old node group until all of the nodes have been replaced. EKS -https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed -node groups] uses the first approach and will display a message in the +managed +node groups uses the first approach and will display a message in the console to upgrade your workers when a new AMI becomes available. -`+eksctl+` also has a mechanism for creating node groups with the latest +eksctl also has a mechanism for creating node groups with the latest AMI and for gracefully cordoning and draining pods from nodes groups before the instances are terminated. If you decide to use a different method for replacing your worker nodes, it is strongly recommended that you automate the process to minimize human oversight as you will likely need to replace workers regularly as new updates/patches are released -and when the control plane is upgraded. - -With EKS Fargate, AWS will automatically update the underlying +and when the control plane is upgraded.

+
+
+

With EKS Fargate, AWS will automatically update the underlying infrastructure as updates become available. Oftentimes this can be done seamlessly, but there may be times when an update will cause your pod to be rescheduled. Hence, we recommend that you create deployments with -multiple replicas when running your application as a Fargate pod. - -=== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] - -kube-bench is an open source project from Aqua that evaluates your +multiple replicas when running your application as a Fargate pod.

+
+
+
+

13.4.4. Periodically run kube-bench to verify compliance with CIS benchmarks for Kubernetes

+
+

kube-bench is an open source project from Aqua that evaluates your cluster against the CIS benchmarks for Kubernetes. The benchmark describes the best practices for securing unmanaged Kubernetes clusters. The CIS Kubernetes Benchmark encompasses the control plane and the data plane. Since Amazon EKS provides a fully managed control plane, not all of the recommendations from the CIS Kubernetes Benchmark are applicable. To ensure this scope reflects how Amazon EKS is implemented, AWS created -the _CIS Amazon EKS Benchmark_. The EKS benchmark inherits from CIS +the CIS Amazon EKS Benchmark. The EKS benchmark inherits from CIS Kubernetes Benchmark with additional inputs from the community with -specific configuration considerations for EKS clusters. - -When running https://github.com/aquasecurity/kube-bench[kube-bench] +specific configuration considerations for EKS clusters.

+
+
+

When running kube-bench against an EKS cluster, follow -https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster[these -instructions] from Aqua Security. For further information see -https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing -The CIS Amazon EKS Benchmark]. - -=== Minimize access to worker nodes - -Instead of enabling SSH access, use -https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM -Session Manager] when you need to remote into a host. Unlike SSH keys +these +instructions from Aqua Security. For further information see +Introducing +The CIS Amazon EKS Benchmark.

+
+
+
+

13.4.5. Minimize access to worker nodes

+
+

Instead of enabling SSH access, use +SSM +Session Manager when you need to remote into a host. Unlike SSH keys which can be lost, copied, or shared, Session Manager allows you to control access to EC2 instances using IAM. Moreover, it provides an -audit trail and log of the commands that were run on the instance. - -As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 +audit trail and log of the commands that were run on the instance.

+
+
+

As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 Launch Templates. This allows you to embed the SSM agent into the AMI or install it as the worker node is being bootstrapped. If you rather not modify the Optimized AMI or the ASG’s launch template, you can install the SSM agent with a DaemonSet as in -https://github.com/aws-samples/ssm-agent-daemonset-installer[this -example]. - -==== Minimal IAM policy for SSM based SSH Access - -The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a +this +example.

+
+
+
Minimal IAM policy for SSM based SSH Access
+
+

The AmazonSSMManagedInstanceCore AWS managed policy contains a number of permissions that are not required for SSM Session Manager / SSM RunCommand if you’re just looking to avoid SSH access. Of concern -specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which +specifically is the * permissions for ssm:GetParameter(s) which would allow for the role to access all parameters in Parameter Store -(including SecureStrings with the AWS managed KMS key configured). - -The following IAM policy contains the minimal set of permissions to -enable node access via SSM Systems Manager. - -[source,json] ----- -{ +(including SecureStrings with the AWS managed KMS key configured).

+
+
+

The following IAM policy contains the minimal set of permissions to +enable node access via SSM Systems Manager.

+
+
+
+
{
   "Version": "2012-10-17",
   "Statement": [
     {
@@ -5782,120 +6886,159 @@ 

Reuse AWS SDK sessions with IRSA

"Resource": "*" } ] -} ----- - -With this policy in place and the -https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html[Session -Manager plugin] installed, you can then run - -[source,bash] ----- -aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE] ----- - -to access the node. - -!!! note You may also want to consider adding permissions to -https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable -Session Manager logging]. - -=== Deploy workers onto private subnets - -By deploying workers onto private subnets, you minimize their exposure +}
+
+
+
+

With this policy in place and the +Session +Manager plugin installed, you can then run

+
+
+
+
aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE]
+
+
+
+

to access the node.

+
+
+

!!! note You may also want to consider adding permissions to +enable +Session Manager logging.

+
+
+
+
+

13.4.6. Deploy workers onto private subnets

+
+

By deploying workers onto private subnets, you minimize their exposure to the Internet where attacks often originate. Beginning April 22, 2020, the assignment of public IP addresses to nodes in a managed node groups will be controlled by the subnet they are deployed onto. Prior to this, nodes in a Managed Node Group were automatically assigned a public IP. If you choose to deploy your worker nodes on to public subnets, -implement restrictive AWS security group rules to limit their exposure. - -=== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices - -You can use -https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon -Inspector] to check for unintended network access to your nodes and for -vulnerabilities on the underlying Amazon EC2 instances. - -Amazon Inspector can provide common vulnerabilities and exposures (CVE) +implement restrictive AWS security group rules to limit their exposure.

+
+
+
+

13.4.7. Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices

+
+

You can use +Amazon +Inspector to check for unintended network access to your nodes and for +vulnerabilities on the underlying Amazon EC2 instances.

+
+
+

Amazon Inspector can provide common vulnerabilities and exposures (CVE) data for your Amazon EC2 instances only if the Amazon EC2 Systems Manager (SSM) agent is installed and enabled. This agent is preinstalled on several -https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html[Amazon -Machine Images (AMIs)] including -https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS -optimized Amazon Linux AMIs]. Regardless of SSM agent status, all of +Amazon +Machine Images (AMIs) including +EKS +optimized Amazon Linux AMIs. Regardless of SSM agent status, all of your Amazon EC2 instances are scanned for network reachability issues. For more information about configuring scans for Amazon EC2, see -https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html[Scanning -Amazon EC2 instances]. - -!!! attention Inspector cannot be run on the infrastructure used to run -Fargate pods. - -== Alternatives - -=== Run SELinux - -!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, -Bottlerocket, and Amazon Linux 2023 - -SELinux provides an additional layer of security to keep containers +Scanning +Amazon EC2 instances.

+
+
+

!!! attention Inspector cannot be run on the infrastructure used to run +Fargate pods.

+
+
+
+
+

13.5. Alternatives

+
+

13.5.1. Run SELinux

+
+

!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, +Bottlerocket, and Amazon Linux 2023

+
+
+

SELinux provides an additional layer of security to keep containers isolated from each other and from the host. SELinux allows administrators to enforce mandatory access controls (MAC) for every user, application, process, and file. Think of it as a backstop that restricts the operations that can be performed against to specific resources based on a set of labels. On EKS, SELinux can be used to -prevent containers from accessing each other’s resources. - -Container SELinux policies are defined in the -https://github.com/containers/container-selinux[container-selinux] +prevent containers from accessing each other’s resources.

+
+
+

Container SELinux policies are defined in the +container-selinux package. Docker CE requires this package (along with its dependencies) so that the processes and files created by Docker (or other container runtimes) run with limited system access. Containers leverage the -`+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +container_t label which is an alias to svirt_lxc_net_t. These policies effectively prevent containers from accessing certain features -of the host. - -When you configure SELinux for Docker, Docker automatically labels -workloads `+container_t+` as a type and gives each container a unique +of the host.

+
+
+

When you configure SELinux for Docker, Docker automatically labels +workloads container_t as a type and gives each container a unique MCS level. This will isolate containers from one another. If you need looser restrictions, you can create your own profile in SElinux which grants a container permissions to specific areas of the file system. This is similar to PSPs in that you can create different profiles for different containers/pods. For example, you can have a profile for general workloads with a set of restrictive controls and another for -things that require privileged access. - -SELinux for Containers has a set of options that can be configured to +things that require privileged access.

+
+
+

SELinux for Containers has a set of options that can be configured to modify the default restrictions. The following SELinux Booleans can be -enabled or disabled based on your needs: - -[width="100%",cols="30%,^40%,30%",options="header",] -|=== -|Boolean |Default |Description -|`+container_connect_any+` |`+off+` |Allow containers to access +enabled or disabled based on your needs:

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
BooleanDefaultDescription

container_connect_any

off

Allow containers to access privileged ports on the host. For example, if you have a container that -needs to map ports to 443 or 80 on the host. - -|`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +needs to map ports to 443 or 80 on the host.

container_manage_cgroup

off

Allow containers to manage cgroup configuration. For example, a container running systemd will need this -to be enabled. - -|`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file -system. -|=== - -By default, containers are allowed to read/execute under `+/usr+` and -read most content from `+/etc+`. The files under `+/var/lib/docker+` and -`+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +to be enabled.

container_use_cephfs

off

Allow containers to use a ceph file +system.

+
+

By default, containers are allowed to read/execute under /usr and +read most content from /etc. The files under /var/lib/docker and +/var/lib/containers have the label container_var_lib_t. To view a full list of default, labels see the -https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] -file. - -[source,bash] ----- -docker container run -it \ +container.fc +file.

+
+
+
+
docker container run -it \
   -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \
   centos:7 cat /host/repositories.json
 # cat: /host/repositories.json: Permission denied
@@ -5903,20 +7046,28 @@ 

Reuse AWS SDK sessions with IRSA

docker container run -it \ -v /etc/passwd:/host/etc/passwd \ centos:7 cat /host/etc/passwd -# cat: /host/etc/passwd: Permission denied ----- - -Files labeled with `+container_file_t+` are the only files that are +# cat: /host/etc/passwd: Permission denied
+
+
+
+

Files labeled with container_file_t are the only files that are writable by containers. If you want a volume mount to be writeable, you -will needed to specify `+:z+` or `+:Z+` at the end. - -* `+:z+` will re-label the files so that the container can read/write -* `+:Z+` will re-label the files so that *only* the container can -read/write - -[source,bash] ----- -ls -Z /var/lib/misc +will needed to specify :z or :Z at the end.

+
+
+
    +
  • +

    :z will re-label the files so that the container can read/write

    +
  • +
  • +

    :Z will re-label the files so that only the container can +read/write

    +
  • +
+
+
+
+
ls -Z /var/lib/misc
 # -rw-r--r--. root root system_u:object_r:var_lib_t:s0   postfix.aliasesdb-stamp
 
 docker container run -it \
@@ -5924,156 +7075,306 @@ 

Reuse AWS SDK sessions with IRSA

centos:7 echo "Relabeled!" ls -Z /var/lib/misc -#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp ----- - -[source,bash] ----- -docker container run -it \ +#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp
+
+
+
+
+
docker container run -it \
   -v /var/log:/host/var/log:Z \
-  fluentbit:latest
-----
-
-In Kubernetes, relabeling is slightly different. Rather than having
+  fluentbit:latest
+
+
+
+

In Kubernetes, relabeling is slightly different. Rather than having Docker automatically relabel the files, you can specify a custom MCS label to run the pod. Volumes that support relabeling will automatically be relabeled so that they are accessible. Pods with a matching MCS label will be able to access the volume. If you need strict isolation, set a -different MCS label for each pod. - -[source,yaml] ----- -securityContext: +different MCS label for each pod.

+
+
+
+
securityContext:
   seLinuxOptions:
     # Provide a unique MCS label per container
     # You can specify user, role, and type also
     # enforcement based on type and level (svert)
-    level: s0:c144:c154
-----
-
-In this example `+s0:c144:c154+` corresponds to an MCS label assigned to
-a file that the container is allowed to access.
-
-On EKS you could create policies that allow for privileged containers to
+    level: s0:c144:c154
+
+
+
+

In this example s0:c144:c154 corresponds to an MCS label assigned to +a file that the container is allowed to access.

+
+
+

On EKS you could create policies that allow for privileged containers to run, like FluentD and create an SELinux policy to allow it to read from /var/log on the host without needing to relabel the host directory. Pods -with the same label will be able to access the same host volumes. - -We have implemented -https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for -Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These +with the same label will be able to access the same host volumes.

+
+
+

We have implemented +sample AMIs for +Amazon EKS that have SELinux configured on CentOS 7 and RHEL 7. These AMIs were developed to demonstrate sample implementations that meet -requirements of highly regulated customers, such as STIG, CJIS, and C2S. - -!!! caution SELinux will ignore containers where the type is unconfined. - -== Tools and resources - -* https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux -Kubernetes RBAC and Shipping Security Policies for On-prem Applications] -* https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html[Iterative -Hardening of Kubernetes] -* https://linux.die.net/man/1/audit2allow[Audit2Allow] -* https://linux.die.net/man/8/sealert[SEAlert] -* https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica[Generate -SELinux policies for containers with Udica] describes a tool that looks +requirements of highly regulated customers, such as STIG, CJIS, and C2S.

+
+
+

!!! caution SELinux will ignore containers where the type is unconfined.

+
+
+
+
+

13.6. Tools and resources

+
+
    +
  • +

    SELinux +Kubernetes RBAC and Shipping Security Policies for On-prem Applications

    +
  • +
  • +

    Iterative +Hardening of Kubernetes

    +
  • +
  • +

    Audit2Allow

    +
  • +
  • +

    SEAlert

    +
  • +
  • +

    Generate +SELinux policies for containers with Udica describes a tool that looks at container spec files for Linux capabilities, ports, and mount points, and generates a set of SELinux rules that allow the container to run -properly -* https://github.com/aws-samples/amazon-eks-custom-amis#hardening[AMI -Hardening] playbooks for hardening the OS to meet different regulatory -requirements -* https://github.com/keikoproj/upgrade-manager[Keiko Upgrade Manager] an +properly

    +
  • +
  • +

    AMI +Hardening playbooks for hardening the OS to meet different regulatory +requirements

    +
  • +
  • +

    Keiko Upgrade Manager an open source project from Intuit that orchestrates the rotation of worker -nodes. -* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] -* https://eksctl.io/[eksctl] - -:leveloffset: 1 -:leveloffset: +1 - -= Compliance - -Compliance is a shared responsibility between AWS and the consumers of -its services. Generally speaking, AWS is responsible for "`security of -the cloud`" whereas its users are responsible for "`security in the -cloud.`" The line that delineates what AWS and its users are responsible +nodes.

    +
  • +
  • +

    Sysdig Secure

    +
  • +
  • +

    eksctl

    +
  • +
+
+
+
+
+
+

14. Compliance

+
+
+

Compliance is a shared responsibility between AWS and the consumers of +its services. Generally speaking, AWS is responsible for “security of +the cloud” whereas its users are responsible for “security in the +cloud.” The line that delineates what AWS and its users are responsible for will vary depending on the service. For example, with Fargate, AWS is responsible for managing the physical security of its data centers, the hardware, the virtual infrastructure (Amazon EC2), and the container runtime (Docker). Users of Fargate are responsible for securing the container image and their application. Knowing who is responsible for what is an important consideration when running workloads that must -adhere to compliance standards. - -The following table shows the compliance programs with which the -different container services conform. - -[width="99%",cols="30%,^17%,^17%,^19%,^17%",options="header",] -|=== -|Compliance Program |Amazon ECS Orchestrator |Amazon EKS Orchestrator -|ECS Fargate |Amazon ECR -|PCI DSS Level 1 |1 |1 |1 |1 - -|HIPAA Eligible |1 |1 |1 |1 - -|SOC I |1 |1 |1 |1 - -|SOC II |1 |1 |1 |1 - -|SOC III |1 |1 |1 |1 - -|ISO 27001:2013 |1 |1 |1 |1 - -|ISO 9001:2015 |1 |1 |1 |1 - -|ISO 27017:2015 |1 |1 |1 |1 - -|ISO 27018:2019 |1 |1 |1 |1 - -|IRAP |1 |1 |1 |1 - -|FedRAMP Moderate (East/West) |1 |1 |0 |1 - -|FedRAMP High (GovCloud) |1 |1 |0 |1 - -|DOD CC SRG |1 |DISA Review (IL5) |0 |1 - -|HIPAA BAA |1 |1 |1 |1 - -|MTCS |1 |1 |0 |1 - -|C5 |1 |1 |0 |1 - -|K-ISMS |1 |1 |0 |1 - -|ENS High |1 |1 |0 |1 - -|OSPAR |1 |1 |0 |1 - -|HITRUST CSF |1 |1 |1 |1 -|=== - -Compliance status changes over time. For the latest status, always refer -to https://aws.amazon.com/compliance/services-in-scope/. - -For further information about cloud accreditation models and best +adhere to compliance standards.

+
+
+

The following table shows the compliance programs with which the +different container services conform.

+
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Compliance ProgramAmazon ECS OrchestratorAmazon EKS OrchestratorECS FargateAmazon ECR

PCI DSS Level 1

1

1

1

1

HIPAA Eligible

1

1

1

1

SOC I

1

1

1

1

SOC II

1

1

1

1

SOC III

1

1

1

1

ISO 27001:2013

1

1

1

1

ISO 9001:2015

1

1

1

1

ISO 27017:2015

1

1

1

1

ISO 27018:2019

1

1

1

1

IRAP

1

1

1

1

FedRAMP Moderate (East/West)

1

1

0

1

FedRAMP High (GovCloud)

1

1

0

1

DOD CC SRG

1

DISA Review (IL5)

0

1

HIPAA BAA

1

1

1

1

MTCS

1

1

0

1

C5

1

1

0

1

K-ISMS

1

1

0

1

ENS High

1

1

0

1

OSPAR

1

1

0

1

HITRUST CSF

1

1

1

1

+
+

Compliance status changes over time. For the latest status, always refer +to https://aws.amazon.com/compliance/services-in-scope/.

+
+
+

For further information about cloud accreditation models and best practices, see the AWS whitepaper, -https://d1.awsstatic.com/whitepapers/accreditation-models-for-secure-cloud-adoption.pdf[Accreditation -Models for Secure Cloud Adoption] - -== Shifting Left - -The concept of shifting left involves catching policy violations and +Accreditation +Models for Secure Cloud Adoption

+
+
+

14.1. Shifting Left

+
+

The concept of shifting left involves catching policy violations and errors earlier in the software development lifecycle. From a security perspective, this can be very beneficial. A developer, for example, can fix issues with their configuration before their application is deployed to the cluster. Catching mistakes like this earlier will help prevent -configurations that violate your policies from being deployed. - -=== Policy as Code - -Policy can be thought of as a set of rules for governing behaviors, +configurations that violate your policies from being deployed.

+
+
+

14.1.1. Policy as Code

+
+

Policy can be thought of as a set of rules for governing behaviors, i.e. behaviors that are allowed or those that are prohibited. For example, you may have a policy that says that all Dockerfiles should include a USER directive that causes the container to run as a non-root @@ -6086,150 +7387,190 @@

Reuse AWS SDK sessions with IRSA

benefit of this approach is that you can reuse your DevOps and GitOps strategies to manage and consistently apply policies across fleets of Kubernetes clusters. Please refer to -https://aws.github.io/aws-eks-best-practices/security/docs/pods/#pod-security[Pod -Security] for information about PaC options and the future of PSPs. - -=== Use policy-as-code tools in pipelines to detect violations before deployment - -* https://www.openpolicyagent.org/[OPA] is an open source policy engine +Pod +Security for information about PaC options and the future of PSPs.

+
+
+
+

14.1.2. Use policy-as-code tools in pipelines to detect violations before deployment

+
+
    +
  • +

    OPA is an open source policy engine that’s part of the CNCF. It’s used for making policy decisions and can be run a variety of different ways, e.g. as a language library or a service. OPA policies are written in a Domain Specific Language (DSL) called Rego. While it is often run as part of a Kubernetes Dynamic Admission Controller as the -https://github.com/open-policy-agent/gatekeeper[Gatekeeper] project, OPA +Gatekeeper project, OPA can also be incorporated into your CI/CD pipeline. This allows developers to get feedback about their configuration earlier in the release cycle which can subsequently help them resolve issues before they get to production. A collection of common OPA policies can be found in the GitHub -https://github.com/aws/aws-eks-best-practices/tree/master/policies/opa[repository] -for this project. -* https://github.com/open-policy-agent/conftest[Conftest] is built on +repository +for this project.

    +
  • +
  • +

    Conftest is built on top of OPA and it provides a developer focused experience for testing -Kubernetes configuration. -* https://kyverno.io/[Kyverno] is a policy engine designed for +Kubernetes configuration.

    +
  • +
  • +

    Kyverno is a policy engine designed for Kubernetes. With Kyverno, policies are managed as Kubernetes resources and no new language is required to write policies. This allows using familiar tools such as kubectl, git, and kustomize to manage policies. Kyverno policies can validate, mutate, and generate Kubernetes resources plus ensure OCI image supply chain security. The -https://kyverno.io/docs/kyverno-cli/[Kyverno CLI] can be used to test +Kyverno CLI can be used to test policies and validate resources as part of a CI/CD pipeline. All the Kyverno community policies can be found on the -https://kyverno.io/policies/[Kyverno website], and for examples using +Kyverno website, and for examples using the Kyverno CLI to write tests in pipelines, see the -https://github.com/kyverno/policies[policies repository]. - -== Tools and resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/10-regulatory-compliance[Amazon -EKS Security Immersion Workshop - Regulatory Compliance] -* https://github.com/aquasecurity/kube-bench[kube-bench] -* https://github.com/docker/docker-bench-security[docker-bench-security] -* https://aws.amazon.com/inspector/[AWS Inspector] -* https://github.com/kubernetes/community/blob/master/sig-security/security-audit-2019/findings/Kubernetes%20Final%20Report.pdf[Kubernetes -Security Review] A 3rd party security assessment of Kubernetes 1.13.4 -(2019) -* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +policies repository.

    +
  • +
+
+
+
+
+

14.2. Tools and resources

+
+ +
+
+
+
+
+

15. Incident response and forensics

+
+
+

Your ability to react quickly to an incident can help minimize damage caused from a breach. Having a reliable alerting system that can warn you of suspicious behavior is the first step in a good incident response plan. When an incident does arise, you have to quickly decide whether to destroy and replace the effected container, or isolate and inspect the container. If you choose to isolate the container as part of a forensic investigation and root cause analysis, then the following set of -activities should be followed: - -== Sample incident response plan - -=== Identify the offending Pod and worker node - -Your first course of action should be to isolate the damage. Start by +activities should be followed:

+
+
+

15.1. Sample incident response plan

+
+

15.1.1. Identify the offending Pod and worker node

+
+

Your first course of action should be to isolate the damage. Start by identifying where the breach occurred and isolate that Pod and its node -from the rest of the infrastructure. - -=== Identify the offending Pods and worker nodes using workload name - -If you know the name and namespace of the offending pod, you can -identify the the worker node running the pod as follows: - -[source,bash] ----- -kubectl get pods <name> --namespace <namespace> -o=jsonpath='{.spec.nodeName}{"\n"}' ----- - -If a https://kubernetes.io/docs/concepts/workloads/controllers/[Workload -Resource] such as a Deployment has been compromised, it is likely that +from the rest of the infrastructure.

+
+
+
+

15.1.2. Identify the offending Pods and worker nodes using workload name

+
+

If you know the name and namespace of the offending pod, you can +identify the the worker node running the pod as follows:

+
+
+
+
kubectl get pods <name> --namespace <namespace> -o=jsonpath='{.spec.nodeName}{"\n"}'
+
+
+
+

If a Workload +Resource such as a Deployment has been compromised, it is likely that all the pods that are part of the workload resource are compromised. Use the following command to list all the pods of the Workload Resource and -the nodes they are running on: - -[source,bash] ----- -selector=$(kubectl get deployments <name> \ +the nodes they are running on:

+
+
+
+
selector=$(kubectl get deployments <name> \
  --namespace <namespace> -o json | jq -j \
 '.spec.selector.matchLabels | to_entries | .[] | "\(.key)=\(.value)"')
 
 kubectl get pods --namespace <namespace> --selector=$selector \
--o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"'
-----
-
-The above command is for deployments. You can run the same command for
-other workload resources such as replicasets,, statefulsets, etc.
-
-=== Identify the offending Pods and worker nodes using service account name
-
-In some cases, you may identify that a service account is compromised.
+-o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"'
+
+
+
+

The above command is for deployments. You can run the same command for +other workload resources such as replicasets,, statefulsets, etc.

+
+
+
+

15.1.3. Identify the offending Pods and worker nodes using service account name

+
+

In some cases, you may identify that a service account is compromised. It is likely that pods using the identified service account are compromised. You can identify all the pods using the service account and -nodes they are running on with the following command: - -[source,bash] ----- -kubectl get pods -o json --namespace <namespace> | \ +nodes they are running on with the following command:

+
+
+
+
kubectl get pods -o json --namespace <namespace> | \
     jq -r '.items[] |
     select(.spec.serviceAccount == "<service account name>") |
-    "\(.metadata.name) \(.spec.nodeName)"'
-----
-
-=== Identify Pods with vulnerable or compromised images and worker nodes
-
-In some cases, you may discover that a container image being used in
+    "\(.metadata.name) \(.spec.nodeName)"'
+
+
+
+
+

15.1.4. Identify Pods with vulnerable or compromised images and worker nodes

+
+

In some cases, you may discover that a container image being used in pods on your cluster is malicious or compromised. A container image is malicious or compromised, if it was found to contain malware, is a known bad image or has a CVE that has been exploited. You should consider all the pods using the container image compromised. You can identify the pods using the image and nodes they are running on with the following -command: - -[source,bash] ----- -IMAGE=<Name of the malicious/compromised image> +command:

+
+
+
+
IMAGE=<Name of the malicious/compromised image>
 
 kubectl get pods -o json --all-namespaces | \
     jq -r --arg image "$IMAGE" '.items[] |
     select(.spec.containers[] | .image == $image) |
-    "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"'
-----
-
-=== Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod
-
-A deny all traffic rule may help stop an attack that is already underway
+    "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"'
+
+
+
+
+

15.1.5. Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod

+
+

A deny all traffic rule may help stop an attack that is already underway by severing all connections to the pod. The following Network Policy -will apply to a pod with the label `+app=web+`. - -[source,yaml] ----- -apiVersion: networking.k8s.io/v1 +will apply to a pod with the label app=web.

+
+
+
+
apiVersion: networking.k8s.io/v1
 kind: NetworkPolicy
 metadata:
   name: default-deny
@@ -6239,198 +7580,274 @@ 

Reuse AWS SDK sessions with IRSA

app: web policyTypes: - Ingress - - Egress ----- - -!!! attention A Network Policy may prove ineffective if an attacker has + - Egress
+
+
+
+

!!! attention A Network Policy may prove ineffective if an attacker has gained access to underlying host. If you suspect that has happened, you can use -https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html[AWS -Security Groups] to isolate a compromised host from other hosts. When +AWS +Security Groups to isolate a compromised host from other hosts. When changing a host’s security group, be aware that it will impact all -containers running on that host. - -=== Revoke temporary security credentials assigned to the pod or worker node if necessary - -If the worker node has been assigned an IAM role that allows Pods to +containers running on that host.

+
+
+
+

15.1.6. Revoke temporary security credentials assigned to the pod or worker node if necessary

+
+

If the worker node has been assigned an IAM role that allows Pods to gain access to other AWS resources, remove those roles from the instance to prevent further damage from the attack. Similarly, if the Pod has been assigned an IAM role, evaluate whether you can safely remove the -IAM policies from the role without impacting other workloads. - -=== Cordon the worker node - -By cordoning the impacted worker node, you’re informing the scheduler to +IAM policies from the role without impacting other workloads.

+
+
+
+

15.1.7. Cordon the worker node

+
+

By cordoning the impacted worker node, you’re informing the scheduler to avoid scheduling pods onto the affected node. This will allow you to -remove the node for forensic study without disrupting other workloads. - -!!! info This guidance is not applicable to Fargate where each Fargate +remove the node for forensic study without disrupting other workloads.

+
+
+

!!! info This guidance is not applicable to Fargate where each Fargate pod run in its own sandboxed environment. Instead of cordoning, sequester the affected Fargate pods by applying a network policy that -denies all ingress and egress traffic. - -=== Enable termination protection on impacted worker node - -An attacker may attempt to erase their misdeeds by terminating an +denies all ingress and egress traffic.

+
+
+
+

15.1.8. Enable termination protection on impacted worker node

+
+

An attacker may attempt to erase their misdeeds by terminating an affected node. Enabling -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingDisableAPITermination[termination -protection] can prevent this from happening. -https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection[Instance -scale-in protection] will protect the node from a scale-in event. - -!!! warning You cannot enable termination protection on a Spot instance. - -=== Label the offending Pod/Node with a label indicating that it is part of an active investigation - -This will serve as a warning to cluster administrators not to tamper -with the affected Pods/Nodes until the investigation is complete. - -=== Capture volatile artifacts on the worker node - -* *Capture the operating system memory*. This will capture the Docker +termination +protection can prevent this from happening. +Instance +scale-in protection will protect the node from a scale-in event.

+
+
+

!!! warning You cannot enable termination protection on a Spot instance.

+
+
+
+

15.1.9. Label the offending Pod/Node with a label indicating that it is part of an active investigation

+
+

This will serve as a warning to cluster administrators not to tamper +with the affected Pods/Nodes until the investigation is complete.

+
+
+
+

15.1.10. Capture volatile artifacts on the worker node

+
+
    +
  • +

    Capture the operating system memory. This will capture the Docker daemon (or other container runtime) and its subprocesses per container. This can be accomplished using tools like -https://github.com/504ensicsLabs/LiME[LiME] and -https://www.volatilityfoundation.org/[Volatility], or through +LiME and +Volatility, or through higher-level tools such as -https://aws.amazon.com/solutions/implementations/automated-forensics-orchestrator-for-amazon-ec2/[Automated -Forensics Orchestrator for Amazon EC2] that build on top of them. -* *Perform a netstat tree dump of the processes running and the open -ports*. This will capture the docker daemon and its subprocess per -container. -* *Run commands to save container-level state before evidence is -altered*. You can use capabilities of the container runtime to capture +Automated +Forensics Orchestrator for Amazon EC2 that build on top of them.

    +
  • +
  • +

    Perform a netstat tree dump of the processes running and the open +ports. This will capture the docker daemon and its subprocess per +container.

    +
  • +
  • +

    Run commands to save container-level state before evidence is +altered. You can use capabilities of the container runtime to capture information about currently running containers. For example, with -Docker, you could do the following: -** `+docker top CONTAINER+` for processes running. -** `+docker logs CONTAINER+` for daemon level held logs. -** `+docker inspect CONTAINER+` for various information about the -container. -+ -The same could be achieved with containerd using the -https://github.com/containerd/nerdctl[nerdctl] CLI, in place of -`+docker+` (e.g. `+nerdctl inspect+`). Some additional commands are +Docker, you could do the following:

    +
    +
      +
    • +

      docker top CONTAINER for processes running.

      +
    • +
    • +

      docker logs CONTAINER for daemon level held logs.

      +
    • +
    • +

      docker inspect CONTAINER for various information about the +container.

      +
      +

      The same could be achieved with containerd using the +nerdctl CLI, in place of +docker (e.g. nerdctl inspect). Some additional commands are available depending on the container runtime. For example, Docker has -`+docker diff+` to see changes to the container filesystem or -`+docker checkpoint+` to save all container state including volatile +docker diff to see changes to the container filesystem or +docker checkpoint to save all container state including volatile memory (RAM). See -https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/[this -Kubernetes blog post] for discussion of similar capabilities with -containerd or CRI-O runtimes. -* *Pause the container for forensic capture*. -* *Snapshot the instance’s EBS volumes*. - -=== Redeploy compromised Pod or Workload Resource - -Once you have gathered data for forensic analysis, you can redeploy the -compromised pod or workload resource. - -First roll out the fix for the vulnerability that was compromised and -start new replacement pods. Then delete the vulnerable pods. - -If the vulnerable pods are managed by a higher-level Kubernetes workload +this +Kubernetes blog post for discussion of similar capabilities with +containerd or CRI-O runtimes.

      +
      +
    • +
    +
    +
  • +
  • +

    Pause the container for forensic capture.

    +
  • +
  • +

    Snapshot the instance’s EBS volumes.

    +
  • +
+
+
+
+

15.1.11. Redeploy compromised Pod or Workload Resource

+
+

Once you have gathered data for forensic analysis, you can redeploy the +compromised pod or workload resource.

+
+
+

First roll out the fix for the vulnerability that was compromised and +start new replacement pods. Then delete the vulnerable pods.

+
+
+

If the vulnerable pods are managed by a higher-level Kubernetes workload resource (for example, a Deployment or DaemonSet), deleting them will schedule new ones. So vulnerable pods will be launched again. In that case you should deploy a new replacement workload resource after fixing -the vulnerability. Then you should delete the vulnerable workload. - -== Recommendations - -=== Review the AWS Security Incident Response Whitepaper - -While this section gives a brief overview along with a few +the vulnerability. Then you should delete the vulnerable workload.

+
+
+
+
+

15.2. Recommendations

+
+

15.2.1. Review the AWS Security Incident Response Whitepaper

+
+

While this section gives a brief overview along with a few recommendations for handling suspected security breaches, the topic is exhaustively covered in the white paper, -https://docs.aws.amazon.com/whitepapers/latest/aws-security-incident-response-guide/welcome.html[AWS -Security Incident Response]. - -=== Practice security game days - -Divide your security practitioners into 2 teams: red and blue. The red +AWS +Security Incident Response.

+
+
+
+

15.2.2. Practice security game days

+
+

Divide your security practitioners into 2 teams: red and blue. The red team will be focused on probing different systems for vulnerabilities while the blue team will be responsible for defending against them. If you don’t have enough security practitioners to create separate teams, consider hiring an outside entity that has knowledge of Kubernetes -exploits. - -https://github.com/cyberark/kubesploit[Kubesploit] is a penetration +exploits.

+
+
+

Kubesploit is a penetration testing framework from CyberArk that you can use to conduct game days. Unlike other tools which scan your cluster for vulnerabilities, kubesploit simulates a real-world attack. This gives your blue team an opportunity to practice its response to an attack and gauge its -effectiveness. - -=== Run penetration tests against your cluster - -Periodically attacking your own cluster can help you discover +effectiveness.

+
+
+
+

15.2.3. Run penetration tests against your cluster

+
+

Periodically attacking your own cluster can help you discover vulnerabilities and misconfigurations. Before getting started, follow -the https://aws.amazon.com/security/penetration-testing/[penetration -test guidelines] before conducting a test against your cluster. - -== Tools and resources - -* https://github.com/aquasecurity/kube-hunter[kube-hunter], a -penetration testing tool for Kubernetes. -* https://www.gremlin.com/product/#kubernetes[Gremlin], a chaos +the penetration +test guidelines before conducting a test against your cluster.

+
+
+
+
+

15.3. Tools and resources

+
+
    +
  • +

    kube-hunter, a +penetration testing tool for Kubernetes.

    +
  • +
  • +

    Gremlin, a chaos engineering toolkit that you can use to simulate attacks against your -applications and infrastructure. -* https://github.com/kubernetes/sig-security/blob/main/sig-security-external-audit/security-audit-2019/findings/AtredisPartners_Attacking_Kubernetes-v1.0.pdf[Attacking -and Defending Kubernetes Installations] -* https://www.cyberark.com/resources/threat-research-blog/kubesploit-a-new-offensive-tool-for-testing-containerized-environments[kubesploit] -* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +applications and infrastructure.

    +
  • +
  • +

    Attacking +and Defending Kubernetes Installations

    +
  • +
  • +

    kubesploit

    +
  • +
  • +

    NeuVector by SUSE open source, zero-trust container security platform, provides vulnerability- and risk -reporting as well as security event notification -* https://www.youtube.com/watch?v=CH7S5rE3j8w[Advanced Persistent -Threats] -* https://www.youtube.com/watch?v=LtCx3zZpOfs[Kubernetes Practical -Attack and Defense] -* https://www.youtube.com/watch?v=1LMo0CftVC4[Compromising Kubernetes -Cluster by Exploiting RBAC Permissions] - -:leveloffset: 1 -:leveloffset: +1 - -= Image security - -You should consider the container image as your first line of defense +reporting as well as security event notification

    +
  • +
  • +

    Advanced Persistent +Threats

    +
  • +
  • +

    Kubernetes Practical +Attack and Defense

    +
  • +
  • +

    Compromising Kubernetes +Cluster by Exploiting RBAC Permissions

    +
  • +
+
+
+
+
+
+

16. Image security

+
+
+

You should consider the container image as your first line of defense against an attack. An insecure, poorly constructed image can allow an attacker to escape the bounds of the container and gain access to the host. Once on the host, an attacker can gain access to sensitive information or move laterally within the cluster or with your AWS account. The following best practices will help mitigate risk of this -happening. - -== Recommendations - -=== Create minimal images - -Start by removing all extraneous binaries from the container image. If +happening.

+
+
+

16.1. Recommendations

+
+

16.1.1. Create minimal images

+
+

Start by removing all extraneous binaries from the container image. If you’re using an unfamiliar image from Dockerhub, inspect the image using -an application like https://github.com/wagoodman/dive[Dive] which can +an application like Dive which can show you the contents of each of the container’s layers. Remove all binaries with the SETUID and SETGID bits as they can be used to escalate privilege and consider removing all shells and utilities like nc and curl that can be used for nefarious purposes. You can find the files -with SETUID and SETGID bits with the following command: - -[source,bash] ----- -find / -perm /6000 -type f -exec ls -ld {} \; ----- - -To remove the special permissions from these files, add the following -directive to your container image: - -[source,docker] ----- -RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true ----- - -Colloquially, this is known as de-fanging your image. - -=== Use multi-stage builds - -Using multi-stage builds is a way to create minimal images. Oftentimes, +with SETUID and SETGID bits with the following command:

+
+
+
+
find / -perm /6000 -type f -exec ls -ld {} \;
+
+
+
+

To remove the special permissions from these files, add the following +directive to your container image:

+
+
+
+
RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true
+
+
+
+

Colloquially, this is known as de-fanging your image.

+
+
+
+

16.1.2. Use multi-stage builds

+
+

Using multi-stage builds is a way to create minimal images. Oftentimes, multi-stage builds are used to automate parts of the Continuous Integration cycle. For example, multi-stage builds can be used to lint your source code or perform static code analysis. This affords @@ -6441,149 +7858,204 @@

Reuse AWS SDK sessions with IRSA

devoid of build tools and other extraneous binaries improves your security posture by reducing the attack surface of the image. For additional information about multi-stage builds, see -https://docs.docker.com/develop/develop-images/multistage-build/[Docker’s -multi-stage builds documentation]. - -=== Create Software Bill of Materials (SBOMs) for your container image - -A "`software bill of materials`" (SBOM) is a nested inventory of the +Docker’s +multi-stage builds documentation.

+
+
+
+

16.1.3. Create Software Bill of Materials (SBOMs) for your container image

+
+

A “software bill of materials” (SBOM) is a nested inventory of the software artifacts that make up your container image. SBOM is a key building block in software security and software supply chain risk -management. https://anchore.com/sbom/[Generating&#44; storing SBOMS in a -central repository and scanning SBOMs for vulnerabilities] helps address -the following concerns: - -* *Visibility*: understand what components make up your container image. +management. Generating, storing SBOMS in a +central repository and scanning SBOMs for vulnerabilities helps address +the following concerns:

+
+
+
    +
  • +

    Visibility: understand what components make up your container image. Storing in a central repository allows SBOMs to be audited and scanned anytime, even post deployment to detect and respond to new -vulnerabilities such as zero day vulnerabilities. -* *Provenance Verification*: assurance that existing assumptions of +vulnerabilities such as zero day vulnerabilities.

    +
  • +
  • +

    Provenance Verification: assurance that existing assumptions of where and how an artifact originates from are true and that the artifact or its accompanying metadata have not been tampered with during the -build or delivery processes. -* *Trustworthiness*: assurance that a given artifact and its contents +build or delivery processes.

    +
  • +
  • +

    Trustworthiness: assurance that a given artifact and its contents can be trusted to do what it is purported to do, i.e. is suitable for a purpose. This involves judgement on whether the code is safe to execute and making informed decisions about the risks associated with executing the code. Trustworthiness is assured by creating an attested pipeline execution report along with attested SBOM and attested CVE scan report to assure the consumers of the image that this image is in-fact created -through secure means (pipeline) with secure components. -* *Dependency Trust Verification*: recursive checking of an artifact’s +through secure means (pipeline) with secure components.

    +
  • +
  • +

    Dependency Trust Verification: recursive checking of an artifact’s dependency tree for trustworthiness and provenance of the artifacts it uses. Drift in SBOMs can help detect malicious activity including -unauthorized, untrusted dependencies, infiltration attempts. - -The following tools can be used to generate SBOM: - -* https://docs.aws.amazon.com/inspector[Amazon Inspector] can be used to -https://docs.aws.amazon.com/inspector/latest/user/sbom-export.html[create -and export SBOMs]. -* https://github.com/anchore/syft[Syft from Anchore] can also be used +unauthorized, untrusted dependencies, infiltration attempts.

    +
  • +
+
+
+

The following tools can be used to generate SBOM:

+
+
+
    +
  • +

    Amazon Inspector can be used to +create +and export SBOMs.

    +
  • +
  • +

    Syft from Anchore can also be used for SBOM generation. For quicker vulnerability scans, the SBOM generated for a container image can be used as an input to scan. The SBOM and scan report are then -https://github.com/sigstore/cosign/blob/main/doc/cosign_attach_attestation.md[attested -and attached] to the image before pushing the image to a central OCI -repository such as Amazon ECR for review and audit purposes. - -Learn more about securing your software supply chain by reviewing -https://project.linuxfoundation.org/hubfs/CNCF_SSCP_v1.pdf[CNCF Software -Supply Chain Best Practices guide]. - -=== Scan images for vulnerabilities regularly - -Like their virtual machine counterparts, container images can contain +attested +and attached to the image before pushing the image to a central OCI +repository such as Amazon ECR for review and audit purposes.

    +
  • +
+
+
+

Learn more about securing your software supply chain by reviewing +CNCF Software +Supply Chain Best Practices guide.

+
+
+
+

16.1.4. Scan images for vulnerabilities regularly

+
+

Like their virtual machine counterparts, container images can contain binaries and application libraries with vulnerabilities or develop vulnerabilities over time. The best way to safeguard against exploits is by regularly scanning your images with an image scanner. Images that are stored in Amazon ECR can be scanned on push or on-demand (once during a 24 hour period). ECR currently supports -https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html[two -types of scanning - Basic and Enhanced]. Basic scanning leverages -https://github.com/quay/clair[Clair] an open source image scanning +two +types of scanning - Basic and Enhanced. Basic scanning leverages +Clair an open source image scanning solution for no cost. -https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-enhanced.html[Enhanced -scanning] uses Amazon Inspector to provide automatic continuous scans -for https://aws.amazon.com/inspector/pricing/[additional cost]. After an +Enhanced +scanning uses Amazon Inspector to provide automatic continuous scans +for additional cost. After an image is scanned, the results are logged to the event stream for ECR in EventBridge. You can also see the results of a scan from within the ECR console. Images with a HIGH or CRITICAL vulnerability should be deleted or rebuilt. If an image that has been deployed develops a vulnerability, -it should be replaced as soon as possible. - -Knowing where images with vulnerabilities have been deployed is +it should be replaced as soon as possible.

+
+
+

Knowing where images with vulnerabilities have been deployed is essential to keeping your environment secure. While you could conceivably build an image tracking solution yourself, there are already several commercial offerings that provide this and other advanced -capabilities out of the box, including: - -* https://github.com/anchore/grype[Grype] -* https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/tools/twistcli_scan_images[Palo -Alto - Prisma Cloud (twistcli)] -* https://www.aquasec.com/[Aqua] -* https://github.com/Portshift/kubei[Kubei] -* https://github.com/aquasecurity/trivy[Trivy] -* https://support.snyk.io/hc/en-us/articles/360003946917-Test-images-with-the-Snyk-Container-CLI[Snyk] - -A Kubernetes validation webhook could also be used to validate that +capabilities out of the box, including:

+
+
+ +
+
+

A Kubernetes validation webhook could also be used to validate that images are free of critical vulnerabilities. Validation webhooks are invoked prior to the Kubernetes API. They are typically used to reject requests that don’t comply with the validation criteria defined in the webhook. -https://aws.amazon.com/blogs/containers/building-serverless-admission-webhooks-for-kubernetes-with-aws-sam/[This] +This is an example of a serverless webhook that calls the ECR describeImageScanFindings API to determine whether a pod is pulling an image with critical vulnerabilities. If vulnerabilities are found, the -pod is rejected and a message with list of CVEs is returned as an Event. - -=== Use attestations to validate artifact integrity - -An attestation is a cryptographically signed "`statement`" that claims -something - a "`predicate`" e.g. a pipeline run or the SBOM or the -vulnerability scan report is true about another thing - a "`subject`" -i.e. the container image. - -Attestations help users to validate that an artifact comes from a +pod is rejected and a message with list of CVEs is returned as an Event.

+
+
+
+

16.1.5. Use attestations to validate artifact integrity

+
+

An attestation is a cryptographically signed “statement” that claims +something - a “predicate” e.g. a pipeline run or the SBOM or the +vulnerability scan report is true about another thing - a “subject” +i.e. the container image.

+
+
+

Attestations help users to validate that an artifact comes from a trusted source in the software supply chain. As an example, we may use a container image without knowing all the software components or dependencies that are included in that image. However, if we trust whatever the producer of the container image says about what software is present, we can use the producer’s attestation to rely on that artifact. This means that we can proceed to use the artifact safely in our -workflow in place of having done the analysis ourself. - -* Attestations can be created using -https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS -Signer] or -https://github.com/sigstore/cosign/blob/main/doc/cosign_attest.md[Sigstore -cosign]. -* Kubernetes admission controllers such as https://kyverno.io/[Kyverno] +workflow in place of having done the analysis ourself.

+
+
+
    +
  • +

    Attestations can be created using +AWS +Signer or +Sigstore +cosign.

    +
  • +
  • +

    Kubernetes admission controllers such as Kyverno can be used to -https://kyverno.io/docs/writing-policies/verify-images/sigstore/[verify -attestations]. -* Refer to this -https://catalog.us-east-1.prod.workshops.aws/workshops/49343bb7-2cc5-4001-9d3b-f6a33b3c4442/en-US/0-introduction[workshop] +verify +attestations.

    +
  • +
  • +

    Refer to this +workshop to learn more about software supply chain management best practices on AWS using open source tools with topics including creating and attaching -attestations to a container image. - -=== Create IAM policies for ECR repositories - -Nowadays, it is not uncommon for an organization to have multiple +attestations to a container image.

    +
  • +
+
+
+
+

16.1.6. Create IAM policies for ECR repositories

+
+

Nowadays, it is not uncommon for an organization to have multiple development teams operating independently within a shared AWS account. If these teams don’t need to share assets, you may want to create a set of IAM policies that restrict access to the repositories each team can interact with. A good way to implement this is by using ECR -https://docs.aws.amazon.com/AmazonECR/latest/userguide/Repositories.html#repository-concepts[namespaces]. +namespaces. Namespaces are a way to group similar repositories together. For example, all of the registries for team A can be prefaced with the team-a/ while those for team B can use the team-b/ prefix. The policy to -restrict access might look like the following: - -[source,json] ----- -{ +restrict access might look like the following:

+
+
+
+
{
   "Version": "2012-10-17",
   "Statement": [
     {
@@ -6603,12 +8075,14 @@ 

Reuse AWS SDK sessions with IRSA

] } ] -} ----- - -=== Consider using ECR private endpoints - -The ECR API has a public endpoint. Consequently, ECR registries can be +}
+
+
+
+
+

16.1.7. Consider using ECR private endpoints

+
+

The ECR API has a public endpoint. Consequently, ECR registries can be accessed from the Internet so long as the request has been authenticated and authorized by IAM. For those who need to operate in a sandboxed environment where the cluster VPC lacks an Internet Gateway (IGW), you @@ -6616,22 +8090,24 @@

Reuse AWS SDK sessions with IRSA

enables you to privately access the ECR API through a private IP address instead of routing traffic across the Internet. For additional information on this topic, see -https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html[Amazon -ECR interface VPC endpoints]. - -=== Implement endpoint policies for ECR - -The default endpoint policy for allows access to all ECR repositories +Amazon +ECR interface VPC endpoints.

+
+
+
+

16.1.8. Implement endpoint policies for ECR

+
+

The default endpoint policy for allows access to all ECR repositories within a region. This might allow an attacker/insider to exfiltrate data by packaging it as a container image and pushing it to a registry in another AWS account. Mitigating this risk involves creating an endpoint policy that limits API access to ECR repositories. For example, the following policy allows all AWS principles in your account to perform -all actions against your and only your ECR repositories: - -[source,json] ----- -{ +all actions against your and only your ECR repositories:

+
+
+
+
{
   "Statement": [
     {
       "Sid": "LimitECRAccess",
@@ -6641,70 +8117,113 @@ 

Reuse AWS SDK sessions with IRSA

"Resource": "arn:aws:ecr:<region>:<account_id>:repository/*" } ] -} ----- - -You can enhance this further by setting a condition that uses the new -`+PrincipalOrgID+` attribute which will prevent pushing/pulling of +}
+
+
+
+

You can enhance this further by setting a condition that uses the new +PrincipalOrgID attribute which will prevent pushing/pulling of images by an IAM principle that is not part of your AWS Organization. See, -https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid[aws:PrincipalOrgID] +aws:PrincipalOrgID for additional details. We recommended applying the same policy to both -the `+com.amazonaws.<region>.ecr.dkr+` and the -`+com.amazonaws.<region>.ecr.api+` endpoints. Since EKS pulls images for +the com.amazonaws.<region>.ecr.dkr and the +com.amazonaws.<region>.ecr.api endpoints. Since EKS pulls images for kube-proxy, coredns, and aws-node from ECR, you will need to add the account ID of the registry, -e.g. `+602401143452.dkr.ecr.us-west-2.amazonaws.com/*+` to the list of +e.g. 602401143452.dkr.ecr.us-west-2.amazonaws.com/* to the list of resources in the endpoint policy or alter the policy to allow pulls from “*” and restrict pushes to your account ID. The table below reveals the mapping between the AWS accounts where EKS images are vended from and -cluster region. - -[cols=",",options="header",] -|=== -|Account Number |Region -|602401143452 |All commercial regions except for those listed below -|— |— -|800184023465 |ap-east-1 - Asia Pacific (Hong Kong) -|558608220178 |me-south-1 - Middle East (Bahrain) -|918309763551 |cn-north-1 - China (Beijing) -|961992271922 |cn-northwest-1 - China (Ningxia) -|=== - -For further information about using endpoint policies, see -https://aws.amazon.com/blogs/containers/using-vpc-endpoint-policies-to-control-amazon-ecr-access/[Using -VPC endpoint policies to control Amazon ECR access]. - -=== Implement lifecycle policies for ECR - -The -https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf[NIST -Application Container Security Guide] warns about the risk of "`stale -images in registries`", noting that over time old images with +cluster region.

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Account NumberRegion

602401143452

All commercial regions except for those listed below

800184023465

ap-east-1 - Asia Pacific (Hong Kong)

558608220178

me-south-1 - Middle East (Bahrain)

918309763551

cn-north-1 - China (Beijing)

961992271922

cn-northwest-1 - China (Ningxia)

+
+

For further information about using endpoint policies, see +Using +VPC endpoint policies to control Amazon ECR access.

+
+
+
+

16.1.9. Implement lifecycle policies for ECR

+
+

The +NIST +Application Container Security Guide warns about the risk of “stale +images in registries”, noting that over time old images with vulnerable, out-of-date software packages should be removed to prevent accidental deployment and exposure. Each ECR repository can have a lifecycle policy that sets rules for when images expire. The -https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html[AWS -official documentation] describes how to set up test rules, evaluate +AWS +official documentation describes how to set up test rules, evaluate them and then apply them. There are several -https://docs.aws.amazon.com/AmazonECR/latest/userguide/lifecycle_policy_examples.html[lifecycle -policy examples] in the official docs that show different ways of -filtering the images in a repository: - -* Filtering by image age or count -* Filtering by tagged or untagged images -* Filtering by image tags, either in multiple rules or a single rule - -???+ warning If the image for long running application is purged from +lifecycle +policy examples in the official docs that show different ways of +filtering the images in a repository:

+
+
+
    +
  • +

    Filtering by image age or count

    +
  • +
  • +

    Filtering by tagged or untagged images

    +
  • +
  • +

    Filtering by image tags, either in multiple rules or a single rule

    +
  • +
+
+
+

???+ warning If the image for long running application is purged from ECR, it can cause an image pull errors when the application is redeployed or scaled horizontally. When using image lifecycle policies, be sure you have good CI/CD practices in place to keep deployments and the images that they reference up to date and always create [image] -expiry rules that account for how often you do releases/deployments. - -=== Create a set of curated images - -Rather than allowing developers to create their own images, consider +expiry rules that account for how often you do releases/deployments.

+
+
+
+

16.1.10. Create a set of curated images

+
+

Rather than allowing developers to create their own images, consider creating a set of vetted images for the different application stacks in your organization. By doing so, developers can forego learning how to compose Dockerfiles and concentrate on writing code. As changes are @@ -6715,45 +8234,51 @@

Reuse AWS SDK sessions with IRSA

developers to create their own Dockerfiles. Ideally, you want to avoid pulling images from Dockerhub because 1/ you don’t always know what is in the image and 2/ about -https://www.kennasecurity.com/blog/one-fifth-of-the-most-used-docker-containers-have-at-least-one-critical-vulnerability/[a -fifth] of the top 1000 images have vulnerabilities. A list of those +a +fifth of the top 1000 images have vulnerabilities. A list of those images and their vulnerabilities can be found -https://vulnerablecontainers.org/[here]. - -=== Add the USER directive to your Dockerfiles to run as a non-root user - -As was mentioned in the pod security section, you should avoid running +here.

+
+
+
+

16.1.11. Add the USER directive to your Dockerfiles to run as a non-root user

+
+

As was mentioned in the pod security section, you should avoid running container as root. While you can configure this as part of the podSpec, -it is a good habit to use the `+USER+` directive to your Dockerfiles. -The `+USER+` directive sets the UID to use when running `+RUN+`, -`+ENTRYPOINT+`, or `+CMD+` instruction that appears after the USER -directive. - -=== Lint your Dockerfiles - -Linting can be used to verify that your Dockerfiles are adhering to a -set of predefined guidelines, e.g. the inclusion of the `+USER+` +it is a good habit to use the USER directive to your Dockerfiles. +The USER directive sets the UID to use when running RUN, +ENTRYPOINT, or CMD instruction that appears after the USER +directive.

+
+
+
+

16.1.12. Lint your Dockerfiles

+
+

Linting can be used to verify that your Dockerfiles are adhering to a +set of predefined guidelines, e.g. the inclusion of the USER directive or the requirement that all images be tagged. -https://github.com/projectatomic/dockerfile_lint[dockerfile_lint] is an +dockerfile_lint is an open source project from RedHat that verifies common best practices and includes a rule engine that you can use to build your own rules for linting Dockerfiles. It can be incorporated into a CI pipeline, in that -builds with Dockerfiles that violate a rule will automatically fail. - -=== Build images from Scratch - -Reducing the attack surface of your container images should be primary +builds with Dockerfiles that violate a rule will automatically fail.

+
+
+
+

16.1.13. Build images from Scratch

+
+

Reducing the attack surface of your container images should be primary aim when building images. The ideal way to do this is by creating minimal images that are devoid of binaries that can be used to exploit vulnerabilities. Fortunately, Docker has a mechanism to create images from -https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch[`+scratch+`]. +scratch. With languages like Go, you can create a static linked binary and -reference it in your Dockerfile as in this example: - -[source,docker] ----- -############################ +reference it in your Dockerfile as in this example:

+
+
+
+
############################
 # STEP 1 build executable binary
 ############################
 FROM golang:alpine AS builder# Install git.
@@ -6768,23 +8293,28 @@ 

Reuse AWS SDK sessions with IRSA

############################ FROM scratch# Copy our static executable. COPY --from=builder /go/bin/hello /go/bin/hello# Run the hello binary. -ENTRYPOINT ["/go/bin/hello"] ----- - -This creates a container image that consists of your application and -nothing else, making it extremely secure. - -=== Use immutable tags with ECR - -https://aws.amazon.com/about-aws/whats-new/2019/07/amazon-ecr-now-supports-immutable-image-tags/[Immutable -tags] force you to update the image tag on each push to the image +ENTRYPOINT ["/go/bin/hello"]
+
+
+
+

This creates a container image that consists of your application and +nothing else, making it extremely secure.

+
+
+
+

16.1.14. Use immutable tags with ECR

+
+

Immutable +tags force you to update the image tag on each push to the image repository. This can thwart an attacker from overwriting an image with a malicious version without changing the image’s tags. Additionally, it -gives you a way to easily and uniquely identify an image. - -=== Sign your images, SBOMs, pipeline runs and vulnerability reports - -When Docker was first introduced, there was no cryptographic model for +gives you a way to easily and uniquely identify an image.

+
+
+
+

16.1.15. Sign your images, SBOMs, pipeline runs and vulnerability reports

+
+

When Docker was first introduced, there was no cryptographic model for verifying container images. With v2, Docker added digests to the image manifest. This allowed an image’s configuration to be hashed and for the hash to be used to generate an ID for the image. When image signing is @@ -6794,11 +8324,12 @@

Reuse AWS SDK sessions with IRSA

of the layer, ensuring that the content matches the content specified in the manifest. Image signing effectively allows you to create a secure supply chain, through the verification of digital signatures associated -with the image. - -We can use -https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html[AWS -Signer] or https://github.com/sigstore/cosign[Sigstore Cosign], to sign +with the image.

+
+
+

We can use +AWS +Signer or Sigstore Cosign, to sign container images, create attestations for SBOMs, vulnerability scan reports and pipeline run reports. These attestations assure the trustworthiness and integrity of the image, that it is in fact created @@ -6806,317 +8337,420 @@

Reuse AWS SDK sessions with IRSA

it contains only the software components that are documented (in the SBOM) that is verified and trusted by the image publisher. These attestations can be attached to the container image and pushed to the -repository. - -In the next section we will see how to use the attested artifacts for -audits and admissions controller verification. - -=== Image integrity verification using Kubernetes admission controller - -We can verify image signatures, attested artifacts in an automated way +repository.

+
+
+

In the next section we will see how to use the attested artifacts for +audits and admissions controller verification.

+
+
+
+

16.1.16. Image integrity verification using Kubernetes admission controller

+
+

We can verify image signatures, attested artifacts in an automated way before deploying the image to target Kubernetes cluster using -https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/[dynamic -admission controller] and admit deployments only when the security -metadata of the artifacts comply with the admission controller policies. - -For example we can write a policy that cryptographically verifies the +dynamic +admission controller and admit deployments only when the security +metadata of the artifacts comply with the admission controller policies.

+
+
+

For example we can write a policy that cryptographically verifies the signature of an image, an attested SBOM, attested pipeline run report, or attested CVE scan report. We can write conditions in the policy to check data in the report, e.g. a CVE scan should not have any critical CVEs. Deployment is allowed only for images that satisfy these conditions and all other deployments will be rejected by the admissions -controller. - -Examples of admission controller include: - -* https://kyverno.io/[Kyverno] -* https://github.com/open-policy-agent/gatekeeper[OPA Gatekeeper] -* https://github.com/IBM/portieris[Portieris] -* https://github.com/deislabs/ratify[Ratify] -* https://github.com/grafeas/kritis[Kritis] -* https://github.com/kelseyhightower/grafeas-tutorial[Grafeas tutorial] -* https://github.com/Shopify/voucher[Voucher] - -=== Update the packages in your container images - -You should include RUN `+apt-get update && apt-get upgrade+` in your +controller.

+
+
+

Examples of admission controller include:

+
+
+ +
+
+
+

16.1.17. Update the packages in your container images

+
+

You should include RUN apt-get update && apt-get upgrade in your Dockerfiles to upgrade the packages in your images. Although upgrading requires you to run as root, this occurs during image build phase. The application doesn’t need to run as root. You can install the updates and then switch to a different user with the USER directive. If your base image runs as a non-root user, switch to root and back; don’t solely rely on the maintainers of the base image to install the latest security -updates. - -Run `+apt-get clean+` to delete the installer files from -`+/var/cache/apt/archives/+`. You can also run -`+rm -rf /var/lib/apt/lists/*+` after installing packages. This removes +updates.

+
+
+

Run apt-get clean to delete the installer files from +/var/cache/apt/archives/. You can also run +rm -rf /var/lib/apt/lists/* after installing packages. This removes the index files or the lists of packages that are available to install. Be aware that these commands may be different for each package manager. -For example: - -[source,docker] ----- -RUN apt-get update && apt-get install -y \ +For example:

+
+
+
+
RUN apt-get update && apt-get install -y \
     curl \
     git \
     libsqlite3-dev \
-    && apt-get clean && rm -rf /var/lib/apt/lists/*
-----
-
-== Tools and resources
-
-* https://catalog.workshops.aws/eks-security-immersionday/en-US/12-image-security[Amazon
-EKS Security Immersion Workshop - Image Security]
-* https://github.com/docker-slim/docker-slim[docker-slim] Build secure
-minimal images
-* https://github.com/goodwithtech/dockle[dockle] Verifies that your
-Dockerfile aligns with best practices for creating secure images
-* https://github.com/projectatomic/dockerfile_lint[dockerfile-lint] Rule
-based linter for Dockerfiles
-* https://github.com/hadolint/hadolint[hadolint] A smart dockerfile
-linter
-* https://github.com/open-policy-agent/gatekeeper[Gatekeeper and OPA] A
-policy based admission controller
-* https://kyverno.io/[Kyverno] A Kubernetes-native policy engine
-* https://in-toto.io/[in-toto] Allows the user to verify if a step in
+    && apt-get clean && rm -rf /var/lib/apt/lists/*
+
+
+
+
+
+

16.2. Tools and resources

+
+
    +
  • +

    Amazon +EKS Security Immersion Workshop - Image Security

    +
  • +
  • +

    docker-slim Build secure +minimal images

    +
  • +
  • +

    dockle Verifies that your +Dockerfile aligns with best practices for creating secure images

    +
  • +
  • +

    dockerfile-lint Rule +based linter for Dockerfiles

    +
  • +
  • +

    hadolint A smart dockerfile +linter

    +
  • +
  • +

    Gatekeeper and OPA A +policy based admission controller

    +
  • +
  • +

    Kyverno A Kubernetes-native policy engine

    +
  • +
  • +

    in-toto Allows the user to verify if a step in the supply chain was intended to be performed, and if the step was -performed by the right actor -* https://github.com/theupdateframework/notary[Notary] A project for -signing container images -* https://github.com/notaryproject/nv2[Notary v2] -* https://grafeas.io/[Grafeas] An open artifact metadata API to audit -and govern your software supply chain -* https://www.suse.com/neuvector/[NeuVector by SUSE] open source, +performed by the right actor

    +
  • +
  • +

    Notary A project for +signing container images

    +
  • +
  • +

    Notary v2

    +
  • +
  • +

    Grafeas An open artifact metadata API to audit +and govern your software supply chain

    +
  • +
  • +

    NeuVector by SUSE open source, zero-trust container security platform, provides container, image and -registry scanning for vulnerabilities, secrets and compliance. - -:leveloffset: 1 -:leveloffset: +1 - -= Multi Account Strategy - -AWS recommends using a -https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi -account strategy] and AWS organizations to help isolate and manage your +registry scanning for vulnerabilities, secrets and compliance.

    +
  • +
+
+
+
+
+
+

17. Multi Account Strategy

+
+
+

AWS recommends using a +multi +account strategy and AWS organizations to help isolate and manage your business applications and data. There are -https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html[many -benefits] to using a multi account strategy: - -* Increased AWS API service quotas. Quotas are applied to AWS accounts, +many +benefits to using a multi account strategy:

+
+
+
    +
  • +

    Increased AWS API service quotas. Quotas are applied to AWS accounts, and using multiple accounts for your workloads increases the overall -quota available to your workloads. -* Simpler Identity and Access Management (IAM) policies. Granting +quota available to your workloads.

    +
  • +
  • +

    Simpler Identity and Access Management (IAM) policies. Granting workloads and the operators that support them access to only their own AWS accounts means less time crafting fine-grained IAM policies to -achieve the principle of least privilege. -* Improved Isolation of AWS resources. By design, all resources +achieve the principle of least privilege.

    +
  • +
  • +

    Improved Isolation of AWS resources. By design, all resources provisioned within an account are logically isolated from resources provisioned in other accounts. This isolation boundary provides you with a way to limit the risks of an application-related issue, misconfiguration, or malicious actions. If an issue occurs within one account, impacts to workloads contained in other accounts can be either -reduced or eliminated. -* More benefits, as described in the -https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html#group-workloads-based-on-business-purpose-and-ownership[AWS -Multi Account Strategy Whitepaper] - -The following sections will explain how to implement a multi account +reduced or eliminated.

    +
  • +
  • +

    More benefits, as described in the +AWS +Multi Account Strategy Whitepaper

    +
  • +
+
+
+

The following sections will explain how to implement a multi account strategy for your EKS workloads using either a centralized, or -de-centralized EKS cluster approach. - -== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters - -In a multi account AWS strategy, resources that belong to a given +de-centralized EKS cluster approach.

+
+
+

17.1. Planning for a Multi Workload Account Strategy for Multi Tenant Clusters

+
+

In a multi account AWS strategy, resources that belong to a given workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables are all created in an AWS account that contains all the resources for that workload. These are referred to as a workload account, and the EKS cluster is deployed into an account referred to as the cluster account. Cluster accounts will be explored in the next section. Deploying resources into a dedicated workload account is similar to deploying -kubernetes resources into a dedicated namespace. - -Workload accounts can then be further broken down by software +kubernetes resources into a dedicated namespace.

+
+
+

Workload accounts can then be further broken down by software development lifecycle or other requirements if appropriate. For example a given workload can have a production account, a development account, or accounts for hosting instances of that workload in a specific region. -https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-workload-oriented-ous.html[More -information] is available in this AWS whitepaper. - -You can adopt the following approaches when implementing EKS Multi -account strategy: - -== Centralized EKS Cluster - -In this approach, your EKS Cluster will be deployed in a single AWS -account called the `+Cluster Account+`. Using -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM -roles for Service Accounts (IRSA)] or -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] to deliver temporary AWS credentials and -https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to +More +information is available in this AWS whitepaper.

+
+
+

You can adopt the following approaches when implementing EKS Multi +account strategy:

+
+
+
+

17.2. Centralized EKS Cluster

+
+

In this approach, your EKS Cluster will be deployed in a single AWS +account called the Cluster Account. Using +IAM +roles for Service Accounts (IRSA) or +EKS +Pod Identities to deliver temporary AWS credentials and +AWS Resource Access Manager (RAM) to simplify network access, you can adopt a multi account strategy for your multi tenant EKS cluster. The cluster account will contain the VPC, subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and -any additional networking configurations needed to run your EKS cluster. - -In a multi workload account strategy for multi tenant cluster, AWS +any additional networking configurations needed to run your EKS cluster.

+
+
+

In a multi workload account strategy for multi tenant cluster, AWS accounts typically align with -https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes -namespaces] as a mechanism for isolating groups of resources. -link:/security/docs/multitenancy/[Best practices for tenant isolation] +kubernetes +namespaces as a mechanism for isolating groups of resources. +Best practices for tenant isolation within an EKS cluster should still be followed when implementing a multi -account strategy for multi tenant EKS clusters. - -It is possible to have multiple `+Cluster Accounts+` in your AWS +account strategy for multi tenant EKS clusters.

+
+
+

It is possible to have multiple Cluster Accounts in your AWS organization, and it is a best practice to have multiple -`+Cluster Accounts+` that align with your software development lifecycle +Cluster Accounts that align with your software development lifecycle needs. For workloads operating at a very large scale, you may require -multiple `+Cluster Accounts+` to ensure that there are enough kubernetes -and AWS service quotas available to all your workloads. - -[width="100%",cols="^100%",options="header",] -|=== -|image:./images/multi-account-eks.jpg[multi-account-eks] -|In the above diagram, AWS RAM is used to share subnets from a cluster +multiple Cluster Accounts to ensure that there are enough kubernetes +and AWS service quotas available to all your workloads.

+
+ +++ + + + + + + + + + + +
multi-account-eks

In the above diagram, AWS RAM is used to share subnets from a cluster account into a workload account. Then workloads running in EKS pods use IRSA or EKS Pod Identities and role chaining to assume a role in their -workload account and access their AWS resources. -|=== - -=== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster - -==== Sharing Subnets With AWS Resource Access Manager - -https://aws.amazon.com/ram/[AWS Resource Access Manager] (RAM) allows -you to share resources across AWS accounts. - -If -https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html#getting-started-sharing-orgs[RAM -is enabled for your AWS Organization], you can share the VPC Subnets +workload account and access their AWS resources.

+
+

17.2.1. Implementing a Multi Workload Account Strategy for Multi Tenant Cluster

+
+
Sharing Subnets With AWS Resource Access Manager
+
+

AWS Resource Access Manager (RAM) allows +you to share resources across AWS accounts.

+
+
+

If +RAM +is enabled for your AWS Organization, you can share the VPC Subnets from the Cluster account to your workload accounts. This will allow AWS resources owned by your workload accounts, such as -https://aws.amazon.com/elasticache/[Amazon ElastiCache] Clusters or -https://aws.amazon.com/rds/[Amazon Relational Database Service (RDS)] +Amazon ElastiCache Clusters or +Amazon Relational Database Service (RDS) Databases to be deployed into the same VPC as your EKS cluster, and be -consumable by the workloads running on your EKS cluster. - -To share a resource via RAM, open up RAM in the AWS console of the -cluster account and select "`Resource Shares`" and "`Create Resource -Share`". Name your Resource Share and Select the subnets you want to +consumable by the workloads running on your EKS cluster.

+
+
+

To share a resource via RAM, open up RAM in the AWS console of the +cluster account and select “Resource Shares” and “Create Resource +Share”. Name your Resource Share and Select the subnets you want to share. Select Next again and enter the 12 digit account IDs for the workload accounts you wish to share the subnets with, select next again, and click Create resource share to finish. After this step, the workload -account can deploy resources into those subnets. - -RAM shares can also be created programmatically, or with infrastructure -as code. - -==== Choosing Between EKS Pod Identities and IRSA - -At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of +account can deploy resources into those subnets.

+
+
+

RAM shares can also be created programmatically, or with infrastructure +as code.

+
+
+
+
Choosing Between EKS Pod Identities and IRSA
+
+

At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of delivering temporary AWS credentials to your pods on EKS. Both IRSA and EKS Pod Identities are valid methods for delivering temporary AWS credentials to your EKS pods and will continue to be supported. You -should consider which method of delivering best meets your needs. - -When working with a EKS cluster and multiple AWS accounts, IRSA can +should consider which method of delivering best meets your needs.

+
+
+

When working with a EKS cluster and multiple AWS accounts, IRSA can directly assume roles in AWS accounts other than the account the EKS cluster is hosted in directly, while EKS Pod identities require you to configure role chaining. Refer -https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html#service-accounts-iam[EKS -documentation] for an in-depth comparison. - -===== Accessing AWS API Resources with IAM Roles For Service Accounts - -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM -Roles for Service Accounts (IRSA)] allows you to deliver temporary AWS +EKS +documentation for an in-depth comparison.

+
+
+
Accessing AWS API Resources with IAM Roles For Service Accounts
+
+

IAM +Roles for Service Accounts (IRSA) allows you to deliver temporary AWS credentials to your workloads running on EKS. IRSA can be used to get temporary credentials for IAM roles in the workload accounts from the cluster account. This allows your workloads running on your EKS clusters in the cluster account to consume AWS API resources, such as S3 buckets hosted in the workload account seemlessly, and use IAM authentication -for resources like Amazon RDS Databases or Amazon EFS FileSystems. - -AWS API resources and other Resources that use IAM authentication in a +for resources like Amazon RDS Databases or Amazon EFS FileSystems.

+
+
+

AWS API resources and other Resources that use IAM authentication in a workload account can only be accessed by credentials for IAM roles in that same workload account, except where cross account access is capable -and has been explicity enabled. - -====== Enabling IRSA for cross account access - -To enable IRSA for workloads in your Cluster Account to access resources +and has been explicity enabled.

+
+
+Enabling IRSA for cross account access +
+

To enable IRSA for workloads in your Cluster Account to access resources in your Workload accounts, you first must create an IAM OIDC identity provider in your workload account. This can be done with the same procedure for setting up -https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html[IRSA], -except the Identity Provider will be created in the workload account. - -Then when configuring IRSA for your workloads on EKS, you can -https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html[follow -the same steps as the documentation], but use the -https://docs.aws.amazon.com/eks/latest/userguide/cross-account-access.html[12 -digit account id of the workload account] as mentioned in the section -"`Example Create an identity provider from another account’s cluster`". - -After this is configured, your application running in EKS will be able +IRSA, +except the Identity Provider will be created in the workload account.

+
+
+

Then when configuring IRSA for your workloads on EKS, you can +follow +the same steps as the documentation, but use the +12 +digit account id of the workload account as mentioned in the section +“Example Create an identity provider from another account’s cluster”.

+
+
+

After this is configured, your application running in EKS will be able to directly use its service account to assume a role in the workload -account, and use resources within it. - -===== Accessing AWS API Resources with EKS Pod Identities - -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] is a new way of delivering AWS credentials to your +account, and use resources within it.

+
+
+
+
+
Accessing AWS API Resources with EKS Pod Identities
+
+

EKS +Pod Identities is a new way of delivering AWS credentials to your workloads running on EKS. EKS pod identities simplifies the configuration of AWS resources as you no longer need to manage OIDC -configurations to deliver AWS credentials to your pods on EKS. - -====== Enabling EKS Pod Identities for cross account access - -Unlike IRSA, EKS Pod Identities can only be used to directly grant +configurations to deliver AWS credentials to your pods on EKS.

+
+
+Enabling EKS Pod Identities for cross account access +
+

Unlike IRSA, EKS Pod Identities can only be used to directly grant access to a role in the same account as the EKS cluster. To access a role in another AWS account, pods that use EKS Pod Identities must perform -https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining[Role -Chaining]. - -Role chaining can be configured in an applications profile with their +Role +Chaining.

+
+
+

Role chaining can be configured in an applications profile with their aws configuration file using the -https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process -Credentials Provider] available in various AWS SDKs. -`+credential_process+` can be used as a credential source when -configuring a profile, such as: - -[source,bash] ----- -# Content of the AWS Config file +Process +Credentials Provider available in various AWS SDKs. +credential_process can be used as a credential source when +configuring a profile, such as:

+
+
+
+
# Content of the AWS Config file
 [profile account_b_role]
 source_profile = account_a_role
 role_arn = arn:aws:iam::444455556666:role/account-b-role
 
 [profile account_a_role]
-credential_process = /eks-credential-processrole.sh
-----
-
-The source of the script called by credential_process:
-
-[source,bash]
-----
-#!/bin/bash
+credential_process = /eks-credential-processrole.sh
+
+
+
+

The source of the script called by credential_process:

+
+
+
+
#!/bin/bash
 # Content of the eks-credential-processrole.sh
 # This will retreive the credential from the pod identities agent,
 # and return it to the AWS SDK when referenced in a profile
-curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}'
-----
-
-You can create an aws config file as shown above with both Account A and
+curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}'
+
+
+
+

You can create an aws config file as shown above with both Account A and B roles and specify the AWS_CONFIG_FILE and AWS_PROFILE env vars in your pod spec. EKS Pod identity webhook does not override if the env vars -already exists in the pod spec. - -[source,yaml] ----- -# Snippet of the PodSpec +already exists in the pod spec.

+
+
+
+
# Snippet of the PodSpec
 containers:
   - name: container-name
     image: container-image:version
@@ -7124,43 +8758,48 @@ 

Reuse AWS SDK sessions with IRSA

- name: AWS_CONFIG_FILE value: path-to-customer-provided-aws-config-file - name: AWS_PROFILE - value: account_b_role ----- - -When configuring role trust policies for role chaining with EKS pod + value: account_b_role
+
+
+
+

When configuring role trust policies for role chaining with EKS pod identities, you can reference -https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html[EKS -specific attributes] as session tags and use attribute based access +EKS +specific attributes as session tags and use attribute based access control(ABAC) to limit access to your IAM roles to only specific EKS Pod identity sessions, such as the Kubernetes Service Account a pod belongs -to. - -Please note that some of these attributes may not be universally unique, +to.

+
+
+

Please note that some of these attributes may not be universally unique, for example two EKS clusters may have identical namespaces, and one cluster may have identically named service accounts across namespaces. So when granting access via EKS Pod Identities and ABAC, it is a best practice to always consider the cluster arn and namespace when granting -access to a service account. - -====== ABAC and EKS Pod Identities for cross account access - -When using EKS Pod Identities to assume roles (role chaining) in other +access to a service account.

+
+
+
+ABAC and EKS Pod Identities for cross account access +
+

When using EKS Pod Identities to assume roles (role chaining) in other accounts as part of a multi account strategy, you have the option to assign a unique IAM role for each service account that needs to access another account, or use a common IAM role across multiple service -accounts and use ABAC to control what accounts it can access. - -To use ABAC to control what service accounts can assume a role into +accounts and use ABAC to control what accounts it can access.

+
+
+

To use ABAC to control what service accounts can assume a role into another account with role chaining, you create a role trust policy statement that only allows a role to be assumed by a role session when the expected values are present. The following role trust policy will only let a role from the EKS cluster account (account ID 111122223333) -assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+` -and `+kubernetes-namespace+` tags all have the expected value. - -[source,json] ----- -{ +assume a role if the kubernetes-service-account, eks-cluster-arn +and kubernetes-namespace tags all have the expected value.

+
+
+
+
{
     "Version": "2012-10-17",
     "Statement": [
         {
@@ -7178,24 +8817,32 @@ 

Reuse AWS SDK sessions with IRSA

} } ] -} ----- - -When using this strategy it is a best practice to ensure that the common -IAM role only has `+sts:AssumeRole+` permissions and no other AWS -access. - -It is important when using ABAC that you control who has the ability to +}
+
+
+
+

When using this strategy it is a best practice to ensure that the common +IAM role only has sts:AssumeRole permissions and no other AWS +access.

+
+
+

It is important when using ABAC that you control who has the ability to tag IAM roles and users to only those who have a strict need to do so. Someone with the ability to tag an IAM role or user would be able to set tags on roles/users identical to what would be set by EKS Pod Identities and may be able to escalate their privileges. You can restrict who has -the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role -and users using IAM policy, or Service Control Policy (SCP). - -== De-centralized EKS Clusters - -In this approach, EKS clusters are deployed to respective workload AWS +the access to set tags the kubernetes- and eks- tags on IAM role +and users using IAM policy, or Service Control Policy (SCP).

+
+
+
+
+
+
+
+

17.3. De-centralized EKS Clusters

+
+

In this approach, EKS clusters are deployed to respective workload AWS Accounts and live along side with other AWS resources like Amazon S3 buckets, VPCs, Amazon DynamoDB tables, etc., Each workload account is independent, self-sufficient, and operated by respective Business @@ -7204,130 +8851,184 @@

Reuse AWS SDK sessions with IRSA

processing, General purpose, etc.,) and vend the clusters based on the application team requirements. Both application and platform teams operate out of their respective -https://www.weave.works/technologies/gitops/[GitOps] repositories to -manage the deployments to the workload clusters. - -[width="100%",cols="^100%",options="header",] -|=== -|image:./images/multi-account-eks-decentralized.png[De-centralized EKS -Cluster Architecture] -|In the above diagram, Amazon EKS clusters and other AWS resources are +GitOps repositories to +manage the deployments to the workload clusters.

+
+ +++ + + + + + + + + + + +
De-centralized EKS Cluster Architecture

In the above diagram, Amazon EKS clusters and other AWS resources are deployed to respective workload accounts. Then workloads running in EKS -pods use IRSA or EKS Pod Identities to access their AWS resources. -|=== - -GitOps is a way of managing application and infrastructure deployment so +pods use IRSA or EKS Pod Identities to access their AWS resources.

+
+

GitOps is a way of managing application and infrastructure deployment so that the whole system is described declaratively in a Git repository. It’s an operational model that offers you the ability to manage the state of multiple Kubernetes clusters using the best practices of version control, immutable artifacts, and automation. In this multi cluster model, each workload cluster is bootstrapped with multiple Git repos, allowing each team (application, platform, security, etc.,) to -deploy their respective changes on the cluster. - -You would utilize -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM -roles for Service Accounts (IRSA)] or -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] in each account to allow your EKS workloads to get +deploy their respective changes on the cluster.

+
+
+

You would utilize +IAM +roles for Service Accounts (IRSA) or +EKS +Pod Identities in each account to allow your EKS workloads to get temporary aws credentials to securely access other AWS resources. IAM roles are created in respective workload AWS Accounts and map them to k8s service accounts to provide temporary IAM access. So, no cross-account access is required in this approach. Follow the -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM -roles for Service Accounts] documentation on how to setup in each +IAM +roles for Service Accounts documentation on how to setup in each workload for IRSA, and -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] documentation on how to setup EKS pod identities in each -account. - -=== Centralized Networking - -You can also utilize AWS RAM to share the VPC Subnets to workload +EKS +Pod Identities documentation on how to setup EKS pod identities in each +account.

+
+
+

17.3.1. Centralized Networking

+
+

You can also utilize AWS RAM to share the VPC Subnets to workload accounts and launch Amazon EKS clusters and other AWS resources in them. This enables centralized network managment/administration, simplified network connectivity, and de-centralized EKS clusters. Refer this -https://aws.amazon.com/blogs/containers/use-shared-vpcs-in-amazon-eks/[AWS -blog] for a detailed walkthrough and considerations of this approach. - -[width="100%",cols="^100%",options="header",] -|=== -|image:./images/multi-account-eks-shared-subnets.png[De-centralized EKS -Cluster Architecture using VPC Shared Subnets] -|In the above diagram, AWS RAM is used to share subnets from a central +AWS +blog for a detailed walkthrough and considerations of this approach.

+
+ +++ + + + + + + + + + + +
De-centralized EKS Cluster Architecture using VPC Shared Subnets

In the above diagram, AWS RAM is used to share subnets from a central networking account into a workload account. Then EKS cluster and other AWS resources are launched in those subnets in respective workload accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS -resources. -|=== - -== Centralized vs De-centralized EKS clusters - -The decision to run with a Centralized or De-centralized will depend on +resources.

+
+
+
+

17.4. Centralized vs De-centralized EKS clusters

+
+

The decision to run with a Centralized or De-centralized will depend on your requirements. This table demonstrates the key differences with each -strategy. - -[width="100%",cols="<34%,<33%,<33%",options="header",] -|=== -|# |Centralized EKS cluster |De-centralized EKS clusters -|Cluster Management: |Managing a single EKS cluster is easier than -administrating multiple clusters |An Efficient cluster management +strategy.

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#Centralized EKS clusterDe-centralized EKS clusters

Cluster Management:

Managing a single EKS cluster is easier than +administrating multiple clusters

An Efficient cluster management automation is necessary to reduce the operational overhead of managing -multiple EKS clusters - -|Cost Efficiency: |Allows reuse of EKS cluster and network resources, -which promotes cost efficiency |Requires networking and cluster setups -per workload, which requires additional resources - -|Resilience: |Multiple workloads on the centralized cluster may be -impacted if a cluster becomes impaired |If a cluster becomes impaired, +multiple EKS clusters

Cost Efficiency:

Allows reuse of EKS cluster and network resources, +which promotes cost efficiency

Requires networking and cluster setups +per workload, which requires additional resources

Resilience:

Multiple workloads on the centralized cluster may be +impacted if a cluster becomes impaired

If a cluster becomes impaired, the damage is limited to only the workloads that run on that cluster. -All other workloads are unaffected - -|Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using -k8s native constructs like `+Namespaces+`. Workloads may share the +All other workloads are unaffected

Isolation & Security:

Isolation/Soft Multi-tenancy is achieved using +k8s native constructs like Namespaces. Workloads may share the underlying resources like CPU, memory, etc. AWS resources are isolated into their own workload accounts which by default are not accessible -from other AWS accounts. |Stronger isolation on compute resources as the +from other AWS accounts.

Stronger isolation on compute resources as the workloads run in individual clusters and nodes that don’t share any resources. AWS resources are isolated into their own workload accounts -which by default are not accessible from other AWS accounts. - -|Performance & Scalabity: |As workloads grow to very large scales you +which by default are not accessible from other AWS accounts.

Performance & Scalabity:

As workloads grow to very large scales you may encounter kubernetes and AWS service quotas in the cluster account. -You can deploy addtional cluster accounts to scale even further |As more +You can deploy addtional cluster accounts to scale even further

As more clusters and VPCs are present, each workload has more available k8s and -AWS service quota - -|Networking: |Single VPC is used per cluster, allowing for simpler -connectivity for applications on that cluster |Routing must be -established between the de-centralized EKS cluster VPCs - -|Kubernetes Access Management: |Need to maintain many different roles +AWS service quota

Networking:

Single VPC is used per cluster, allowing for simpler +connectivity for applications on that cluster

Routing must be +established between the de-centralized EKS cluster VPCs

Kubernetes Access Management:

Need to maintain many different roles and users in the cluster to provide access to all workload teams and -ensure kubernetes resources are properly segregated |Simplified access -management as each cluster is dedicated to a workload/team - -|AWS Access Management: |AWS resources are deployed into to their own +ensure kubernetes resources are properly segregated

Simplified access +management as each cluster is dedicated to a workload/team

AWS Access Management:

AWS resources are deployed into to their own account which can only be accessed by default with IAM roles in the workload account. IAM roles in the workload accounts are assumed cross -account either with IRSA or EKS Pod Identities. |AWS resources are +account either with IRSA or EKS Pod Identities.

AWS resources are deployed into to their own account which can only be accessed by default with IAM roles in the workload account. IAM roles in the workload -accounts are delivered directly to pods with IRSA or EKS Pod Identities -|=== - -:leveloffset: 1 - - - +accounts are delivered directly to pods with IRSA or EKS Pod Identities

diff --git a/latest/bpg/security/multiaccount.adoc b/latest/bpg/security/multiaccount.adoc index 4d18ad90d..17b1064d0 100644 --- a/latest/bpg/security/multiaccount.adoc +++ b/latest/bpg/security/multiaccount.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[multi-account-strategy,multi-account-strategy.title]] = Multi Account Strategy +:info_doctype: section +:info_title: Multi Account Strategy +:info_abstract: Multi Account Strategy +:info_titleabbrev: Multi Account Strategy +:imagesdir: images/ AWS recommends using a https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi diff --git a/latest/bpg/security/multitenancy.adoc b/latest/bpg/security/multitenancy.adoc index 8cf35ece2..a586aeebb 100644 --- a/latest/bpg/security/multitenancy.adoc +++ b/latest/bpg/security/multitenancy.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[tenant-isolation,tenant-isolation.title]] = Tenant Isolation +:info_doctype: section +:info_title: Tenant Isolation +:info_abstract: Tenant Isolation +:info_titleabbrev: Tenant Isolation +:imagesdir: images/ When we think of multi-tenancy, we often want to isolate a user or application from other users or applications running on a shared diff --git a/latest/bpg/security/network.adoc b/latest/bpg/security/network.adoc index c473a9a6d..195025dcb 100644 --- a/latest/bpg/security/network.adoc +++ b/latest/bpg/security/network.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[network-security,network-security.title]] = Network security +:info_doctype: section +:info_title: Network security +:info_abstract: Network security +:info_titleabbrev: Network security +:imagesdir: images/ Network security has several facets. The first involves the application of rules which restrict the flow of network traffic between services. diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc index c29559002..2582f59a1 100644 --- a/latest/bpg/security/pods.adoc +++ b/latest/bpg/security/pods.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[pod-security,pod-security.title]] = Pod Security +:info_doctype: section +:info_title: Pod Security +:info_abstract: Pod Security +:info_titleabbrev: Pod Security +:imagesdir: images/ The pod specification includes a variety of different attributes that can strengthen or weaken your overall security posture. As a Kubernetes diff --git a/latest/bpg/security/process_adoc.sh b/latest/bpg/security/process_adoc.sh index 08fd9846f..570c76bae 100755 --- a/latest/bpg/security/process_adoc.sh +++ b/latest/bpg/security/process_adoc.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Function to convert string to lowercase and replace spaces with hyphens +format_string() { + echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/ /-/g' +} + # Loop through all .adoc files in the current directory for file in *.adoc; do # Skip index.adoc @@ -9,12 +14,15 @@ for file in *.adoc; do # Get the title from the first line of the file title=$(head -n 1 "$file" | sed 's/^= //') + # Format the title for use inside square brackets + formatted_title=$(format_string "$title") + # Create the new header (using a heredoc to preserve formatting) read -r -d '' new_header << EOM //!!NODE_ROOT
-**[."topic"]** -[[${title},${title}.title]] -**= ${title}** +[."topic"] +[[${formatted_title},${formatted_title}.title]] += ${title} :info_doctype: section :info_title: ${title} :info_abstract: ${title} diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc index 73f59b2f6..5486d60bd 100644 --- a/latest/bpg/security/runtime.adoc +++ b/latest/bpg/security/runtime.adoc @@ -1,4 +1,12 @@ +//!!NODE_ROOT
+[."topic"] +[[runtime-security,runtime-security.title]] = Runtime security +:info_doctype: section +:info_title: Runtime security +:info_abstract: Runtime security +:info_titleabbrev: Runtime security +:imagesdir: images/ Runtime security provides active protection for your containers while they’re running. The idea is to detect and/or prevent malicious activity diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py new file mode 100644 index 000000000..f33f77c7d --- /dev/null +++ b/latest/bpg/security/test.py @@ -0,0 +1,135 @@ +import subprocess +import re +import os +import time +import shutil +from dataclasses import dataclass +from typing import List, Tuple + +@dataclass +class Section: + level: int + title: str + content: str + start_line: int + end_line: int + +def run_build(content: str, test_description: str) -> bool: + print(f"\nTesting: {test_description}") + print("Building... (this may take about 30 seconds)") + start_time = time.time() + + if not os.path.exists('iam.adoc.backup'): + shutil.copy2('iam.adoc', 'iam.adoc.backup') + + with open('iam.adoc', 'w') as f: + f.write(content) + + try: + result = subprocess.run(["eda", "build", "brazil-build", "release", "-Dtype=html"], capture_output=True, text=True) + end_time = time.time() + success = result.returncode == 0 + print(f"Build {'succeeded' if success else 'failed'} in {end_time - start_time:.2f} seconds") + return success + finally: + shutil.copy2('iam.adoc.backup', 'iam.adoc') + +def parse_sections(content: str) -> List[Section]: + print("\nParsing AsciiDoc sections...") + lines = content.split('\n') + sections = [] + current_section = None + for i, line in enumerate(lines): + match = re.match(r'^(=+)\s+(.+)$', line) + if match: + if current_section: + current_section.end_line = i - 1 + sections.append(current_section) + level = len(match.group(1)) + title = match.group(2) + current_section = Section(level, title, '', i, -1) + elif current_section: + current_section.content += line + '\n' + if current_section: + current_section.end_line = len(lines) - 1 + sections.append(current_section) + print(f"Found {len(sections)} sections") + return sections + +def bisect_problematic_sections(sections: List[Section]) -> List[Section]: + print("\nStarting bisection search for problematic sections...") + all_content = '\n'.join(section.content for section in sections) + + if run_build(all_content, "Full document"): + print("Full document builds successfully. No problematic sections identified.") + return [] + + def bisect_recursive(start: int, end: int) -> List[Section]: + if start == end: + return [sections[start]] + + mid = (start + end) // 2 + first_half = '\n'.join(section.content for section in sections[start:mid+1]) + second_half = '\n'.join(section.content for section in sections[mid+1:end+1]) + + problematic_sections = [] + + if not run_build(first_half, f"First half (sections {start+1}-{mid+1})"): + problematic_sections.extend(bisect_recursive(start, mid)) + + if not run_build(second_half, f"Second half (sections {mid+2}-{end+1})"): + problematic_sections.extend(bisect_recursive(mid+1, end)) + + return problematic_sections + + return bisect_recursive(0, len(sections) - 1) + +def suggest_fixes(section: Section) -> List[str]: + print(f"\nAnalyzing section: {section.title}") + suggestions = [] + + if re.search(r'\[.*\]', section.content) and not re.search(r'\[.*\]\n', section.content): + suggestions.append("Ensure all attribute lists are on their own line") + + if re.search(r'[^=]=+[^=]', section.content): + suggestions.append("Check for misplaced section headers or formatting issues with '=' characters") + + if re.search(r'[^`]`[^`]+`[^`]', section.content): + suggestions.append("Ensure all inline code blocks use matching backticks") + + if re.search(r'\{[^}]+\}', section.content): + suggestions.append("Check for unclosed or mismatched curly braces in attribute references") + + print(f"Found {len(suggestions)} potential issues") + return suggestions + +def main(): + print("Starting AsciiDoc debugging process...") + with open('iam.adoc', 'r') as f: + content = f.read() + + sections = parse_sections(content) + problematic_sections = bisect_problematic_sections(sections) + + if problematic_sections: + print("\nResults:") + print("The following sections may be causing issues:") + for section in problematic_sections: + print(f"\nSection: {section.title} (lines {section.start_line + 1}-{section.end_line + 1})") + print("First few lines of the section:") + print('\n'.join(section.content.split('\n')[:5])) + print("...") + + suggestions = suggest_fixes(section) + if suggestions: + print("Suggestions for fixing this section:") + for suggestion in suggestions: + print(f"- {suggestion}") + else: + print("\nNo specific problematic sections identified. The issue may be more complex or involve interactions between multiple sections.") + + print("\nDebugging process completed.") + print("Note: The original 'iam.adoc' file has been restored.") + +if __name__ == "__main__": + main() \ No newline at end of file From 0c5343428311d2d3d980f8782fc0b43056a7d5d0 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 26 Jun 2024 23:19:08 +0000 Subject: [PATCH 10/56] fixup --- content/security/docs/iam.md | 4 ++-- latest/bpg/book.adoc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/content/security/docs/iam.md b/content/security/docs/iam.md index 41eff6a09..658895a25 100644 --- a/content/security/docs/iam.md +++ b/content/security/docs/iam.md @@ -447,10 +447,10 @@ This particular token grants the Pod view-only privileges to S3 by assuming an I "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { - "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1", + "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", - "AccessKeyId": "XXXX36C6WWEJUMHA3L7Z" + "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } } ``` diff --git a/latest/bpg/book.adoc b/latest/bpg/book.adoc index 640ecae82..345f9c6d8 100644 --- a/latest/bpg/book.adoc +++ b/latest/bpg/book.adoc @@ -38,4 +38,6 @@ include::autoscaling/index.adoc[leveloffset=+1] include::reliability/index.adoc[leveloffset=+1] +include::security/index.adoc[leveloffset=+1] + From 6282c341500daaa1e4642b560d80d7d0c90655f2 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 20:02:44 +0000 Subject: [PATCH 11/56] fixup --- latest/bpg/security/hosts.adoc | 1 + latest/bpg/security/iam.adoc | 6 ++++-- latest/bpg/security/index.adoc | 4 ++-- latest/bpg/security/network.adoc | 13 ++++++++----- latest/bpg/security/pods.adoc | 4 ++-- latest/bpg/security/runtime.adoc | 7 ++++--- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index aae930a56..8d649880a 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -210,6 +210,7 @@ Fargate pods. == Alternatives +[[iam-se-linux,iam-se-linux.title]] === Run SELinux !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index 46db7be1f..6cb5c6be0 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -363,6 +363,7 @@ access the Kubernetes API. If you need to grant an IAM user access to an EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user that maps to a specific Kubernetes RBAC group. +[[iam-cluster-creator,iam-cluster-creator.title]] === Remove the cluster-admin permissions from the cluster creator principal By default Amazon EKS clusters are created with a permanent @@ -471,7 +472,7 @@ user that creates the cluster, is automatically granted `+system:masters+` permissions in the cluster’s RBAC configuration. Even being a best practice to remove this permission, as described -link:#remove-the-cluster-admin-permissions-from-the-cluster-creator-principal[here] +xref:iam-cluster-creator[here] if using the `+CONFIG_MAP+` authentication method, relying on `+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a good idea to create the cluster with an infrastructure automation @@ -739,7 +740,7 @@ validating the token’s signature, IAM exchanges the Kubernetes issued token for a temporary AWS role credential. When using IRSA, it is important to -link:#reuse-aws-sdk-sessions-with-irsa[reuse AWS SDK sessions] to avoid +xref:iam-reuse-sessions[reuse AWS SDK sessions] to avoid unneeded calls to AWS STS. Decoding the (JWT) token for IRSA will produce output similar to the @@ -1357,6 +1358,7 @@ section in the above editor screen. Repeat the same steps for system:basic-user ClusterRoleBinding. +[[iam-reuse-sessions,iam-reuse-sessions.title]] === Reuse AWS SDK sessions with IRSA When you use IRSA, applications written using the AWS SDK use the token diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 22af75f39..0dd90c72a 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -141,8 +141,8 @@ practices that align with DevOps processes and agile methodologies. https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] -include::iam.adoc[leveloffset=+1] -//include::pods.adoc[leveloffset=+1] ISSUES +include::iam.adoc[leveloffset=+1] STILL ISSUES +//include::pods.adoc[leveloffset=+1] STILL ISSUES //include::multitenancy.adoc[leveloffset=+1] ISSUES include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] diff --git a/latest/bpg/security/network.adoc b/latest/bpg/security/network.adoc index 195025dcb..c51b35687 100644 --- a/latest/bpg/security/network.adoc +++ b/latest/bpg/security/network.adoc @@ -27,6 +27,7 @@ but often include the following items: * Nitro Instances * ACM Private CA with cert-manager +[[iam-network-policy,iam-network-policy.title]] == Network policy Within a Kubernetes cluster, all Pod to Pod communication is allowed by @@ -192,8 +193,7 @@ exists before onboarding application pods. This policy denies onboarding k8s pods with a label `+k8s-app: sample-app+` if corresponding network policy does not exist. -[source,javascript] ----- +``` package kubernetes.admission import data.kubernetes.networkpolicies @@ -208,7 +208,8 @@ deny[msg] { contains_label(arr, val) { arr[_] == val } ----- +``` + === Troubleshooting @@ -666,6 +667,7 @@ do I terminate HTTPS traffic on Amazon EKS workloads with ACM?] !!! attention Some Ingresses, like the AWS LB controller, implement the SSL/TLS using Annotations instead of as part of the Ingress Spec. +[[iam-cert-manager,iam-cert-manager.title]] === ACM Private CA with cert-manager You can enable TLS and mTLS to secure your EKS application workloads at @@ -682,6 +684,7 @@ keys encoded in memory (less secure). A centralized CA also gives you more control and improved auditability for private certificates both inside and outside of a Kubernetes environment. +[[iam-ca-mode,iam-ca-mode.title]] ==== Short-Lived CA Mode for Mutual TLS Between Workloads When using ACM Private CA for mTLS in EKS, it is recommended that you @@ -775,7 +778,7 @@ control plane (specifically `+istiod+`) from functioning as the root Certificate Authority (CA), and configure ACM Private CA as the root CA for mTLS between workloads. If you’re going with this approach, consider using the _short-lived CA mode_ in ACM Private CA. Refer to the -link:#short-lived-ca-mode-for-mutual-tls-between-workloads[previous +xref:iam-ca-mode[previous section] and this https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode[blog post] for more details. @@ -842,7 +845,7 @@ Certificate Signing Requests with istio-csr] [arabic] . Start by following the same -link:#acm-private-ca-with-cert-manager[setup instructions in this +xref:iam-cert-manager[setup instructions in this section] to complete the following: . Create a Private CA . Install cert-manager diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc index 2582f59a1..4f4a000a3 100644 --- a/latest/bpg/security/pods.adoc +++ b/latest/bpg/security/pods.adoc @@ -730,7 +730,7 @@ network access to the Kubernetes API. To prevent a pod from having any network access to the Kubernetes API, you will need to modify the https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS cluster endpoint access] and use a -link:../network/#network-policy[NetworkPolicy] to block pod access. +xref:iam-network-policy[NetworkPolicy] to block pod access. [source,yaml] ---- @@ -773,7 +773,7 @@ An attacker can still enumerate services in a cluster by reaching the in-cluster DNS service. (ex: `+dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP+`) To prevent in-cluster service discovery, use a -link:../network/#network-policy[NetworkPolicy] to block pod access +xref:iam-network-policy[NetworkPolicy] to block pod access [source,yaml] ---- diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc index 5486d60bd..7d2f6eb15 100644 --- a/latest/bpg/security/runtime.adoc +++ b/latest/bpg/security/runtime.adoc @@ -81,7 +81,7 @@ It’s also possible to create your own profiles for things that require additional privileges. This can be very tedious to do manually, but there are tools like https://github.com/inspektor-gadget/inspektor-gadget[Inspektor Gadget] -(also recommended in the link:../network/[network security section] for +(also recommended in the xref:network-security[network security section] for generating network policies) and https://github.com/inspektor-gadget/inspektor-gadget[Security Profiles Operator] that support using tools like eBPF or logs to record baseline @@ -98,7 +98,7 @@ different APIs and abilities, allowing access control for e.g. specific filesystem paths or network ports. Support for these tools depends on the Linux distribution, with Debian/Ubuntu supporting AppArmor and RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see -the link:../hosts/#run-selinux[infrastructure security section] for +the xref:iam-se-linux[infrastructure security section] for further discussion of SELinux. Both AppArmor and SELinux are integrated with Kubernetes, but as of @@ -154,7 +154,7 @@ become proficient, consider using a 3rd party commercial solution. A lot of them have moved beyond static profiles like Apparmor and seccomp and have begun using machine learning to block or alert on suspicious activity. A handful of these solutions can be found below in the -link:#tools-and-resources[tools] section. Additional options can be +xref:iam-tools[tools] section. Additional options can be found on the https://aws.amazon.com/marketplace/features/containers[AWS Marketplace for Containers]. @@ -196,6 +196,7 @@ including the full collection of https://kubernetes.io/docs/concepts/security/pod-security-standards/[Pod Security Standards]. +[[iam-tools,iam-tools.title]] == Tools and Resources * https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6[7 From 8a2010eced93df95f6cb52164fc04ee4f7a41478 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 20:17:58 +0000 Subject: [PATCH 12/56] fixup --- latest/bpg/security/iam.adoc | 6 +++--- latest/bpg/security/index.adoc | 2 +- latest/bpg/security/test.py | 20 +++++++++++--------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index 6cb5c6be0..cd18127de 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -472,7 +472,7 @@ user that creates the cluster, is automatically granted `+system:masters+` permissions in the cluster’s RBAC configuration. Even being a best practice to remove this permission, as described -xref:iam-cluster-creator[here] +xref:iam-cluster-creator][here] if using the `+CONFIG_MAP+` authentication method, relying on `+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a good idea to create the cluster with an infrastructure automation @@ -509,7 +509,7 @@ like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine the roles bound to a particular service account, user, or group. We’ll explore this topic further when we get to the section on -link:detective.md[auditing]. Additional ideas can be found in this +xref:auditing-and-logging[auditing]. Additional ideas can be found in this https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] from NCC Group. @@ -740,7 +740,7 @@ validating the token’s signature, IAM exchanges the Kubernetes issued token for a temporary AWS role credential. When using IRSA, it is important to -xref:iam-reuse-sessions[reuse AWS SDK sessions] to avoid +xref:iam-reuse-sessions,[reuse AWS SDK sessions] to avoid unneeded calls to AWS STS. Decoding the (JWT) token for IRSA will produce output similar to the diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 0dd90c72a..c2940c7b6 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -141,7 +141,7 @@ practices that align with DevOps processes and agile methodologies. https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] -include::iam.adoc[leveloffset=+1] STILL ISSUES +include::iam.adoc[leveloffset=+1] //include::pods.adoc[leveloffset=+1] STILL ISSUES //include::multitenancy.adoc[leveloffset=+1] ISSUES include::detective.adoc[leveloffset=+1] diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index f33f77c7d..9bc207ae3 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -14,7 +14,7 @@ class Section: start_line: int end_line: int -def run_build(content: str, test_description: str) -> bool: +def run_build(header: str, content: str, test_description: str) -> bool: print(f"\nTesting: {test_description}") print("Building... (this may take about 30 seconds)") start_time = time.time() @@ -23,7 +23,7 @@ def run_build(content: str, test_description: str) -> bool: shutil.copy2('iam.adoc', 'iam.adoc.backup') with open('iam.adoc', 'w') as f: - f.write(content) + f.write(header + content) try: result = subprocess.run(["eda", "build", "brazil-build", "release", "-Dtype=html"], capture_output=True, text=True) @@ -56,11 +56,11 @@ def parse_sections(content: str) -> List[Section]: print(f"Found {len(sections)} sections") return sections -def bisect_problematic_sections(sections: List[Section]) -> List[Section]: +def bisect_problematic_sections(header: str, sections: List[Section]) -> List[Section]: print("\nStarting bisection search for problematic sections...") all_content = '\n'.join(section.content for section in sections) - if run_build(all_content, "Full document"): + if run_build(header, all_content, "Full document"): print("Full document builds successfully. No problematic sections identified.") return [] @@ -74,10 +74,10 @@ def bisect_recursive(start: int, end: int) -> List[Section]: problematic_sections = [] - if not run_build(first_half, f"First half (sections {start+1}-{mid+1})"): + if not run_build(header, first_half, f"First half (sections {start+1}-{mid+1})"): problematic_sections.extend(bisect_recursive(start, mid)) - if not run_build(second_half, f"Second half (sections {mid+2}-{end+1})"): + if not run_build(header, second_half, f"Second half (sections {mid+2}-{end+1})"): problematic_sections.extend(bisect_recursive(mid+1, end)) return problematic_sections @@ -106,16 +106,18 @@ def suggest_fixes(section: Section) -> List[str]: def main(): print("Starting AsciiDoc debugging process...") with open('iam.adoc', 'r') as f: - content = f.read() + lines = f.readlines() + header = ''.join(lines[:10]) + content = ''.join(lines[10:]) sections = parse_sections(content) - problematic_sections = bisect_problematic_sections(sections) + problematic_sections = bisect_problematic_sections(header, sections) if problematic_sections: print("\nResults:") print("The following sections may be causing issues:") for section in problematic_sections: - print(f"\nSection: {section.title} (lines {section.start_line + 1}-{section.end_line + 1})") + print(f"\nSection: {section.title} (lines {section.start_line + 11}-{section.end_line + 11})") print("First few lines of the section:") print('\n'.join(section.content.split('\n')[:5])) print("...") From 0b7d053636b522dc4a956aa7d456de5ec9576a9d Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 20:52:32 +0000 Subject: [PATCH 13/56] iam.adoc is working --- latest/bpg/security/iam.adoc | 304 ++++++++++++++-------------- latest/bpg/security/iam.adoc.backup | 106 +++++----- 2 files changed, 204 insertions(+), 206 deletions(-) diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index cd18127de..38022aec5 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -13,7 +13,7 @@ and Access Management] (IAM) is an AWS service that performs two essential functions: Authentication and Authorization. Authentication involves the verification of a identity whereas authorization governs the actions that can be performed by AWS resources. Within AWS, a -resource can be another AWS service, e.g. EC2, or an AWS +resource can be another AWS service, e.g. EC2, or an AWS https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal[principal] such as an https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-users[IAM @@ -27,7 +27,7 @@ policies]. == Controlling Access to EKS Clusters The Kubernetes project supports a variety of different strategies to -authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, +authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, X.509 certificates, OIDC, etc. EKS currently has native support for https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication[webhook token authentication], @@ -37,12 +37,12 @@ account tokens], and as of February 21, 2021, OIDC authentication. The webhook authentication strategy calls a webhook that verifies bearer tokens. On EKS, these bearer tokens are generated by the AWS CLI or the https://github.com/kubernetes-sigs/aws-iam-authenticator[aws-iam-authenticator] -client when you run `+kubectl+` commands. As you execute commands, the +client when you run `kubectl` commands. As you execute commands, the token is passed to the kube-apiserver which forwards it to the authentication webhook. If the request is well-formed, the webhook calls -a pre-signed URL embedded in the token’s body. This URL validates the -request’s signature and returns information about the user, e.g. the -user’s account, Arn, and UserId to the kube-apiserver. +a pre-signed URL embedded in the token's body. This URL validates the +request's signature and returns information about the user, e.g. the +user's account, Arn, and UserId to the kube-apiserver. To manually generate a authentication token, type the following command in a terminal window: @@ -90,7 +90,7 @@ The output should resemble this: } ---- -Each token starts with `+k8s-aws-v1.+` followed by a base64 encoded +Each token starts with `k8s-aws-v1.` followed by a base64 encoded string. The string, when decoded, should resemble to something similar to this: @@ -105,15 +105,15 @@ https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. The token has a time to live (TTL) of 15 minutes after which a new token will need to be generated. This is handled automatically when you use a -client like `+kubectl+`, however, if you’re using the Kubernetes +client like `kubectl`, however, if you're using the Kubernetes dashboard, you will need to generate a new token and re-authenticate each time the token expires. -Once the user’s identity has been authenticated by the AWS IAM service, -the kube-apiserver reads the `+aws-auth+` ConfigMap in the -`+kube-system+` Namespace to determine the RBAC group to associate with -the user. The `+aws-auth+` ConfigMap is used to create a static mapping -between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC +Once the user's identity has been authenticated by the AWS IAM service, +the kube-apiserver reads the `aws-auth` ConfigMap in the +`kube-system` Namespace to determine the RBAC group to associate with +the user. The `aws-auth` ConfigMap is used to create a static mapping +between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC groups. RBAC groups can be referenced in Kubernetes RoleBindings or ClusterRoleBindings. They are similar to IAM Roles in that they define a set of actions (verbs) that can be performed against a collection of @@ -126,10 +126,10 @@ IAM principals to Amazon EKS clusters, is a functionality of the AWS API and is an opt-in feature for EKS v1.23 and later clusters (new or existing). It simplifies identity mapping between AWS IAM and Kubernetes RBACs, eliminating the need to switch between AWS and Kubernetes APIs or -editing the `+aws-auth+` ConfigMap for access management, reducing +editing the `aws-auth` ConfigMap for access management, reducing operational overhead, and helping address misconfigurations. The tool also enables cluster administrators to revoke or refine -`+cluster-admin+` permissions automatically granted to the AWS IAM +`cluster-admin` permissions automatically granted to the AWS IAM principal used to create the cluster. This API relies on two concepts: @@ -150,23 +150,23 @@ ____ Cluster Access Manager allows the combination of upstream RBAC with Access Policies supporting allow and pass (but not deny) on Kubernetes AuthZ decisions regarding API server requests. A deny decision will -happen when both, the upstream RBAC and Amazon EKS authorizers can’t +happen when both, the upstream RBAC and Amazon EKS authorizers can't determine the outcome of a request evaluation. With this feature, Amazon EKS supports three modes of authentication: [arabic] -. `+CONFIG_MAP+` to continue using `+aws-auth+` configMap exclusively. -. `+API_AND_CONFIG_MAP+` to source authenticated IAM principals from -both EKS Access Entry APIs and the `+aws-auth+` configMap, prioritizing -the Access Entries. Ideal to migrate existing `+aws-auth+` permissions +. `CONFIG_MAP` to continue using `aws-auth` configMap exclusively. +. `API_AND_CONFIG_MAP` to source authenticated IAM principals from +both EKS Access Entry APIs and the `aws-auth` configMap, prioritizing +the Access Entries. Ideal to migrate existing `aws-auth` permissions to Access Entries. -. `+API+` to exclusively rely on EKS Access Entry APIs. This is the new +. `API` to exclusively rely on EKS Access Entry APIs. This is the new *recommended approach*. To get started, cluster administrators can create or update Amazon EKS -clusters, setting the preferred authentication to `+API_AND_CONFIG_MAP+` -or `+API+` method and define Access Entries to grant access the desired +clusters, setting the preferred authentication to `API_AND_CONFIG_MAP` +or `API` method and define Access Entries to grant access the desired AWS IAM principals. [source,bash] @@ -183,12 +183,12 @@ The above command is an example to create an Amazon EKS cluster already without the admin permissions of the cluster creator. It is possible to update Amazon EKS clusters configuration to enable -`+API+` authenticationMode using the `+update-cluster-config+` command, -to do that on existing clusters using `+CONFIG_MAP+` you will have to -first update to `+API_AND_CONFIG_MAP+` and then to `+API+`. *These -operations cannot be reverted*, meaning that’s not possible to switch -from `+API+` to `+API_AND_CONFIG_MAP+` or `+CONFIG_MAP+`, and also from -`+API_AND_CONFIG_MAP+` to `+CONFIG_MAP+`. +`API` authenticationMode using the `update-cluster-config` command, +to do that on existing clusters using `CONFIG_MAP` you will have to +first update to `API_AND_CONFIG_MAP` and then to `API`. *These +operations cannot be reverted*, meaning that's not possible to switch +from `API` to `API_AND_CONFIG_MAP` or `CONFIG_MAP`, and also from +`API_AND_CONFIG_MAP` to `CONFIG_MAP`. [source,bash] ---- @@ -248,19 +248,19 @@ cluster creator admin permission, which is the only entry created by default. ____ -=== The `+aws-auth+` ConfigMap _(deprecated)_ +=== The `aws-auth` ConfigMap _(deprecated)_ One way Kubernetes integration with AWS authentication can be done is -via the `+aws-auth+` ConfigMap, which resides in the `+kube-system+` +via the `aws-auth` ConfigMap, which resides in the `kube-system` Namespace. It is responsible for mapping the AWS IAM Identities (Users, Groups, and Roles) authentication, to Kubernetes role-based access -control (RBAC) authorization. The `+aws-auth+` ConfigMap is +control (RBAC) authorization. The `aws-auth` ConfigMap is automatically created in your Amazon EKS cluster during its provisioning phase. It was initially created to allow nodes to join your cluster, but as mentioned you can also use this ConfigMap to add RBACs access to IAM principals. -To check your cluster’s `+aws-auth+` ConfigMap, you can use the +To check your cluster's `aws-auth` ConfigMap, you can use the following command. [source,bash] @@ -268,7 +268,7 @@ following command. kubectl -n kube-system get configmap aws-auth -o yaml ---- -This is a sample of a default configuration of the `+aws-auth+` +This is a sample of a default configuration of the `aws-auth` ConfigMap. [source,yaml] @@ -289,30 +289,30 @@ metadata: namespace: kube-system ---- -The main session of this ConfigMap, is under `+data+` in the -`+mapRoles+` block, which is basically composed by 3 parameters. +The main session of this ConfigMap, is under `data` in the +`mapRoles` block, which is basically composed by 3 parameters. -* *groups:* The Kubernetes group(s) to map the IAM Role to. This can be -a default group, or a custom group specified in a `+clusterrolebinding+` -or `+rolebinding+`. In the above example we have just system groups +* *groups:* The Kubernetes group/groups to map the IAM Role to. This can be +a default group, or a custom group specified in a `clusterrolebinding` +or `rolebinding`. In the above example we have just system groups declared. * *rolearn:* The ARN of the AWS IAM Role be mapped to the Kubernetes -group(s) add, using the following format -`+arn::iam:::role/role-name+`. +group/groups add, using the following format +`arn::iam:::role/role-name`. * *username:* The username within Kubernetes to map to the AWS IAM role. This can be any custom name. ____ It is also possible to map permissions for AWS IAM Users, defining a new -configuration block for `+mapUsers+`, under `+data+` in the `+aws-auth+` +configuration block for `mapUsers`, under `data` in the `aws-auth` ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a -*Best Practice* it’s always recommended to user `+mapRoles+` instead. +*Best Practice* it's always recommended to user `mapRoles` instead. ____ -To manage permissions, you can edit the `+aws-auth+` ConfigMap adding or -removing access to your Amazon EKS cluster. Although it’s possible to -edit the `+aws-auth+` ConfigMap manually, it’s recommended using tools -like `+eksctl+`, since this is a very senstitive configuration, and an +To manage permissions, you can edit the `aws-auth` ConfigMap adding or +removing access to your Amazon EKS cluster. Although it's possible to +edit the `aws-auth` ConfigMap manually, it's recommended using tools +like `eksctl`, since this is a very senstitive configuration, and an inaccurate configuration can lock you outside your Amazon EKS Cluster. Check the subsection https://aws.github.io/aws-eks-best-practices/security/docs/iam/#use-tools-to-make-changes-to-the-aws-auth-configmap[Use @@ -323,7 +323,7 @@ tools to make changes to the aws-auth ConfigMap] below for more details. === Make the EKS Cluster Endpoint private By default when you provision an EKS cluster, the API cluster endpoint -is set to public, i.e. it can be accessed from the Internet. Despite +is set to public, i.e. it can be accessed from the Internet. Despite being accessible from the Internet, the endpoint is still considered secure because it requires all API requests to be authenticated by IAM and then authorized by Kubernetes RBAC. That said, if your corporate @@ -345,13 +345,13 @@ the kubelets (workers) and the Kubernetes API through the cross-account ENIs that get provisioned into the cluster VPC when the control plane is provisioned. -=== Don’t use a service account token for authentication +=== Don't use a service account token for authentication A service account token is a long-lived, static credential. If it is compromised, lost, or stolen, an attacker may be able to perform all the actions associated with that token until the service account is deleted. At times, you may need to grant an exception for applications that have -to consume the Kubernetes API from outside the cluster, e.g. a CI/CD +to consume the Kubernetes API from outside the cluster, e.g. a CI/CD pipeline application. If such applications run on AWS infrastructure, like EC2 instances, consider using an instance profile and mapping that to a Kubernetes RBAC role. @@ -360,25 +360,25 @@ to a Kubernetes RBAC role. An IAM User does not need to be assigned privileges to AWS resources to access the Kubernetes API. If you need to grant an IAM user access to an -EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user +EKS cluster, create an entry in the `aws-auth` ConfigMap for that user that maps to a specific Kubernetes RBAC group. [[iam-cluster-creator,iam-cluster-creator.title]] === Remove the cluster-admin permissions from the cluster creator principal By default Amazon EKS clusters are created with a permanent -`+cluster-admin+` permission bound to the cluster creator principal. -With the Cluster Access Manager API, it’s possible to create clusters +`cluster-admin` permission bound to the cluster creator principal. +With the Cluster Access Manager API, it's possible to create clusters without this permission setting the -`+--access-config bootstrapClusterCreatorAdminPermissions+` to -`+false+`, when using `+API_AND_CONFIG_MAP+` or `+API+` authentication +`--access-config bootstrapClusterCreatorAdminPermissions` to +`false`, when using `API_AND_CONFIG_MAP` or `API` authentication mode. Revoke this access considered a best practice to avoid any unwanted changes to the cluster configuration. The process to revoke this access, follows the same process to revoke any other access to the cluster. The API gives you flexibility to only disassociate an IAM principal from -an Access Policy, in this case the `+AmazonEKSClusterAdminPolicy+`. +an Access Policy, in this case the `AmazonEKSClusterAdminPolicy`. [source,bash] ---- @@ -392,7 +392,7 @@ $ aws eks disassociate-access-policy --cluster-name \ ---- Or completely removing the Access Entry associated with the -`+cluster-admin+` permission. +`cluster-admin` permission. [source,bash] ---- @@ -411,12 +411,12 @@ This access can be granted again if needed during an incident, emergency or break glass scenario where the cluster is otherwise inaccessible. ____ -If the cluster still configured with the `+CONFIG_MAP+` authentication +If the cluster still configured with the `CONFIG_MAP` authentication method, all additional users should be granted access to the cluster -through the `+aws-auth+` ConfigMap, and after `+aws-auth+` ConfigMap is +through the `aws-auth` ConfigMap, and after `aws-auth` ConfigMap is configured, the role assigned to the entity that created the cluster, can be deleted and only recreated in case of an incident, emergency or -break glass scenario, or where the `+aws-auth+` ConfigMap is corrupted +break glass scenario, or where the `aws-auth` ConfigMap is corrupted and the cluster is otherwise inaccessible. This can be particularly useful in production clusters. @@ -428,11 +428,11 @@ group. This will be easier to maintain, especially as the number of users that require access grows. !!! attention When accessing the EKS cluster with the IAM entity mapped -by `+aws-auth+` ConfigMap, the username described is recorded in the -user field of the Kubernetes audit log. If you’re using an IAM role, the -actual users who assume that role aren’t recorded and can’t be audited. +by `aws-auth` ConfigMap, the username described is recorded in the +user field of the Kubernetes audit log. If you're using an IAM role, the +actual users who assume that role aren't recorded and can't be audited. -If still using the `+aws-auth+` configMap as the authentication method, +If still using the `aws-auth` configMap as the authentication method, when assigning K8s RBAC permissions to an IAM role, you should include \{\{SessionName}} in your username. That way, the audit log will record the session name so you can track who the actual user assume this role @@ -448,7 +448,7 @@ along with the CloudTrail log. ____ In Kubernetes 1.20 and above, this change is no longer required, since -`+user.extra.sessionName.0+` was added to the Kubernetes audit log. +`user.extra.sessionName.0` was added to the Kubernetes audit log. ____ === Employ least privileged access when creating RoleBindings and ClusterRoleBindings @@ -456,8 +456,8 @@ ____ Like the earlier point about granting access to AWS Resources, RoleBindings and ClusterRoleBindings should only include the set of permissions necessary to perform a specific function. Avoid using -`+["*"]+` in your Roles and ClusterRoles unless it’s absolutely -necessary. If you’re unsure what permissions to assign, consider using a +`["*"]` in your Roles and ClusterRoles unless it's absolutely +necessary. If you're unsure what permissions to assign, consider using a tool like https://github.com/liggitt/audit2rbac[audit2rbac] to automatically generate Roles and binding based on the observed API calls in the Kubernetes Audit Log. @@ -465,19 +465,17 @@ in the Kubernetes Audit Log. === Create cluster using an automated process As seen in earlier steps, when creating an Amazon EKS cluster, if not -using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, -and not opting out to delegate `+cluster-admin+` permissions to the -cluster creator, the IAM entity user or role, such as a federated -user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster’s RBAC +using the using `API_AND_CONFIG_MAP` or `API` authentication mode, +and not opting out to delegate `cluster-admin` permissions to the +cluster creator, the IAM entity user or role, such as a federated +user that creates the cluster, is automatically +granted `system:masters` permissions in the cluster's RBAC configuration. Even being a best practice to remove this permission, as -described -xref:iam-cluster-creator][here] -if using the `+CONFIG_MAP+` authentication method, relying on -`+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a +described xref:iam-cluster-creator[here] if using the `CONFIG_MAP` authentication method, relying on +`aws-auth` ConfigMap, this access cannot be revoked. Therefore it is a good idea to create the cluster with an infrastructure automation pipeline tied to dedicated IAM role, with no permissions to be assumed -by other users or entities and regularly audit this role’s permissions, +by other users or entities and regularly audit this role's permissions, policies, and who has access to trigger the pipeline. Also, this role should not be used to perform routine actions on the cluster, and be exclusively used to cluster level actions triggered by the pipeline, via @@ -486,15 +484,15 @@ SCM code changes for example. === Create the cluster with a dedicated IAM role When you create an Amazon EKS cluster, the IAM entity user or role, such -as a federated user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster’s RBAC +as a federated user that creates the cluster, is automatically +granted `system:masters` permissions in the cluster's RBAC configuration. This access cannot be removed and is not managed through -the `+aws-auth+` ConfigMap. Therefore it is a good idea to create the +the `aws-auth` ConfigMap. Therefore it is a good idea to create the cluster with a dedicated IAM role and regularly audit who can assume this role. This role should not be used to perform routine actions on the cluster, and instead additional users should be granted access to -the cluster through the `+aws-auth+` ConfigMap for this purpose. After -the `+aws-auth+` ConfigMap is configured, the role should be secured and +the cluster through the `aws-auth` ConfigMap for this purpose. After +the `aws-auth` ConfigMap is configured, the role should be secured and only used in temporary elevated privilege mode / break glass for scenarios where the cluster is otherwise inaccessible. This can be particularly useful in clusters which do not have direct user access @@ -503,23 +501,23 @@ configured. === Regularly audit access to the cluster Who requires access is likely to change over time. Plan to periodically -audit the `+aws-auth+` ConfigMap to see who has been granted access and -the rights they’ve been assigned. You can also use open source tooling +audit the `aws-auth` ConfigMap to see who has been granted access and +the rights they've been assigned. You can also use open source tooling like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine -the roles bound to a particular service account, user, or group. We’ll +the roles bound to a particular service account, user, or group. We'll explore this topic further when we get to the section on xref:auditing-and-logging[auditing]. Additional ideas can be found in this https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] from NCC Group. -=== If relying on `+aws-auth+` configMap use tools to make changes +=== If relying on `aws-auth` configMap use tools to make changes An improperly formatted aws-auth ConfigMap may cause you to lose access to the cluster. If you need to make changes to the ConfigMap, use a tool. -*eksctl* The `+eksctl+` CLI includes a command for adding identity +*eksctl* The `eksctl` CLI includes a command for adding identity mappings to the aws-auth ConfigMap. View CLI Help: @@ -548,11 +546,11 @@ $ eksctl create iamidentitymapping --cluster --region= - ---- For more information, review -https://eksctl.io/usage/iam-identity-mappings/[`+eksctl+` docs] +https://eksctl.io/usage/iam-identity-mappings/[`eksctl` docs] *https://github.com/keikoproj/aws-auth[aws-auth] by keikoproj* -`+aws-auth+` by keikoproj includes both a cli and a go library. +`aws-auth` by keikoproj includes both a cli and a go library. Download and view help CLI help: @@ -564,7 +562,7 @@ $ aws-auth help ... ---- -Alternatively, install `+aws-auth+` with the +Alternatively, install `aws-auth` with the https://krew.sigs.k8s.io[krew plugin manager] for kubectl. [source,bash] @@ -581,7 +579,7 @@ aws-auth docs on GitHub] for more information, including the go library. *https://github.com/kubernetes-sigs/aws-iam-authenticator/tree/master/cmd/aws-iam-authenticator[AWS IAM Authenticator CLI]* -The `+aws-iam-authenticator+` project includes a CLI for updating the +The `aws-iam-authenticator` project includes a CLI for updating the ConfigMap. https://github.com/kubernetes-sigs/aws-iam-authenticator/releases[Download @@ -623,19 +621,19 @@ provider will appear in the Kubernetes audit log. You can also use https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[AWS -SSO] to federate AWS with an external identity provider, e.g. Azure AD. +SSO] to federate AWS with an external identity provider, e.g. Azure AD. If you decide to use this, the AWS CLI v2.0 includes an option to create a named profile that makes it easy to associate an SSO session with your current CLI session and assume an IAM role. Know that you must assume a -role _prior_ to running `+kubectl+` as the IAM role is used to determine -the user’s Kubernetes RBAC group. +role _prior_ to running `kubectl` as the IAM role is used to determine +the user's Kubernetes RBAC group. == Identities and Credentials for EKS pods Certain applications that run within a Kubernetes cluster need permission to call the Kubernetes API to function properly. For example, the https://github.com/kubernetes-sigs/aws-load-balancer-controller[AWS -Load Balancer Controller] needs to be able to list a Service’s +Load Balancer Controller] needs to be able to list a Service's Endpoints. The controller also needs to be able to invoke AWS APIs to provision and configure an ALB. In this section we will explore the best practices for assigning rights and privileges to Pods. @@ -647,9 +645,9 @@ a Kubernetes RBAC role to a pod. A default service account is created automatically for each Namespace within a cluster. When you deploy a pod into a Namespace without referencing a specific service account, the default service account for that Namespace will automatically get -assigned to the Pod and the Secret, i.e. the service account (JWT) token +assigned to the Pod and the Secret, i.e. the service account (JWT) token for that service account, will get mounted to the pod as a volume at -`+/var/run/secrets/kubernetes.io/serviceaccount+`. Decoding the service +`/var/run/secrets/kubernetes.io/serviceaccount`. Decoding the service account token in that directory will reveal the following metadata: [source,json] @@ -705,7 +703,7 @@ permission to call those APIs. Similar to guidelines for user access, the Role or ClusterRole bound to a service account should be restricted to the API resources and methods that the application needs to function and nothing else. To use a non-default service account simply set the -`+spec.serviceAccountName+` field of a Pod to the name of the service +`spec.serviceAccountName` field of a Pod to the name of the service account you wish to use. For additional information about creating service accounts, see https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions. @@ -718,10 +716,10 @@ the pod to authenticate to the Kubernetes API server. In Kubernetes and is only valid for an hour by default. A secret for the service account will not be created. If you have an application that runs outside the cluster that needs to authenticate to the Kubernetes API, -e.g. Jenkins, you will need to create a secret of type -`+kubernetes.io/service-account-token+` along with an annotation that +e.g. Jenkins, you will need to create a secret of type +`kubernetes.io/service-account-token` along with an annotation that references the service account such as -`+metadata.annotations.kubernetes.io/service-account.name: +`. +`metadata.annotations.kubernetes.io/service-account.name: `. Secrets created in this way do not expire. === IAM Roles for Service Accounts (IRSA) @@ -735,12 +733,12 @@ will call the public OIDC discovery endpoint for the cluster on startup. The endpoint cryptographically signs the OIDC token issued by Kubernetes and the resulting token mounted as a volume. This signed token allows the Pod to call the AWS APIs associated IAM role. When an AWS API is -invoked, the AWS SDKs calls `+sts:AssumeRoleWithWebIdentity+`. After -validating the token’s signature, IAM exchanges the Kubernetes issued +invoked, the AWS SDKs calls `sts:AssumeRoleWithWebIdentity`. After +validating the token's signature, IAM exchanges the Kubernetes issued token for a temporary AWS role credential. When using IRSA, it is important to -xref:iam-reuse-sessions,[reuse AWS SDK sessions] to avoid +xref:iam-reuse-sessions[reuse AWS SDK sessions] to avoid unneeded calls to AWS STS. Decoding the (JWT) token for IRSA will produce output similar to the @@ -788,7 +786,7 @@ this: "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", + "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oesl1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZeuE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0Hbi/PWAtlI8YJcDX69cM30JAHDdQHltm/4scFptW1hlvMaPWReCAaCrsHrATyka7ttw5YlUyvZ8EPogj6fwHlxmrXM9h1BqdikomyJU00gm1FJelfP1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkWsCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZGCkyDLIa8MBn9KPXeJd/yjTk5IifIwO/mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVCM+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } @@ -826,9 +824,9 @@ version of the AWS SDK] to use this feature. When EKS Pod Identities are configured for a Pod, EKS will mount and refresh a pod identity token at -`+/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token+`. +`/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token`. This token will be used by the AWS SDK to communicate with the EKS Pod -Identity Agent, which uses the pod identity token and the agent’s IAM +Identity Agent, which uses the pod identity token and the agent's IAM role to create temporary credentials for your pods by calling the https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html[AssumeRoleForPodIdentity API]. The pod identity token delivered to your pods is a JWT issued from @@ -853,16 +851,16 @@ to the same AWS account as the EKS cluster. To access an IAM role in another AWS account, you must assume that role by https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html[configuring a profile in your SDK configuration], or in your -https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application’s +https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application's code]. * When EKS Pod Identities are being configured for Service Accounts, the person or process configuring the Pod Identity Association must have the -`+iam:PassRole+` entitlement for that role. +`iam:PassRole` entitlement for that role. * Each Service Account may only have one IAM role associated with it through EKS Pod Identities, however you can associate the same IAM role with multiple service accounts. * IAM roles used with EKS Pod Identities must allow the -`+pods.eks.amazonaws.com+` Service Principal to assume them, _and_ set +`pods.eks.amazonaws.com` Service Principal to assume them, _and_ set session tags. The following is an example role trust policy which allows EKS Pod Identities to use an IAM role: @@ -890,13 +888,13 @@ EKS Pod Identities to use an IAM role: } ---- -AWS recommends using condition keys like `+aws:SourceOrgId+` to help +AWS recommends using condition keys like `aws:SourceOrgId` to help protect against the https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention[cross-service confused deputy problem]. In the above example role trust policy, the -`+ResourceOrgId+` is a variable equal to the AWS Organizations +`ResourceOrgId` is a variable equal to the AWS Organizations Organization ID of the AWS Organization that the AWS account belongs to. -EKS will pass in a value for `+aws:SourceOrgId+` equal to that when +EKS will pass in a value for `aws:SourceOrgId` equal to that when assuming a role with EKS Pod Identities. ==== ABAC and EKS Pod Identities @@ -914,7 +912,7 @@ Identities runs in. associated with EKS Pod Identities |eks-cluster-arn |The ARN of the EKS cluster, -e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. +e.g. `arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}`. The cluster ARN is unique, but if a cluster is deleted and recreated in the same region with the same name, within the same AWS account, it will have the same ARN. @@ -935,23 +933,23 @@ only specific kubernetes service accounts. When doing so, it is _very important_ to understand that kubernetes service accounts are only unique within a namespace, and kubernetes namespaces are only unique within an EKS cluster. These session tags can be accessed in AWS -policies by using the `+aws:PrincipalTag/+` global condition -key, such as `+aws:PrincipalTag/eks-cluster-arn+` +policies by using the `aws:PrincipalTag/` global condition +key, such as `aws:PrincipalTag/eks-cluster-arn` For example, if you wanted to grant access to only a specific service account to access an AWS resource in your account with an IAM or -resource policy, you would need to check `+eks-cluster-arn+` and -`+kubernetes-namespace+` tags as well as the -`+kubernetes-service-account+` to ensure that only that service accounts +resource policy, you would need to check `eks-cluster-arn` and +`kubernetes-namespace` tags as well as the +`kubernetes-service-account` to ensure that only that service accounts from the intended cluster have access to that resource as other clusters -could have identical `+kubernetes-service-accounts+` and -`+kubernetes-namespaces+`. +could have identical `kubernetes-service-accounts` and +`kubernetes-namespaces`. This example S3 Bucket policy only grants access to objects in the S3 -bucket it’s attached to, only if `+kubernetes-service-account+`, -`+kubernetes-namespace+`, `+eks-cluster-arn+` all meet their expected +bucket it's attached to, only if `kubernetes-service-account`, +`kubernetes-namespace`, `eks-cluster-arn` all meet their expected values, where the EKS cluster is hosted in the AWS account -`+111122223333+`. +`111122223333`. [source,json] ---- @@ -1014,7 +1012,7 @@ with sts:AssumeRoleWithWebIdentity At present, the aws-node daemonset is configured to use a role assigned to the EC2 instances to assign IPs to pods. This role includes several -AWS managed policies, e.g. AmazonEKS_CNI_Policy and +AWS managed policies, e.g. AmazonEKS_CNI_Policy and EC2ContainerRegistryReadOnly that effectively allow *all* pods running on a node to attach/detach ENIs, assign/unassign IP addresses, or pull images from ECR. Since this presents a risk to your cluster, it is @@ -1042,7 +1040,7 @@ to the worker node. You can block access to instance metadata by requiring the instance to use IMDSv2 only and updating the hop count to 1 as in the example below. -You can also include these settings in the node group’s launch template. +You can also include these settings in the node group's launch template. Do *not* disable instance metadata as this will prevent components like the node termination handler and other things that rely on instance metadata from working properly. @@ -1057,33 +1055,33 @@ If you are using Terraform to create launch templates for use with Managed Node Groups, add the metadata block to configure the hop count as seen in this code snippet: -`+tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...+` +`tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...` -You can also block a pod’s access to EC2 metadata by manipulating +You can also block a pod's access to EC2 metadata by manipulating iptables on the node. For further information about this method, see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access[Limiting access to the instance metadata service]. If you have an application that is using an older version of the AWS SDK -that doesn’t support IRSA or EKS Pod Identities, you should update the +that doesn't support IRSA or EKS Pod Identities, you should update the SDK version. === Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster The trust policy can be scoped to a Namespace or a specific service -account within a Namespace. When using IRSA it’s best to make the role +account within a Namespace. When using IRSA it's best to make the role trust policy as explicit as possible by including the service account name. This will effectively prevent other Pods within the same Namespace -from assuming the role. The CLI `+eksctl+` will do this automatically +from assuming the role. The CLI `eksctl` will do this automatically when you use it to create service accounts/IAM roles. See https://eksctl.io/usage/iamserviceaccounts/ for further information. -When working with IAM directly, this is adding condition into the role’s -trust policy that uses conditions to ensure the `+:sub+` claim are the +When working with IAM directly, this is adding condition into the role's +trust policy that uses conditions to ensure the `:sub` claim are the namespace and service account you expect. As an example, before we had an IRSA token with a sub claim of -"`system:serviceaccount:default:s3-read-only`" . This is the `+default+` -namespace and the service account is `+s3-read-only+`. You would use a +"`system:serviceaccount:default:s3-read-only`" . This is the `default` +namespace and the service account is `s3-read-only`. You would use a condition like the following to ensure that only your service account in a given namespace from your cluster can assume that role: @@ -1116,7 +1114,7 @@ https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadat requires you use a PUT request to get a session token. The initial PUT request has to include a TTL for the session token. Newer versions of the AWS SDKs will handle this and the renewal of said token -automatically. It’s also important to be aware that the default hop +automatically. It's also important to be aware that the default hop limit on EC2 instances is intentionally set to 1 to prevent IP forwarding. As a consequence, Pods that request a session token that are run on EC2 instances may eventually time out and fallback to using the @@ -1126,10 +1124,10 @@ the official CloudFormation templates. === Disable auto-mounting of service account tokens -If your application doesn’t need to call the Kubernetes API set the -`+automountServiceAccountToken+` attribute to `+false+` in the PodSpec +If your application doesn't need to call the Kubernetes API set the +`automountServiceAccountToken` attribute to `false` in the PodSpec for your application or patch the default service account in each -namespace so that it’s no longer mounted to pods automatically. For +namespace so that it's no longer mounted to pods automatically. For example: [source,bash] @@ -1153,18 +1151,18 @@ seamlessly shift traffic from services running on the old cluster to the new cluster. When using blue/green cluster upgrades with EKS Pod Identity, you would create pod identity associations between the IAM roles and service accounts in the new cluster. And update the IAM role -trust policy if you have a `+sourceArn+` condition. +trust policy if you have a `sourceArn` condition. === Run the application as a non-root user Containers run as root by default. While this allows them to read the web identity token file, running a container as root is not considered a best practice. As an alternative, consider adding the -`+spec.securityContext.runAsUser+` attribute to the PodSpec. The value -of `+runAsUser+` is arbitrary value. +`spec.securityContext.runAsUser` attribute to the PodSpec. The value +of `runAsUser` is arbitrary value. In the following example, all processes within the Pod will run under -the user ID specified in the `+runAsUser+` field. +the user ID specified in the `runAsUser` field. [source,yaml] ---- @@ -1244,7 +1242,7 @@ be bound to system:anonymous user or system:unauthenticated group. There may be some legitimate reasons to enable anonymous access on specific APIs. If this is the case for your cluster ensure that only those specific APIs are accessible by anonymous user and exposing those -APIs without authentication doesn’t make your cluster vulnerable. +APIs without authentication doesn't make your cluster vulnerable. Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was associated to system:discovery and system:basic-user ClusterRoles by @@ -1362,25 +1360,25 @@ Repeat the same steps for system:basic-user ClusterRoleBinding. === Reuse AWS SDK sessions with IRSA When you use IRSA, applications written using the AWS SDK use the token -delivered to your pods to call `+sts:AssumeRoleWithWebIdentity+` to +delivered to your pods to call `sts:AssumeRoleWithWebIdentity` to generate temporary AWS credentials. This is different from other AWS compute services, where the compute service delivers temporary AWS credentials directly to the AWS compute resource, such as a lambda function. This means that every time an AWS SDK session is initialized, -a call to AWS STS for `+AssumeRoleWithWebIdentity+` is made. If your +a call to AWS STS for `AssumeRoleWithWebIdentity` is made. If your application scales rapidly and initializes many AWS SDK sessions, you may experience throttling from AWS STS as your code will be making many -calls for `+AssumeRoleWithWebIdentity+`. +calls for `AssumeRoleWithWebIdentity`. To avoid this scenario, we recommend reusing AWS SDK sessions within your application so that unnecessary calls to -`+AssumeRoleWithWebIdentity+` are not made. +`AssumeRoleWithWebIdentity` are not made. In the following example code, a session is created using the boto3 python SDK, and that same session is used to create clients and interact -with both Amazon S3 and Amazon SQS. `+AssumeRoleWithWebIdentity+` is +with both Amazon S3 and Amazon SQS. `AssumeRoleWithWebIdentity` is only called once, and the AWS SDK will refresh the credentials of -`+my_session+` when they expire automatically. +`my_session` when they expire automatically. ```python import boto3 @@ -1401,7 +1399,7 @@ print(sqsresponse) ``` ``` -If you’re migrating an application from another AWS compute service, +If you're migrating an application from another AWS compute service, such as EC2, to EKS with IRSA, this is a particularly important detail. On other compute services initializing an AWS SDK session does not call AWS STS unless you instruct it to. @@ -1415,11 +1413,11 @@ that currently support IRSA, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, for EKS Pod Identities, see https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. -If you have an application that you can’t immediately update with a +If you have an application that you can't immediately update with a compatible SDK, there are several community-built solutions available for assigning IAM roles to Kubernetes pods, including https://github.com/jtblin/kube2iam[kube2iam] and -https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse, +https://github.com/uswitch/kiam[kiam]. Although AWS doesn't endorse, condone, nor support the use of these solutions, they are frequently used by the community at large to achieve similar results as IRSA and EKS Pod Identities. diff --git a/latest/bpg/security/iam.adoc.backup b/latest/bpg/security/iam.adoc.backup index 46db7be1f..8a7d9e538 100644 --- a/latest/bpg/security/iam.adoc.backup +++ b/latest/bpg/security/iam.adoc.backup @@ -40,9 +40,9 @@ https://github.com/kubernetes-sigs/aws-iam-authenticator[aws-iam-authenticator] client when you run `+kubectl+` commands. As you execute commands, the token is passed to the kube-apiserver which forwards it to the authentication webhook. If the request is well-formed, the webhook calls -a pre-signed URL embedded in the token’s body. This URL validates the -request’s signature and returns information about the user, e.g. the -user’s account, Arn, and UserId to the kube-apiserver. +a pre-signed URL embedded in the token's body. This URL validates the +request's signature and returns information about the user, e.g. the +user's account, Arn, and UserId to the kube-apiserver. To manually generate a authentication token, type the following command in a terminal window: @@ -105,11 +105,11 @@ https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. The token has a time to live (TTL) of 15 minutes after which a new token will need to be generated. This is handled automatically when you use a -client like `+kubectl+`, however, if you’re using the Kubernetes +client like `+kubectl+`, however, if you're using the Kubernetes dashboard, you will need to generate a new token and re-authenticate each time the token expires. -Once the user’s identity has been authenticated by the AWS IAM service, +Once the user's identity has been authenticated by the AWS IAM service, the kube-apiserver reads the `+aws-auth+` ConfigMap in the `+kube-system+` Namespace to determine the RBAC group to associate with the user. The `+aws-auth+` ConfigMap is used to create a static mapping @@ -150,7 +150,7 @@ ____ Cluster Access Manager allows the combination of upstream RBAC with Access Policies supporting allow and pass (but not deny) on Kubernetes AuthZ decisions regarding API server requests. A deny decision will -happen when both, the upstream RBAC and Amazon EKS authorizers can’t +happen when both, the upstream RBAC and Amazon EKS authorizers can't determine the outcome of a request evaluation. With this feature, Amazon EKS supports three modes of authentication: @@ -186,7 +186,7 @@ It is possible to update Amazon EKS clusters configuration to enable `+API+` authenticationMode using the `+update-cluster-config+` command, to do that on existing clusters using `+CONFIG_MAP+` you will have to first update to `+API_AND_CONFIG_MAP+` and then to `+API+`. *These -operations cannot be reverted*, meaning that’s not possible to switch +operations cannot be reverted*, meaning that's not possible to switch from `+API+` to `+API_AND_CONFIG_MAP+` or `+CONFIG_MAP+`, and also from `+API_AND_CONFIG_MAP+` to `+CONFIG_MAP+`. @@ -260,7 +260,7 @@ phase. It was initially created to allow nodes to join your cluster, but as mentioned you can also use this ConfigMap to add RBACs access to IAM principals. -To check your cluster’s `+aws-auth+` ConfigMap, you can use the +To check your cluster's `+aws-auth+` ConfigMap, you can use the following command. [source,bash] @@ -292,12 +292,12 @@ metadata: The main session of this ConfigMap, is under `+data+` in the `+mapRoles+` block, which is basically composed by 3 parameters. -* *groups:* The Kubernetes group(s) to map the IAM Role to. This can be +* *groups:* The Kubernetes group/groups to map the IAM Role to. This can be a default group, or a custom group specified in a `+clusterrolebinding+` or `+rolebinding+`. In the above example we have just system groups declared. * *rolearn:* The ARN of the AWS IAM Role be mapped to the Kubernetes -group(s) add, using the following format +group/groups add, using the following format `+arn::iam:::role/role-name+`. * *username:* The username within Kubernetes to map to the AWS IAM role. This can be any custom name. @@ -306,12 +306,12 @@ ____ It is also possible to map permissions for AWS IAM Users, defining a new configuration block for `+mapUsers+`, under `+data+` in the `+aws-auth+` ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a -*Best Practice* it’s always recommended to user `+mapRoles+` instead. +*Best Practice* it's always recommended to user `+mapRoles+` instead. ____ To manage permissions, you can edit the `+aws-auth+` ConfigMap adding or -removing access to your Amazon EKS cluster. Although it’s possible to -edit the `+aws-auth+` ConfigMap manually, it’s recommended using tools +removing access to your Amazon EKS cluster. Although it's possible to +edit the `+aws-auth+` ConfigMap manually, it's recommended using tools like `+eksctl+`, since this is a very senstitive configuration, and an inaccurate configuration can lock you outside your Amazon EKS Cluster. Check the subsection @@ -345,7 +345,7 @@ the kubelets (workers) and the Kubernetes API through the cross-account ENIs that get provisioned into the cluster VPC when the control plane is provisioned. -=== Don’t use a service account token for authentication +=== Don't use a service account token for authentication A service account token is a long-lived, static credential. If it is compromised, lost, or stolen, an attacker may be able to perform all the @@ -363,11 +363,12 @@ access the Kubernetes API. If you need to grant an IAM user access to an EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user that maps to a specific Kubernetes RBAC group. +[[iam-cluster-creator,iam-cluster-creator.title]] === Remove the cluster-admin permissions from the cluster creator principal By default Amazon EKS clusters are created with a permanent `+cluster-admin+` permission bound to the cluster creator principal. -With the Cluster Access Manager API, it’s possible to create clusters +With the Cluster Access Manager API, it's possible to create clusters without this permission setting the `+--access-config bootstrapClusterCreatorAdminPermissions+` to `+false+`, when using `+API_AND_CONFIG_MAP+` or `+API+` authentication @@ -428,8 +429,8 @@ users that require access grows. !!! attention When accessing the EKS cluster with the IAM entity mapped by `+aws-auth+` ConfigMap, the username described is recorded in the -user field of the Kubernetes audit log. If you’re using an IAM role, the -actual users who assume that role aren’t recorded and can’t be audited. +user field of the Kubernetes audit log. If you're using an IAM role, the +actual users who assume that role aren't recorded and can't be audited. If still using the `+aws-auth+` configMap as the authentication method, when assigning K8s RBAC permissions to an IAM role, you should include @@ -455,8 +456,8 @@ ____ Like the earlier point about granting access to AWS Resources, RoleBindings and ClusterRoleBindings should only include the set of permissions necessary to perform a specific function. Avoid using -`+["*"]+` in your Roles and ClusterRoles unless it’s absolutely -necessary. If you’re unsure what permissions to assign, consider using a +`+["*"]+` in your Roles and ClusterRoles unless it's absolutely +necessary. If you're unsure what permissions to assign, consider using a tool like https://github.com/liggitt/audit2rbac[audit2rbac] to automatically generate Roles and binding based on the observed API calls in the Kubernetes Audit Log. @@ -466,17 +467,15 @@ in the Kubernetes Audit Log. As seen in earlier steps, when creating an Amazon EKS cluster, if not using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, and not opting out to delegate `+cluster-admin+` permissions to the -cluster creator, the IAM entity user or role, such as a federated -user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster’s RBAC +cluster creator, the IAM entity user or role, such as a federated +user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster's RBAC configuration. Even being a best practice to remove this permission, as -described -link:#remove-the-cluster-admin-permissions-from-the-cluster-creator-principal[here] -if using the `+CONFIG_MAP+` authentication method, relying on +described xref:iam-cluster-creator[here] if using the `+CONFIG_MAP+` authentication method, relying on `+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a good idea to create the cluster with an infrastructure automation pipeline tied to dedicated IAM role, with no permissions to be assumed -by other users or entities and regularly audit this role’s permissions, +by other users or entities and regularly audit this role's permissions, policies, and who has access to trigger the pipeline. Also, this role should not be used to perform routine actions on the cluster, and be exclusively used to cluster level actions triggered by the pipeline, via @@ -485,8 +484,8 @@ SCM code changes for example. === Create the cluster with a dedicated IAM role When you create an Amazon EKS cluster, the IAM entity user or role, such -as a federated user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster’s RBAC +as a federated user that creates the cluster, is automatically +granted `+system:masters+` permissions in the cluster's RBAC configuration. This access cannot be removed and is not managed through the `+aws-auth+` ConfigMap. Therefore it is a good idea to create the cluster with a dedicated IAM role and regularly audit who can assume @@ -503,12 +502,12 @@ configured. Who requires access is likely to change over time. Plan to periodically audit the `+aws-auth+` ConfigMap to see who has been granted access and -the rights they’ve been assigned. You can also use open source tooling +the rights they've been assigned. You can also use open source tooling like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine -the roles bound to a particular service account, user, or group. We’ll +the roles bound to a particular service account, user, or group. We'll explore this topic further when we get to the section on -link:detective.md[auditing]. Additional ideas can be found in this +xref:auditing-and-logging[auditing]. Additional ideas can be found in this https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] from NCC Group. @@ -627,14 +626,14 @@ If you decide to use this, the AWS CLI v2.0 includes an option to create a named profile that makes it easy to associate an SSO session with your current CLI session and assume an IAM role. Know that you must assume a role _prior_ to running `+kubectl+` as the IAM role is used to determine -the user’s Kubernetes RBAC group. +the user's Kubernetes RBAC group. == Identities and Credentials for EKS pods Certain applications that run within a Kubernetes cluster need permission to call the Kubernetes API to function properly. For example, the https://github.com/kubernetes-sigs/aws-load-balancer-controller[AWS -Load Balancer Controller] needs to be able to list a Service’s +Load Balancer Controller] needs to be able to list a Service's Endpoints. The controller also needs to be able to invoke AWS APIs to provision and configure an ALB. In this section we will explore the best practices for assigning rights and privileges to Pods. @@ -717,7 +716,7 @@ the pod to authenticate to the Kubernetes API server. In Kubernetes and is only valid for an hour by default. A secret for the service account will not be created. If you have an application that runs outside the cluster that needs to authenticate to the Kubernetes API, -e.g. Jenkins, you will need to create a secret of type +e.g. Jenkins, you will need to create a secret of type `+kubernetes.io/service-account-token+` along with an annotation that references the service account such as `+metadata.annotations.kubernetes.io/service-account.name: +`. @@ -735,11 +734,11 @@ The endpoint cryptographically signs the OIDC token issued by Kubernetes and the resulting token mounted as a volume. This signed token allows the Pod to call the AWS APIs associated IAM role. When an AWS API is invoked, the AWS SDKs calls `+sts:AssumeRoleWithWebIdentity+`. After -validating the token’s signature, IAM exchanges the Kubernetes issued +validating the token's signature, IAM exchanges the Kubernetes issued token for a temporary AWS role credential. When using IRSA, it is important to -link:#reuse-aws-sdk-sessions-with-irsa[reuse AWS SDK sessions] to avoid +xref:iam-reuse-sessions,[reuse AWS SDK sessions] to avoid unneeded calls to AWS STS. Decoding the (JWT) token for IRSA will produce output similar to the @@ -827,7 +826,7 @@ When EKS Pod Identities are configured for a Pod, EKS will mount and refresh a pod identity token at `+/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token+`. This token will be used by the AWS SDK to communicate with the EKS Pod -Identity Agent, which uses the pod identity token and the agent’s IAM +Identity Agent, which uses the pod identity token and the agent's IAM role to create temporary credentials for your pods by calling the https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html[AssumeRoleForPodIdentity API]. The pod identity token delivered to your pods is a JWT issued from @@ -852,7 +851,7 @@ to the same AWS account as the EKS cluster. To access an IAM role in another AWS account, you must assume that role by https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html[configuring a profile in your SDK configuration], or in your -https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application’s +https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application's code]. * When EKS Pod Identities are being configured for Service Accounts, the person or process configuring the Pod Identity Association must have the @@ -913,7 +912,7 @@ Identities runs in. associated with EKS Pod Identities |eks-cluster-arn |The ARN of the EKS cluster, -e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. +e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. The cluster ARN is unique, but if a cluster is deleted and recreated in the same region with the same name, within the same AWS account, it will have the same ARN. @@ -947,7 +946,7 @@ could have identical `+kubernetes-service-accounts+` and `+kubernetes-namespaces+`. This example S3 Bucket policy only grants access to objects in the S3 -bucket it’s attached to, only if `+kubernetes-service-account+`, +bucket it's attached to, only if `+kubernetes-service-account+`, `+kubernetes-namespace+`, `+eks-cluster-arn+` all meet their expected values, where the EKS cluster is hosted in the AWS account `+111122223333+`. @@ -1013,7 +1012,7 @@ with sts:AssumeRoleWithWebIdentity At present, the aws-node daemonset is configured to use a role assigned to the EC2 instances to assign IPs to pods. This role includes several -AWS managed policies, e.g. AmazonEKS_CNI_Policy and +AWS managed policies, e.g. AmazonEKS_CNI_Policy and EC2ContainerRegistryReadOnly that effectively allow *all* pods running on a node to attach/detach ENIs, assign/unassign IP addresses, or pull images from ECR. Since this presents a risk to your cluster, it is @@ -1041,7 +1040,7 @@ to the worker node. You can block access to instance metadata by requiring the instance to use IMDSv2 only and updating the hop count to 1 as in the example below. -You can also include these settings in the node group’s launch template. +You can also include these settings in the node group's launch template. Do *not* disable instance metadata as this will prevent components like the node termination handler and other things that rely on instance metadata from working properly. @@ -1058,26 +1057,26 @@ as seen in this code snippet: `+tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...+` -You can also block a pod’s access to EC2 metadata by manipulating +You can also block a pod's access to EC2 metadata by manipulating iptables on the node. For further information about this method, see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access[Limiting access to the instance metadata service]. If you have an application that is using an older version of the AWS SDK -that doesn’t support IRSA or EKS Pod Identities, you should update the +that doesn't support IRSA or EKS Pod Identities, you should update the SDK version. === Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster The trust policy can be scoped to a Namespace or a specific service -account within a Namespace. When using IRSA it’s best to make the role +account within a Namespace. When using IRSA it's best to make the role trust policy as explicit as possible by including the service account name. This will effectively prevent other Pods within the same Namespace from assuming the role. The CLI `+eksctl+` will do this automatically when you use it to create service accounts/IAM roles. See https://eksctl.io/usage/iamserviceaccounts/ for further information. -When working with IAM directly, this is adding condition into the role’s +When working with IAM directly, this is adding condition into the role's trust policy that uses conditions to ensure the `+:sub+` claim are the namespace and service account you expect. As an example, before we had an IRSA token with a sub claim of @@ -1115,7 +1114,7 @@ https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadat requires you use a PUT request to get a session token. The initial PUT request has to include a TTL for the session token. Newer versions of the AWS SDKs will handle this and the renewal of said token -automatically. It’s also important to be aware that the default hop +automatically. It's also important to be aware that the default hop limit on EC2 instances is intentionally set to 1 to prevent IP forwarding. As a consequence, Pods that request a session token that are run on EC2 instances may eventually time out and fallback to using the @@ -1125,10 +1124,10 @@ the official CloudFormation templates. === Disable auto-mounting of service account tokens -If your application doesn’t need to call the Kubernetes API set the +If your application doesn't need to call the Kubernetes API set the `+automountServiceAccountToken+` attribute to `+false+` in the PodSpec for your application or patch the default service account in each -namespace so that it’s no longer mounted to pods automatically. For +namespace so that it's no longer mounted to pods automatically. For example: [source,bash] @@ -1243,7 +1242,7 @@ be bound to system:anonymous user or system:unauthenticated group. There may be some legitimate reasons to enable anonymous access on specific APIs. If this is the case for your cluster ensure that only those specific APIs are accessible by anonymous user and exposing those -APIs without authentication doesn’t make your cluster vulnerable. +APIs without authentication doesn't make your cluster vulnerable. Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was associated to system:discovery and system:basic-user ClusterRoles by @@ -1357,6 +1356,7 @@ section in the above editor screen. Repeat the same steps for system:basic-user ClusterRoleBinding. +[[iam-reuse-sessions,iam-reuse-sessions.title]] === Reuse AWS SDK sessions with IRSA When you use IRSA, applications written using the AWS SDK use the token @@ -1399,7 +1399,7 @@ print(sqsresponse) ``` ``` -If you’re migrating an application from another AWS compute service, +If you're migrating an application from another AWS compute service, such as EC2, to EKS with IRSA, this is a particularly important detail. On other compute services initializing an AWS SDK session does not call AWS STS unless you instruct it to. @@ -1413,11 +1413,11 @@ that currently support IRSA, see https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, for EKS Pod Identities, see https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. -If you have an application that you can’t immediately update with a +If you have an application that you can't immediately update with a compatible SDK, there are several community-built solutions available for assigning IAM roles to Kubernetes pods, including https://github.com/jtblin/kube2iam[kube2iam] and -https://github.com/uswitch/kiam[kiam]. Although AWS doesn’t endorse, +https://github.com/uswitch/kiam[kiam]. Although AWS doesn't endorse, condone, nor support the use of these solutions, they are frequently used by the community at large to achieve similar results as IRSA and EKS Pod Identities. From 46caaed765b8b629b25ffd317c60514cd974f2c7 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 20:58:58 +0000 Subject: [PATCH 14/56] fixup --- latest/bpg/security/fix-code.py | 24 ++++++++ latest/bpg/security/fix-literals.py | 29 ++++++++++ latest/bpg/security/index.adoc | 2 +- latest/bpg/security/pods.adoc | 88 ++++++++++++++--------------- 4 files changed, 98 insertions(+), 45 deletions(-) create mode 100644 latest/bpg/security/fix-code.py create mode 100644 latest/bpg/security/fix-literals.py diff --git a/latest/bpg/security/fix-code.py b/latest/bpg/security/fix-code.py new file mode 100644 index 000000000..2a11e9666 --- /dev/null +++ b/latest/bpg/security/fix-code.py @@ -0,0 +1,24 @@ +import re +import sys + +def remove_plus_wrapping(file_path): + with open(file_path, 'r') as file: + content = file.read() + + # Pattern to match any text wrapped in '+' symbols + pattern = r'\+([^+\n]+)\+' + + # Replace '+text+' with 'text' + modified_content = re.sub(pattern, r'\1', content) + + with open(file_path, 'w') as file: + file.write(modified_content) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python script.py ") + sys.exit(1) + + file_path = sys.argv[1] + remove_plus_wrapping(file_path) + print(f"Processed {file_path}. Text wrapped in '+' symbols has been unwrapped.") \ No newline at end of file diff --git a/latest/bpg/security/fix-literals.py b/latest/bpg/security/fix-literals.py new file mode 100644 index 000000000..7674a45be --- /dev/null +++ b/latest/bpg/security/fix-literals.py @@ -0,0 +1,29 @@ +import re +import shutil + +def fix_code_literals(filename): + # Create a backup of the original file + shutil.copy2(filename, f"{filename}.backup") + + print(f"Processing file: {filename}") + print("Creating backup...") + + # Read the content of the file + with open(filename, 'r') as file: + content = file.read() + + # Use regex to replace `+code literal+` with `code literal` + pattern = r'`\+(.*?)\+`' + replaced_content, count = re.subn(pattern, r'`\1`', content) + + # Write the modified content back to the file + with open(filename, 'w') as file: + file.write(replaced_content) + + print(f"Replaced {count} instances of `+code literal+` syntax.") + print(f"Modified file saved as: {filename}") + print(f"Original file backed up as: {filename}.backup") + +if __name__ == "__main__": + filename = 'iam.adoc' + fix_code_literals(filename) \ No newline at end of file diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index c2940c7b6..83c94673f 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -142,7 +142,7 @@ https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] include::iam.adoc[leveloffset=+1] -//include::pods.adoc[leveloffset=+1] STILL ISSUES +include::pods.adoc[leveloffset=+1] //include::multitenancy.adoc[leveloffset=+1] ISSUES include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc index 4f4a000a3..d1c5ed25b 100644 --- a/latest/bpg/security/pods.adoc +++ b/latest/bpg/security/pods.adoc @@ -10,7 +10,7 @@ The pod specification includes a variety of different attributes that can strengthen or weaken your overall security posture. As a Kubernetes -practitioner your chief concern should be preventing a process that’s +practitioner your chief concern should be preventing a process that's running in a container from escaping the isolation boundaries of the container runtime and gaining access to the underlying host. @@ -27,7 +27,7 @@ assigned to containers. For additional information about each capability, see http://man7.org/linux/man-pages/man7/capabilities.7.html. -`+CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT+` +`CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT` !!! Info @@ -53,13 +53,13 @@ Read operations: * nodes * pods * secrets, configmaps, persistent volume claims and persistent volumes -related to pods bound to the kubelet’s node +related to pods bound to the kubelet's node Write operations: -* nodes and node status (enable the `+NodeRestriction+` admission plugin +* nodes and node status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify its own node) -* pods and pod status (enable the `+NodeRestriction+` admission plugin +* pods and pod status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify pods bound to itself) * events @@ -191,7 +191,7 @@ capabilities, along with several other restrictions. * *Restricted:* Heavily restricted policy, following current Pod hardening best practices. This policy inherits from the baseline and adds further restrictions such as the inability to run as root or a -root-group. Restricted policies may impact an application’s ability to +root-group. Restricted policies may impact an application's ability to function. They are primarily targeted at running security critical applications. @@ -235,8 +235,8 @@ pod(s) will be prevented from being applied. This is a difficult user experience, as there is no immediate indication that the successfully applied Deployment object belies failed pod creation. The offending podSpecs will not create pods. Inspecting the -Deployment resource with `+kubectl get deploy -oyaml+` -will expose the message from the failed pod(s) `+.status.conditions+` +Deployment resource with `kubectl get deploy -oyaml` +will expose the message from the failed pod(s) `.status.conditions` element, as seen below. [source,yaml] @@ -263,7 +263,7 @@ prevent violating pods from being created and started. However, in these modes audit annotations on API server audit log events and warnings to API server clients, such as _kubectl_, are triggered, respectively, when pods, as well as objects that create pods, contain podSpecs with -violations. A `+kubectl+` _Warning_ message is seen below. +violations. A `kubectl` _Warning_ message is seen below. [source,bash] ---- @@ -381,7 +381,7 @@ data: As seen in the above ConfigMap YAML the cluster-wide default PSS level has been set to _restricted_ for all PSA modes, _audit_, _enforce_, and _warn_. This affects all namespaces, except those exempted: -`+namespaces: ["kube-system","policy-test1"]+`. Additionally, in the +`namespaces: ["kube-system","policy-test1"]`. Additionally, in the _ValidatingWebhookConfiguration_ resource, seen below, the _pod-security-webhook_ namespace is also exempted from configured PSS. @@ -451,7 +451,7 @@ the Kubernetes API server (solution dependent) * Can be used to implement behaviors that are not necessarily security related, such as best practices, organizational standards, etc. * Can be used in non-Kubernetes use cases (solution dependent) -* Because of flexibility, the user experience can be tuned to users’ +* Because of flexibility, the user experience can be tuned to users' needs Cons: @@ -543,11 +543,11 @@ shell access to the running container. You can mitigate this risk a variety of ways. First, by removing the shell from the container image. Second, adding the USER directive to your Dockerfile or running the containers in the pod as a non-root user. The Kubernetes podSpec -includes a set of fields, under `+spec.securityContext+`, that let you +includes a set of fields, under `spec.securityContext`, that let you specify the user and/or group under which to run your application. These -fields are `+runAsUser+` and `+runAsGroup+` respectively. +fields are `runAsUser` and `runAsGroup` respectively. -To enforce the use of the `+spec.securityContext+`, and its associated +To enforce the use of the `spec.securityContext`, and its associated elements, within the Kubernetes podSpec, policy-as-code or Pod Security Standards can be added to clusters. These solutions allow you to write and/or use policies or profiles that can validate inbound Kubernetes API @@ -558,7 +558,7 @@ in some cases, generate new requests. === Never run Docker in Docker or mount the socket in the container While this conveniently lets you to build/run images in Docker -containers, you’re basically relinquishing complete control of the node +containers, you're basically relinquishing complete control of the node to the process running in the container. If you need to build container images on Kubernetes use https://github.com/GoogleContainerTools/kaniko[Kaniko], @@ -574,7 +574,7 @@ workloads. === Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only -`+hostPath+` is a volume that mounts a directory from the host directly +`hostPath` is a volume that mounts a directory from the host directly to the container. Rarely will pods need this type of access, but if they do, you need to be aware of the risks. By default pods that run as root will have write access to the file system exposed by hostPath. This @@ -582,7 +582,7 @@ could allow an attacker to modify the kubelet settings, create symbolic links to directories or files not directly exposed by the hostPath, e.g. /etc/shadow, install ssh keys, read secrets mounted to the host, and other malicious things. To mitigate the risks from hostPath, -configure the `+spec.containers.volumeMounts+` as `+readOnly+`, for +configure the `spec.containers.volumeMounts` as `readOnly`, for example: [source,yaml] @@ -594,12 +594,12 @@ volumeMounts: ---- You should also use policy-as-code solutions to restrict the directories -that can be used by `+hostPath+` volumes, or prevent `+hostPath+` usage +that can be used by `hostPath` volumes, or prevent `hostPath` usage altogether. You can use the Pod Security Standards _Baseline_ or -_Restricted_ policies to prevent the use of `+hostPath+`. +_Restricted_ policies to prevent the use of `hostPath`. For further information about the dangers of privileged escalation, read -Seth Art’s blog +Seth Art's blog https://labs.bishopfox.com/tech-blog/bad-pods-kubernetes-pod-privilege-escalation[Bad Pods: Kubernetes Pod Privilege Escalation]. @@ -608,36 +608,36 @@ Pods: Kubernetes Pod Privilege Escalation]. A pod without requests or limits can theoretically consume all of the resources available on a host. As additional pods are scheduled onto a node, the node may experience CPU or memory pressure which can cause the -Kubelet to terminate or evict pods from the node. While you can’t +Kubelet to terminate or evict pods from the node. While you can't prevent this from happening all together, setting requests and limits will help minimize resource contention and mitigate the risk from poorly written applications that consume an excessive amount of resources. -The `+podSpec+` allows you to specify requests and limits for CPU and +The `podSpec` allows you to specify requests and limits for CPU and memory. CPU is considered a compressible resource because it can be oversubscribed. Memory is incompressible, i.e. it cannot be shared among multiple containers. -When you specify _requests_ for CPU or memory, you’re essentially +When you specify _requests_ for CPU or memory, you're essentially designating the amount of _memory_ that containers are guaranteed to get. Kubernetes aggregates the requests of all the containers in a pod to determine which node to schedule the pod onto. If a container exceeds the requested amount of memory it may be subject to termination if -there’s memory pressure on the node. +there's memory pressure on the node. _Limits_ are the maximum amount of CPU and memory resources that a container is allowed to consume and directly corresponds to the -`+memory.limit_in_bytes+` value of the cgroup created for the container. +`memory.limit_in_bytes` value of the cgroup created for the container. A container that exceeds the memory limit will be OOM killed. If a container exceeds its CPU limit, it will be throttled. !!! Tip -When using container `+resources.limits+` it is strongly recommended +When using container `resources.limits` it is strongly recommended that container resource usage (a.k.a. Resource Footprints) be data-driven and accurate, based on load testing. Absent an accurate and -trusted resource footprint, container `+resources.limits+` can be -padded. For example, `+resources.limits.memory+` could be padded 20-30% +trusted resource footprint, container `resources.limits` can be +padded. For example, `resources.limits.memory` could be padded 20-30% higher than observable maximums, to account for potential memory resource limit inaccuracies. @@ -656,15 +656,15 @@ same values and not equal to 0, the pod is configured as _guaranteed_ (highest priority). Guaranteed pods will not be killed unless they exceed their configured memory limits. If the limits and requests are configured with different values and not equal to 0, or one container -within the pod sets limits and the others don’t or have limits set for +within the pod sets limits and the others don't or have limits set for different resources, the pods are configured as _burstable_ (medium priority). These pods have some resource guarantees, but can be killed once they exceed their requested memory. !!! Attention -Requests don’t affect the `+memory_limit_in_bytes+` value of the -container’s cgroup; the cgroup limit is set to the amount of memory +Requests don't affect the `memory_limit_in_bytes` value of the +container's cgroup; the cgroup limit is set to the amount of memory available on the host. Nevertheless, setting the requests value too low could cause the pod to be targeted for termination by the kubelet if the node undergoes memory pressure. @@ -678,7 +678,7 @@ node undergoes memory pressure. request memory |Best-Effort |lowest |limit & request Not Set |First to get killed when -there’s insufficient memory +there's insufficient memory |=== For additional information about resource QoS, please refer to the @@ -690,7 +690,7 @@ https://kubernetes.io/docs/concepts/policy/resource-quotas/[resource quota] on a namespace or by creating a https://kubernetes.io/docs/concepts/policy/limit-range/[limit range]. A resource quota allows you to specify the total amount of resources, -e.g. CPU and RAM, allocated to a namespace. When it’s applied to a +e.g. CPU and RAM, allocated to a namespace. When it's applied to a namespace, it forces you to specify requests and limits for all containers deployed into that namespace. By contrast, limit ranges give you more granular control of the allocation of resources. With limit @@ -710,8 +710,8 @@ with the SUID or SGID bit. Privileged escalation is basically a way for users to execute a file with the permissions of another user or group. You can prevent a container from using privileged escalation by implementing a policy-as-code mutating policy that sets -`+allowPrivilegeEscalation+` to `+false+` or by setting -`+securityContext.allowPrivilegeEscalation+` in the `+podSpec+`. +`allowPrivilegeEscalation` to `false` or by setting +`securityContext.allowPrivilegeEscalation` in the `podSpec`. Policy-as-code policies can also be used to prevent API server requests from succeeding if incorrect settings are detected. Pod Security Standards can also be used to prevent pods from using privilege @@ -754,24 +754,24 @@ automountServiceAccountToken: false === Disable service discovery For pods that do not need to lookup or call in-cluster services, you can -reduce the amount of information given to a pod. You can set the Pod’s -DNS policy to not use CoreDNS, and not expose services in the pod’s +reduce the amount of information given to a pod. You can set the Pod's +DNS policy to not use CoreDNS, and not expose services in the pod's namespace as environment variables. See the https://kubernetes.io/docs/concepts/services-networking/service/#environment-variables[Kubernetes docs on environment variables] for more information on service links. -The default value for a pod’s DNS policy is "`ClusterFirst`" which uses +The default value for a pod's DNS policy is "`ClusterFirst`" which uses in-cluster DNS, while the non-default value "`Default`" uses the -underlying node’s DNS resolution. See the +underlying node's DNS resolution. See the https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy[Kubernetes docs on Pod DNS policy] for more information. !!! Attention -Disabling service links and changing the pod’s DNS policy does not +Disabling service links and changing the pod's DNS policy does not prevent a pod from having network access to the in-cluster DNS service. An attacker can still enumerate services in a cluster by reaching the in-cluster DNS service. (ex: -`+dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP+`) To prevent +`dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP`) To prevent in-cluster service discovery, use a xref:iam-network-policy[NetworkPolicy] to block pod access @@ -792,7 +792,7 @@ Configuring your images with a read-only root file system prevents an attacker from overwriting a binary on the file system that your application uses. If your application has to write to the file system, consider writing to a temporary directory or attach and mount a volume. -You can enforce this by setting the pod’s SecurityContext as follows: +You can enforce this by setting the pod's SecurityContext as follows: [source,yaml] ---- @@ -808,8 +808,8 @@ behavior. !!! Info As per https://kubernetes.io/docs/concepts/windows/intro/[Windows -containers in Kubernetes] `+securityContext.readOnlyRootFilesystem+` -cannot be set to `+true+` for a container running on Windows as write +containers in Kubernetes] `securityContext.readOnlyRootFilesystem` +cannot be set to `true` for a container running on Windows as write access is required for registry and system processes to run inside the container. From 66613bbae09b465a6e3f00ad137fa3e020bb7efc Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 21:05:49 +0000 Subject: [PATCH 15/56] fixup --- latest/bpg/security/index.adoc | 2 +- latest/bpg/security/test.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 83c94673f..15b04497f 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -143,7 +143,7 @@ Security Immersion Workshop] include::iam.adoc[leveloffset=+1] include::pods.adoc[leveloffset=+1] -//include::multitenancy.adoc[leveloffset=+1] ISSUES +include::multitenancy.adoc[leveloffset=+1] include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] include::data.adoc[leveloffset=+1] diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index 9bc207ae3..b4fa87f8c 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -19,10 +19,10 @@ def run_build(header: str, content: str, test_description: str) -> bool: print("Building... (this may take about 30 seconds)") start_time = time.time() - if not os.path.exists('iam.adoc.backup'): - shutil.copy2('iam.adoc', 'iam.adoc.backup') + if not os.path.exists('multitenancy.adoc.backup'): + shutil.copy2('multitenancy.adoc', 'multitenancy.adoc.backup') - with open('iam.adoc', 'w') as f: + with open('multitenancy.adoc', 'w') as f: f.write(header + content) try: @@ -32,7 +32,7 @@ def run_build(header: str, content: str, test_description: str) -> bool: print(f"Build {'succeeded' if success else 'failed'} in {end_time - start_time:.2f} seconds") return success finally: - shutil.copy2('iam.adoc.backup', 'iam.adoc') + shutil.copy2('multitenancy.adoc.backup', 'multitenancy.adoc') def parse_sections(content: str) -> List[Section]: print("\nParsing AsciiDoc sections...") @@ -105,7 +105,7 @@ def suggest_fixes(section: Section) -> List[str]: def main(): print("Starting AsciiDoc debugging process...") - with open('iam.adoc', 'r') as f: + with open('multitenancy.adoc', 'r') as f: lines = f.readlines() header = ''.join(lines[:10]) content = ''.join(lines[10:]) @@ -131,7 +131,7 @@ def main(): print("\nNo specific problematic sections identified. The issue may be more complex or involve interactions between multiple sections.") print("\nDebugging process completed.") - print("Note: The original 'iam.adoc' file has been restored.") + print("Note: The original 'multitenancy.adoc' file has been restored.") if __name__ == "__main__": main() \ No newline at end of file From 8fb78e23e29f0bd5d1d2fc685392940b835f4f95 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 21:18:48 +0000 Subject: [PATCH 16/56] fixup --- latest/bpg/security/index.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 15b04497f..afcc4d613 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -143,7 +143,7 @@ Security Immersion Workshop] include::iam.adoc[leveloffset=+1] include::pods.adoc[leveloffset=+1] -include::multitenancy.adoc[leveloffset=+1] +//include::multitenancy.adoc[leveloffset=+1] include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] include::data.adoc[leveloffset=+1] From 465bc7f089847ac5c62dae102fc55e1f32fa19b3 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 21:49:42 +0000 Subject: [PATCH 17/56] gave up on security section for now --- latest/bpg/security/index.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index afcc4d613..06af18ed7 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -142,13 +142,13 @@ https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] include::iam.adoc[leveloffset=+1] -include::pods.adoc[leveloffset=+1] +//include::pods.adoc[leveloffset=+1] //include::multitenancy.adoc[leveloffset=+1] include::detective.adoc[leveloffset=+1] include::network.adoc[leveloffset=+1] include::data.adoc[leveloffset=+1] include::runtime.adoc[leveloffset=+1] -//include::hosts.adoc[leveloffset=+1] ISSUES +//include::hosts.adoc[leveloffset=+1] include::compliance.adoc[leveloffset=+1] include::incidents.adoc[leveloffset=+1] include::image.adoc[leveloffset=+1] From 07a085b5527e4c4ccf5700b0a0bf277619f0c318 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 17:25:35 -0500 Subject: [PATCH 18/56] add copy of cost opt guide --- latest/bpg/book.adoc | 2 + latest/bpg/cost/awareness.adoc | 228 +++++++++ latest/bpg/cost/cfm_framework.adoc | 77 +++ latest/bpg/cost/cost-effective.adoc | 399 +++++++++++++++ latest/bpg/cost/cost_opt_compute.adoc | 312 ++++++++++++ latest/bpg/cost/cost_opt_networking.adoc | 484 +++++++++++++++++++ latest/bpg/cost/cost_opt_observability.adoc | 350 ++++++++++++++ latest/bpg/cost/cost_opt_storage.adoc | 167 +++++++ latest/bpg/cost/cost_optimization_index.adoc | 41 ++ latest/bpg/cost/optimizing.adoc | 81 ++++ 10 files changed, 2141 insertions(+) create mode 100644 latest/bpg/cost/awareness.adoc create mode 100644 latest/bpg/cost/cfm_framework.adoc create mode 100644 latest/bpg/cost/cost-effective.adoc create mode 100644 latest/bpg/cost/cost_opt_compute.adoc create mode 100644 latest/bpg/cost/cost_opt_networking.adoc create mode 100644 latest/bpg/cost/cost_opt_observability.adoc create mode 100644 latest/bpg/cost/cost_opt_storage.adoc create mode 100644 latest/bpg/cost/cost_optimization_index.adoc create mode 100644 latest/bpg/cost/optimizing.adoc diff --git a/latest/bpg/book.adoc b/latest/bpg/book.adoc index 345f9c6d8..386965246 100644 --- a/latest/bpg/book.adoc +++ b/latest/bpg/book.adoc @@ -40,4 +40,6 @@ include::reliability/index.adoc[leveloffset=+1] include::security/index.adoc[leveloffset=+1] +include::cost/cfm_framework.adoc[leveloffset=+1] + diff --git a/latest/bpg/cost/awareness.adoc b/latest/bpg/cost/awareness.adoc new file mode 100644 index 000000000..f59aba551 --- /dev/null +++ b/latest/bpg/cost/awareness.adoc @@ -0,0 +1,228 @@ += Expenditure awareness + +Expenditure awareness is understanding who, where and what is causing expenditures in your EKS cluster. Getting an accurate picture of this data will help raise awareness of your spend and highlight areas to remediate. + +== Recommendations + +=== Use Cost Explorer + +https://aws.amazon.com/aws-cost-management/aws-cost-explorer/[AWS Cost Explorer] has an easy-to-use interface that lets you visualize, understand, and manage your AWS costs and usage over time. You can analyze cost and usage data, at various levels using the filters available in Cost Explorer. + +==== EKS Control Plane and EKS Fargate costs + +Using the filters, we can query the costs incurred for the EKS costs at the Control Plane and Fargate Pod as shown in the diagram below: + +image::../images/eks-controlplane-costexplorer.png[Cost Explorer - EKS Control Plane] + +Using the filters, we can query the aggregate costs incurred for the Fargate Pods across regions in EKS - which includes both vCPU-Hours per CPU and GB Hrs as shown in the diagram below: + +image::../images/eks-fargate-costexplorer.png[Cost Explorer - EKS Fargate] + +==== Tagging of Resources + +Amazon EKS supports https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html[adding AWS tags] to your Amazon EKS clusters. This makes it easy to control access to the EKS API for managing your clusters. Tags added to an EKS cluster are specific to the AWS EKS cluster resource, they do not propagate to other AWS resources used by the cluster such as EC2 instances or load balancers. Today, cluster tagging is supported for all new and existing EKS clusters via the AWS API, Console, and SDKs. + +AWS Fargate is a technology that provides on-demand, right-sized compute capacity for containers. Before you can schedule pods on Fargate in your cluster, you must define at least one Fargate profile that specifies which pods should use Fargate when they are launched. + +Adding and Listing tags to an EKS cluster: + + $ aws eks tag-resource --resource-arn arn:aws:eks:us-west-2:xxx:cluster/ekscluster1 --tags team=devops,env=staging,bu=cio,costcenter=1234 + $ aws eks list-tags-for-resource --resource-arn arn:aws:eks:us-west-2:xxx:cluster/ekscluster1 + { + "tags": { + "bu": "cio", + "env": "staging", + "costcenter": "1234", + "team": "devops" + } + } + +After you activate cost allocation tags in the https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html[AWS Cost Explorer], AWS uses the cost allocation tags to organize your resource costs on your cost allocation report, to make it easier for you to categorize and track your AWS costs. + +Tags don't have any semantic meaning to Amazon EKS and are interpreted strictly as a string of characters. For example, you can define a set of tags for your Amazon EKS clusters to help you track each cluster's owner and stack level. + +=== Use AWS Trusted Advisor + +AWS Trusted Advisor offers a rich set of best practice checks and recommendations across five categories: cost optimization; security; fault tolerance; performance; and service limits. + +For Cost Optimization, Trusted Advisor helps eliminate unused and idle resources and recommends making commitments to reserved capacity. The key action items that will help Amazon EKS will be around low utilsed EC2 instances, unassociated Elastic IP addresses, Idle Load Balancers, underutilized EBS volumes among other things. The complete list of checks are provided at https://aws.amazon.com/premiumsupport/technology/trusted-advisor/best-practice-checklist/. + +The Trusted Advisor also provides Savings Plans and Reserved Instances recommendations for EC2 instances and Fargate which allows you to commit to a consistent usage amount in exchange for discounted rates. + +!!! Note + that the recommendations from Trusted Advisor are generic recommendations and not specific to EKS. + +=== Use the Kubernetes dashboard + +*_Kubernetes dashboard_* + +Kubernetes Dashboard is a general purpose, web-based UI for Kubernetes clusters, which provides information about the Kubernetes cluster including the resource usage at a cluster, node and pod level. The deployment of the Kubernetes dashboard on an Amazon EKS cluster is described in the https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html[Amazon EKS documentation]. + +Dashboard provides resource usage breakdowns for each node and pod, as well as detailed metadata about pods, services, Deployments, and other Kubernetes objects. This consolidated information provides visibility into your Kubernetes environment. + +image::../images/kubernetes-dashboard.png[Kubernetes Dashboard] + +*_kubectl top and describe commands_* + +Viewing resource usage metrics with kubectl top and kubectl describe commands. kubectl top will show current CPU and memory usage for the pods or nodes across your cluster, or for a specific pod or node. The kubectl describe command will give more detailed information about a specific node or a pod. + + $ kubectl top pods + $ kubectl top nodes + $ kubectl top pod pod-name --namespace mynamespace --containers + +Using the top command, the output will displays the total amount of CPU (in cores) and memory (in MiB) that the node is using, and the percentages of the node's allocatable capacity those numbers represent. You can then drill-down to the next level, container level within pods by adding a _--containers_ flag. + + $ kubectl describe node + $ kubectl describe pod + +_kubectl describe_ returns the percent of total available capacity that each resource request or limit represents. + +kubectl top and describe, track the utilization and availability of critical resources such as CPU, memory, and storage across kubernetes pods, nodes and containers. This awareness will help in understanding resource usage and help in controlling costs. + +=== Use CloudWatch Container Insights + +Use https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html[CloudWatch Container Insights] to collect, aggregate, and summarize metrics and logs from your containerized applications and microservices. Container Insights is available for Amazon Elastic Kubernetes Service on EC2, and Kubernetes platforms on Amazon EC2. The metrics include utilization for resources such as CPU, memory, disk, and network. + +The installation of insights is given in the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html[documentation]. + +CloudWatch creates aggregated metrics at the cluster, node, pod, task, and service level as CloudWatch metrics. + +*The following query shows a list of nodes, sorted by average node CPU utilization* + +---- +STATS avg(node_cpu_utilization) as avg_node_cpu_utilization by NodeName +| SORT avg_node_cpu_utilization DESC +---- + +*CPU usage by Container name* + +---- +stats pct(container_cpu_usage_total, 50) as CPUPercMedian by kubernetes.container_name +| filter Type="Container" +---- + +*Disk usage by Container name* + +---- +stats floor(avg(container_filesystem_usage/1024)) as container_filesystem_usage_avg_kb by InstanceId, kubernetes.container_name, device +| filter Type="ContainerFS" +| sort container_filesystem_usage_avg_kb desc +---- + +More sample queries are given in the https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-view-metrics.html[Container Insights documention] + +This awareness will help in understanding resource usage and help in controlling costs. + +=== Using KubeCost for expenditure awareness and guidance + +Third party tools like https://kubecost.com/[kubecost] can also be deployed on Amazon EKS to get visibility into cost of running your Kubernetes cluster. Please refer to this https://aws.amazon.com/blogs/containers/how-to-track-costs-in-multi-tenant-amazon-eks-clusters-using-kubecost/[AWS blog] for tracking costs using Kubecost + +Deploying kubecost using Helm 3: + +[,console] +---- +$ curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash +$ helm version --short +v3.2.1+gfe51cd1 +$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/ +$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/c^C +$ kubectl create namespace kubecost +namespace/kubecost created +$ helm repo add kubecost https://kubecost.github.io/cost-analyzer/ +"kubecost" has been added to your repositories + +$ helm install kubecost kubecost/cost-analyzer --namespace kubecost --set kubecostToken="aGRoZEBqc2pzLmNvbQ==xm343yadf98" +NAME: kubecost +LAST DEPLOYED: Mon May 18 08:49:05 2020 +NAMESPACE: kubecost +STATUS: deployed +REVISION: 1 +TEST SUITE: None +NOTES: +--------------------------------------------------Kubecost has been successfully installed. When pods are Ready, you can enable port-forwarding with the following command: + + kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090 + +Next, navigate to http://localhost:9090 in a web browser. +$ kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090 + +Note: If you are using Cloud 9 or have a need to forward it to a different port like 8080, issue the following command +$ kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 8080:9090 +---- + +Kube Cost Dashboard - +image:../images/kube-cost.png[Kubernetes Cluster Auto Scaler logs] + +=== Use Kubernetes Cost Allocation and Capacity Planning Analytics Tool + +https://github.com/rchakode/kube-opex-analytics[Kubernetes Opex Analytics] is a tool to help organizations track the resources being consumed by their Kubernetes clusters to prevent overpaying. To do so it generates, short- (7 days), mid- (14 days) and long-term (12 months) usage reports showing relevant insights on what amount of resources each project is spending over time. + +image::../images/kube-opex-analytics.png[Kubernetes Opex Analytics] + +=== Magalix Kubeadvisor + +https://www.magalix.com/kubeadvisor[KubeAdvisor] continuously scans your Kubernetes clusters and reports how you can fix issues, apply best practices, and optimize your cluster (with recommendations of resources like CPU/Memory around cost-efficiency). + +=== Spot.io, previously called Spotinst + +Spotinst Ocean is an application scaling service. Similar to Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling groups, Spotinst Ocean is designed to optimize performance and costs by leveraging Spot Instances combined with On-Demand and Reserved Instances. Using a combination of automated Spot Instance management and the variety of instance sizes, the Ocean cluster autoscaler scales according to the pod resource requirements. Spotinst Ocean also includes a prediction algorithm to predict Spot Instance interruption 15 minutes ahead of time and spin up a new node in a different Spot capacity pool. + +This is available as an https://aws.amazon.com/quickstart/architecture/spotinst-ocean-eks/[AWS Quickstart] developed by Spotinst, Inc. in collaboration with AWS. + +The EKS workshop also has a module on https://eksworkshop.com/beginner/190_ocean/[Optimized Worker Node on Amazon EKS Management] with Ocean by Spot.io which includes sections on cost allocation, right sizing and scaling strategies. + +=== Yotascale + +Yotascale helps with accurately allocating Kubernetes costs. Yotascale Kubernetes Cost Allocation feature utilizes actual cost data, which is inclusive of Reserved Instance discounts and spot instance pricing instead of generic market-rate estimations, to inform the total Kubernetes cost footprint + +More details can be found at https://www.yotascale.com/[their website]. + +=== Alcide Advisor + +Alcide is an AWS Partner Network (APN) Advanced Technology Partner. Alcide Advisor helps ensure your Amazon EKS cluster, nodes, and pods configuration are tuned to run according to security best practices and internal guidelines. Alcide Advisor is an agentless service for Kubernetes audit and compliance that's built to ensure a frictionless and secured DevSecOps flow by hardening the development stage before moving to production. + +More details can be found in this https://aws.amazon.com/blogs/apn/driving-continuous-security-and-configuration-checks-for-amazon-eks-with-alcide-advisor/[blog post]. + +== Other tools + +=== Kubernetes Garbage Collection + +The role of the https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/[Kubernetes garbage collector] is to delete certain objects that once had an owner, but no longer have an owner. + +=== Fargate count + +https://github.com/mreferre/fargatecount[Fargatecount] is an useful tool, which allows AWS customers to track, with a custom CloudWatch metric, the total number of EKS pods that have been deployed on Fargate in a specific region of a specific account. This helps in keeping track of all the Fargate pods running across an EKS cluster. + +=== Kubernetes Ops View + +https://github.com/hjacobs/kube-ops-view[Kube Ops View] is an useful tool, which provides a common operational picture visually for multiple Kubernetes clusters. + +---- +git clone https://github.com/hjacobs/kube-ops-view +cd kube-ops-view +kubectl apply -k deploy/ +---- + +image::../images/kube-ops-report.png[Home Page] + +=== Popeye - A Kubernetes Cluster Sanitizer + +https://github.com/derailed/popeye[Popeye - A Kubernetes Cluster Sanitizer] is a utility that scans live Kubernetes cluster and reports potential issues with deployed resources and configurations. It sanitizes your cluster based on what's deployed and not what's sitting on disk. By scanning your cluster, it detects misconfigurations and helps you to ensure that best practices are in place + +=== Resources + +Refer to the following resources to learn more about best practices for cost optimization. + +Documentation and Blogs + +* https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html[Amazon EKS supports tagging] + +Tools + +* https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html[What is AWS Billing and Cost Management?] +* https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html[Amazon CloudWatch Container Insights] +* https://aws.amazon.com/blogs/containers/how-to-track-costs-in-multi-tenant-amazon-eks-clusters-using-kubecost/[How to track costs in multi-tenant Amazon EKS clusters using Kubecost] +* https://kubecost.com/[Kube Cost] +* https://github.com/hjacobs/kube-ops-view[Kube Opsview] +* https://github.com/hjacobs/kube-janitor[Kube Janitor] +* https://github.com/rchakode/kube-opex-analytics[Kubernetes Opex Analytics] diff --git a/latest/bpg/cost/cfm_framework.adoc b/latest/bpg/cost/cfm_framework.adoc new file mode 100644 index 000000000..947ec8065 --- /dev/null +++ b/latest/bpg/cost/cfm_framework.adoc @@ -0,0 +1,77 @@ +//!!NODE_ROOT +[[cost-opt,cost-opt.title]] += Cost Optimization - Introduction +:doctype: book +:sectnums: +:toc: left +:icons: font +:experimental: +:idprefix: +:idseparator: - +:sourcedir: . +:info_doctype: chapter +:info_title: Best Practices for Cost Optimization +:info_abstract: Best Practices for Cost Optimization +:info_titleabbrev: Cost Optimization +:imagesdir: images/ + +AWS Cloud Economics is a discipline that helps customers increase efficiency and reduce their costs through the adoption of modern compute technologies like Amazon EKS. The discipline recommends following a methodology called the "`Cloud Financial Management (CFM) framework`" which consists of 4 pillars: + +image::../images/cfm_framework.png[CFM Framework] + +== The See pillar: Measurement and accountability + +The See pillar is a foundational set of activities and technologies that define how to measure, monitor and create accountability for cloud spend. It is often referred to as "`Observability`", "`Instrumentation`", or "`Telemetry`". The capabilities and limitations of the "`Observability`" infrastructure dictate what can be optimized. Obtaining a clear picture of your costs is a critical first step in cost optimization as you need to know where you are starting from. This type of visibility will also guide the types of activities you will need to do to further optimize your environment. + +Here is a brief overview of our best practices for the See pillar: + +* Define and maintain a tagging strategy for your workloads. + ** Use https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html#tag-resources-for-billing[Instance Tagging], tagging EKS clusters allows you to see individual cluster costs and allocate them in your Cost & Usage Reports. +* Establish reporting and monitoring of EKS usage by using technologies like https://docs.kubecost.com/install-and-configure/install/provider-installations/aws-eks-cost-monitoring[Kubecost]. + ** https://wellarchitectedlabs.com/cost/200_labs/200_enterprise_dashboards/[Enable Cloud Intelligence Dashboards], by having resources properly tagged and using visualizations, you can measure and estimate costs. +* Allocate cloud costs to applications, Lines of Business (LoBs), and revenue streams. +* Define, measure, and circulate efficiency/value KPIs with business stakeholders. For example, create a "`unit metric`" KPI that measures the cost per transaction, e.g. a ride sharing services might have a KPI for "`cost per ride`". + +For more details on the recommended technologies and activities associated with this pillar, please see the xref:cost-opt-observability[Cost Optimization - Observability] section of this guide. + +== The Save pillar: Cost optimization + +This pillar is based on the technologies and capabilities developed in the "`See`" pillar. The following activities typically fall under this pillar: + +* Identify and eliminate waste in your environment. +* Architect and design for cost efficiency. +* Choose the best purchasing option, e.g. on-demand instances vs Spot instances. +* Adapt as services evolve: as AWS services evolve, the way to efficiently use those services may change. Be willing to adapt to account for these changes. + +Since these activities are operational, they are highly dependent on your environment's characteristics. Ask yourself, what are the main drivers of costs? What business value do your different environments provide? What purchasing options and infrastructure choices, e.g. instance family types, are best suited for each environment? + +Below is a prioritized list of the most common cost drivers for EKS clusters: + +. *Compute costs:* Combining multiple types of instance families, purchasing options, and balancing scalability with availability require careful consideration. For further information, see the recommendations in the xref:cost-opt-compute[Cost Optimization - Compute] section of this guide. +. *Networking costs:* using 3 AZs for EKS clusters can potentially increase inter-AZ traffic costs. For our recommendations on how to balance HA requirements with keeping network traffic costs down, please consult the xref:cost-opt-networking[Cost Optimization - Networking] section of this guide. +. *Storage costs:* Depending on the stateful/stateless nature of the workloads in the EKS clusters, and how the different storage types are used, storage can be considered as part of the workload. For considerations relating to EKS storage costs, please consult the xref:cost-opt-storage[Cost Optimization - Storage] section of this guide. + +== The Plan pillar: Planning and forecasting + +Once the recommendations in the See pillar are implemented, clusters are optimized on an on-going basis. As experience is gained in operating clusters efficiently, planning and forecasting activities can focus on: + +* Budgeting and forecasting cloud costs dynamically. +* Quantifying the business value delivered by EKS container services. +* Integrating EKS cluster cost management with IT financial management planning. + +== The Run pillar + +Cost optimization is a continuous process and involves a flywheel of incremental improvements: + +image::../images/flywheel.png[Cost optimization flywheel] + +Securing executive sponsorship for these types of activities is crucial for integrating EKS cluster optimization into the organization's "`FinOps`" efforts. It allows stakeholder alignment through a shared understanding of EKS cluster costs, implementation of EKS cluster cost guardrails, and ensuring that the tooling, automation, and activities evolve with the organization's needs. + +== References + +* https://aws.amazon.com/aws-cost-management/[AWS Cloud Economics, Cloud Financial Management] + +include::cost_opt_compute.adoc[leveloffset=+1] +include::cost_opt_networking.adoc[leveloffset=+1] +include::cost_opt_storage.adoc[leveloffset=+1] +include::cost_opt_observability.adoc[leveloffset=+1] \ No newline at end of file diff --git a/latest/bpg/cost/cost-effective.adoc b/latest/bpg/cost/cost-effective.adoc new file mode 100644 index 000000000..7612cf223 --- /dev/null +++ b/latest/bpg/cost/cost-effective.adoc @@ -0,0 +1,399 @@ += Cost-effective resources + +Cost Effective resources means using the appropriate services, resources, and configurations for your workloads running on a Kubernetes cluster, which will result in cost savings. + +== Recommendations + +=== Ensure that the infrastructure used to deploy the containerized service matches the application profile and scaling needs + +There are several types of Kubernetes autoscaling supported in Amazon EKS - https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html[Cluster Autoscaler], https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html[Horizontal Pod Autoscaler] and https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html[Vertical Pod Autoscaler]. This section covers two of them, Cluster Auto Scaler and Horizontal Pod Autoscaler. + +=== Use Cluster Autoscaler to adjust the size of a Kubernetes cluster to meet the current needs + +The https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler[Kubernetes Cluster Autoscaler] automatically adjusts the number of nodes in the EKS cluster when pods fail to launch due to lack of resources or when nodes in the cluster are underutilized and their pods can be rescheduled onto other nodes in the cluster. The Cluster Autoscaler scales worker nodes within any specified Auto Scaling group and runs as a deployment in your EKS cluster. + +Amazon EKS with EC2 managed node groups automate the provisioning and lifecycle management of nodes (Amazon EC2 instances) for Amazon EKS Kubernetes clusters. All managed nodes are provisioned as part of an Amazon EC2 Auto Scaling group that is managed for you by Amazon EKS and all resources including Amazon EC2 instances and Auto Scaling groups run within your AWS account. Amazon EKS tags managed node group resources so that they can be discovered the Kubernetes Cluster Autoscaler. + +The documentation at https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html provides detailed guidance on setting up a Managed Node Group and then deploying Kubernetes Cluster Auto Scaler. If you are running a stateful application across multiple Availability Zones that is backed by Amazon EBS volumes and using the Kubernetes Cluster Autoscaler, you should configure multiple node groups, each scoped to a single Availability Zone. + +_Cluster Autoscaler logs for EC2 based Worker Nodes -_ +image:../images/cluster-auto-scaler.png[Kubernetes Cluster Auto Scaler logs] + +When a pod cannot be scheduled due to lack of available resources, Cluster Autoscaler determines that the cluster must scale out and increases the size of the node group. When multiple node groups are used, Cluster Autoscaler chooses one based on the Expander configuration. Currently, the following strategies are supported in EKS: + +* *random* - default expander, selects the instance group randomly +* *most-pods* - selects the instance group that schedules the most amount of pods. +* *least-waste* - selects the node group that will have the least idle CPU (if tied, unused memory) after scale-up. This is useful when you have different classes of nodes, for example, high CPU or high memory nodes, and only want to expand those when there are pending pods that need a lot of those resources. +* *priority* - selects the node group that has the highest priority assigned by the user + +You can use the *random* placement strategy for the Expander in Cluster Autoscaler, if EC2 Spot instances are being used as worker nodes. This is the default expander, and arbitrarily chooses a node-group when the cluster must scale out. The random expander maximizes your ability to leverage multiple Spot capacity pools. + +https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/expander/priority/readme.md[*Priority*] based expander selects an expansion option based on priorities assigned by a user to scaling groups. Sample priorities can be to let Autoscaler first try to scale out a spot instance node group and then, if it cannot, falls back to scaling out an on-demand node group. + +*most-pods* based expander is useful when you are using nodeSelector to make sure certain pods land on certain nodes. + +From the https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html[documentation] to specify *least-waste* as the expander type for the Cluster Autoscaling configuration: + +---- + spec: + containers: + - command: + - ./cluster-autoscaler + - --v=4 + - --stderrthreshold=info + - --cloud-provider=aws + - --skip-nodes-with-local-storage=false + - --expander=least-waste + - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/ + - --balance-similar-node-groups + - --skip-nodes-with-system-pods=false +---- + +=== Deploy Horizontal Pod Autoscaling to automatically scales the number of pods in a deployment, replication controller, or replica set based on that resource's CPU utilization or other application related metrics + +The https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/[Kubernetes Horizontal Pod Autoscaler] automatically scales the number of pods in a deployment, replication controller, or replica set based on resource metrics like CPU utilization or with custom metrics support, on some other application-provided metrics. This can help your applications scale out to meet increased demand or scale in when resources are not needed, thus freeing up your worker nodes for other applications. When you set a target metric utilization percentage, the Horizontal Pod Autoscaler scales your application in or out to try to meet that target. + +The https://github.com/awslabs/k8s-cloudwatch-adapter[k8s-cloudwatch-adapter] is an implementation of the Kubernetes Custom Metrics API and External Metrics API with integration for CloudWatch metrics. It allows you to scale your Kubernetes deployment using the Horizontal Pod Autoscaler (HPA) with CloudWatch metrics. + +For an example of scaling using a resource metric like CPU, follow https://eksworkshop.com/beginner/080_scaling/test_hpa/ to deploy a sample app, perform a simple load test to test the autoscaling of pod and simulate pod autoscaling. + +Refer to this https://aws.amazon.com/blogs/compute/scaling-kubernetes-deployments-with-amazon-cloudwatch-metrics/[blog] for an example of a custom metric for an application to scale according to the number of messages in the Amazon SQS (Simple Queue Service) queue. + +An example of an external metric from Amazon SQS from the blog: + +[,yaml] +---- +apiVersion: metrics.aws/v1alpha1 +kind: ExternalMetric: + metadata: + name: hello-queue-length + spec: + name: hello-queue-length + resource: + resource: "deployment" + queries: + - id: sqs_helloworld + metricStat: + metric: + namespace: "AWS/SQS" + metricName: "ApproximateNumberOfMessagesVisible" + dimensions: + - name: QueueName + value: "helloworld" + period: 300 + stat: Average + unit: Count + returnData: true +---- + +An example of an HPA utilizing this external metric: + +[,yaml] +---- +kind: HorizontalPodAutoscaler +apiVersion: autoscaling/v2beta1 +metadata: + name: sqs-consumer-scaler +spec: + scaleTargetRef: + apiVersion: apps/v1beta1 + kind: Deployment + name: sqs-consumer + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: External + external: + metricName: hello-queue-length + targetAverageValue: 30 +---- + +The combination of Cluster Auto Scaler for the Kubernetes worker nodes and Horizontal Pod Autoscaler for the pods, will ensure that the provisioned resources will be as close to the actual utilization as possible. + +image:../images/ClusterAS-HPA.png[Kubernetes Cluster AutoScaler and HPA] +*_(Image source: https://aws.amazon.com/blogs/containers/cost-optimization-for-kubernetes-on-aws/)_* + +*_Amazon EKS with Fargate_* + +***Horizontal Pod Autoscaling of Pods*** + +Autoscaling EKS on Fargate can be done using the following mechanisms: + +. Using the Kubernetes metrics server and configure auto-scaling based on CPU and/or memory usage. +. Configure autoscaling based on custom metrics like HTTP traffic using Prometheus and Prometheus metrics adapter +. Configure autoscaling based on App Mesh traffic + +The above scenarios are explained in a hands-on blog on https://aws.amazon.com/blogs/containers/autoscaling-eks-on-fargate-with-custom-metrics/["Autoscaling EKS on Fargate with custom metrics] + +***Vertical Pod Autoscaling*** + +Use the https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html[Vertical Pod Autoscaler] with pods running on Fargate to optimize the CPU and memory used for your applications. However, because changing the resource allocation for a pod requires the pod to be restarted, you must set the pod update policy to either Auto or Recreate to ensure correct functionality. + +== Recommendations + +=== Use Down Scaling to scale down Kubernetes Deployments, StatefulSets, and/or HorizontalPodAutoscalers during non-work hours. + +As part of controlling costs Down-Scaling resources that are not in-use can also have an huge impact on the overall costs. There are tools like https://github.com/hjacobs/kube-downscaler[kube-downscaler] and https://github.com/kubernetes-sigs/descheduler[Descheduler for Kubernetes]. + +*Kube-descaler*, can be used to Scale down Kubernetes deployments after work hours or during set periods of time. + +*Descheduler for Kubernetes*, based on its policy, can find pods that can be moved and evicts them. In its current implementation, the kubernetes descheduler does not reschedule evicted pods but relies on the default scheduler for that + +*Kube-descaler* + +_Installation of kube-downscaler_: + +---- +git clone https://github.com/hjacobs/kube-downscaler +cd kube-downscaler +kubectl apply -k deploy/ +---- + +The example configuration uses the --dry-run as a safety flag to prevent downscaling -- remove it to enable the downscaler, e.g. by editing the deployment: + + $ kubectl edit deploy kube-downscaler + +Deploy an nginx pod and schedule it to be run in the time zone - Mon-Fri 09:00-17:00 Asia/Kolkata: + + $ kubectl run nginx1 --image=nginx + $ kubectl annotate deploy nginx1 'downscaler/uptime=Mon-Fri 09:00-17:00 Asia/Kolkata' + +!!! note + The default grace period of 15 minutes applies to the new nginx deployment, i.e. if the current time is not within Mon-Fri 9-17 (Asia/Kolkata timezone), it will downscale not immediately, but after 15 minutes. + +image::../images/kube-down-scaler.png[Kube-down-scaler for nginx] + +More advanced downscaling deployment scenarios are available at the https://github.com/hjacobs/kube-downscaler[kube-down-scaler github project]. + +*Kubernetes descheduler* + +The descheduler can be run as a Job or CronJob inside of a k8s cluster. Descheduler's policy is configurable and includes strategies that can be enabled or disabled. Seven strategies _RemoveDuplicates_, _LowNodeUtilization_, _RemovePodsViolatingInterPodAntiAffinity_, _RemovePodsViolatingNodeAffinity_, _RemovePodsViolatingNodeTaints_, _RemovePodsHavingTooManyRestarts_, and _PodLifeTime_ are currently implemented. More details can be found in their https://github.com/kubernetes-sigs/descheduler[documentation]. + +A sample policy, which has the descheduler enabled for lowcpuutilization of nodes (where it covers the scenarios for both underutilized and overutilized), removing pods for too many restarts and others : + +[,yaml] +---- +apiVersion: "descheduler/v1alpha1" +kind: "DeschedulerPolicy" +strategies: + "RemoveDuplicates": + enabled: true + "RemovePodsViolatingInterPodAntiAffinity": + enabled: true + "LowNodeUtilization": + enabled: true + params: + nodeResourceUtilizationThresholds: + thresholds: + "cpu" : 20 + "memory": 20 + "pods": 20 + targetThresholds: + "cpu" : 50 + "memory": 50 + "pods": 50 + "RemovePodsHavingTooManyRestarts": + enabled: true + params: + podsHavingTooManyRestarts: + podRestartThresholds: 100 + includingInitContainers: true +---- + +*Cluster Turndown* + +https://github.com/kubecost/cluster-turndown[Cluster Turndown] is an automated scaledown and scaleup of a Kubernetes cluster's backing nodes based on a custom schedule and turndown criteria. This feature can be used to reduce spend during down hours and/or reduce surface area for security reasons. The most common use case is to scale non-prod environments (e.g. dev clusters) to zero during off hours. Cluster Turndown is currently in ALPHA release. + +Cluster Turndown uses a Kubernetes Custom Resource Definition to create schedules. The following schedule will create a schedule that starts by turning down at the designated start date-time and turning back up at the designated end date-time (times should be in RFC3339 format, i.e. times based on offsets to UTC). + +[,yaml] +---- +apiVersion: kubecost.k8s.io/v1alpha1 +kind: TurndownSchedule +metadata: + name: example-schedule + finalizers: + - "finalizer.kubecost.k8s.io" +spec: + start: 2020-03-12T00:00:00Z + end: 2020-03-12T12:00:00Z + repeat: daily +---- + +=== Use LimitRanges and Resource Quotas to help manage costs by constraining the amount of resources allocated at an Namespace level + +By default, containers run with unbounded compute resources on a Kubernetes cluster. With resource quotas, cluster administrators can restrict resource consumption and creation on a namespace basis. Within a namespace, a Pod or Container can consume as much CPU and memory as defined by the namespace's resource quota. There is a concern that one Pod or Container could monopolize all available resources. + +Kubernetes controls the allocation of resources such as CPU, memory, PersistentVolumeClaims and others using Resource Quotas and Limit Ranges. ResourceQuota is at the Namespace level, while a LimitRange applies at an container level. + +*_Limit Ranges_* + +A LimitRange is a policy to constrain resource allocations (to Pods or Containers) in a namespace. + +The following is an example of setting an default memory request and a default memory limit using Limit Range. + +[,yaml] +---- +apiVersion: v1 +kind: LimitRange +metadata: + name: mem-limit-range +spec: + limits: + - default: + memory: 512Mi + defaultRequest: + memory: 256Mi + type: Container +---- + +More examples are available in the https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/[Kubernetes documentation]. + +*_Resource Quotas_* + +When several users or teams share a cluster with a fixed number of nodes, there is a concern that one team could use more than its fair share of resources. Resource quotas are a tool for administrators to address this concern. + +The following is an example of how to set quotas for the total amount memory and CPU that can be used by all Containers running in a namespace, by specifying quotas in a ResourceQuota object. This specifies that a Container must have a memory request, memory limit, cpu request, and cpu limit, and should not exceed the threshold set in the ResourceQuota. + +[,yaml] +---- +apiVersion: v1 +kind: ResourceQuota +metadata: + name: mem-cpu-demo +spec: + hard: + requests.cpu: "1" + requests.memory: 1Gi + limits.cpu: "2" + limits.memory: 2Gi +---- + +More examples are available in the https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/[Kubernetes documentation]. + +=== Use pricing models for effective utilization + +The pricing details for Amazon EKS are given in the https://aws.amazon.com/eks/pricing/[pricing page]. There is a common control plane cost for both Amazon EKS on Fargate and EC2. + +If you are using AWS Fargate, pricing is calculated based on the vCPU and memory resources used from the time you start to download your container image until the Amazon EKS pod terminates, rounded up to the nearest second. A minimum charge of 1 minute applies. See detailed pricing information on the https://aws.amazon.com/fargate/pricing/[AWS Fargate pricing page]. + +*_Amazon EKS on EC2:_* + +Amazon EC2 provides a wide selection of https://aws.amazon.com/ec2/instance-types/[instance types] optimized to fit different use cases. Instance types comprise varying combinations of CPU, memory, storage, and networking capacity and give you the flexibility to choose the appropriate mix of resources for your applications. Each instance type includes one or more instance sizes, allowing you to scale your resources to the requirements of your target workload. + +One of the key decision parameters apart from number of CPUs, memory, processor family type related to the instance type is the https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html[number of Elastic network interfaces(ENI's)], which in-turn has a bearing on the maximum number of pods you can run on that EC2 Instance. The list of https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt[max pods per EC2 Instance type] is maintained in a github. + +***On-Demand EC2 Instances:*** + +With https://aws.amazon.com/ec2/pricing/[On-Demand instances], you pay for compute capacity by the hour or the second depending on which instances you run. No longer-term commitments or upfront payments are needed. + +Amazon EC2 A1 instances deliver significant cost savings and are ideally suited for scale-out and ARM-based workloads that are supported by the extensive Arm ecosystem. You can now use Amazon Elastic Container Service for Kubernetes (EKS) to run containers on Amazon EC2 A1 Instances as part of a https://github.com/aws/containers-roadmap/tree/master/preview-programs/eks-arm-preview[public developer preview]. Amazon ECR now supports https://aws.amazon.com/blogs/containers/introducing-multi-architecture-container-images-for-amazon-ecr/[multi-architecture container images], which makes it simpler to deploy container images for different architectures and operating systems from the same image repository. + +You can use the https://calculator.s3.amazonaws.com/index.html[AWS Simple Monthly Calculator] or the new https://calculator.aws/[pricing calculator] to get pricing for the On-Demand EC2 instances for the EKS workder nodes. + +=== Use Spot EC2 Instances: + +Amazon https://aws.amazon.com/ec2/pricing/[EC2 Spot instances] allow you to request spare Amazon EC2 computing capacity for up to 90% off the On-Demand price. + +Spot Instances are often a great fit for stateless containerized workloads because the approach to containers and Spot Instances are similar; ephemeral and autoscaled capacity. This means they both can be added and removed while adhering to SLAs and without impacting the performance or availability of your applications. + +You can create multiple nodegroups with a mix of on-demand instance types and EC2 Spot instances to leverage the advantages of pricing between these two instance types. + +image:../images/spot_diagram.png[On-Demand and Spot Node Groups] +*_(Image source: https://ec2spotworkshops.com/using_ec2_spot_instances_with_eks/spotworkers/workers_eksctl.html)_* + +A sample yaml file for eksctl to create a nodegroup with EC2 spot instances is given below. During the creation of the Node Group, we have configured a node-label so that kubernetes knows what type of nodes we have provisioned. We set the lifecycle for the nodes as Ec2Spot. We are also tainting with PreferNoSchedule to prefer pods not be scheduled on Spot Instances. This is a "`preference`" or "`soft`" version of NoSchedule, i.e. the system will try to avoid placing a pod that does not tolerate the taint on the node, but it is not required. We are using this technique to make sure that only the right type of workloads are scheduled on Spot Instances. + +[,yaml] +---- +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig +metadata: + name: my-cluster-testscaling + region: us-west-2 +nodeGroups: + - name: ng-spot + labels: + lifecycle: Ec2Spot + taints: + spotInstance: true:PreferNoSchedule + minSize: 2 + maxSize: 5 + instancesDistribution: # At least two instance types should be specified + instanceTypes: + - m4.large + - c4.large + - c5.large + onDemandBaseCapacity: 0 + onDemandPercentageAboveBaseCapacity: 0 # all the instances will be spot instances + spotInstancePools: 2 +---- + +Use the node-labels to identify the lifecycle of the nodes. + + $ kubectl get nodes --label-columns=lifecycle --selector=lifecycle=Ec2Spot + +We should also deploy the https://github.com/aws/aws-node-termination-handler[AWS Node Termination Handler] on each Spot Instance. This will monitor the EC2 metadata service on the instance for an interruption notice. The termination handler consists of a ServiceAccount, ClusterRole, ClusterRoleBinding, and a DaemonSet. AWS Node Termination Handler is not only for Spot Instances, it can also catch general EC2 maintenance events, so it can be used across all the worker nodes in the cluster. + +If a customer is well diversified and uses the capacity-optimized allocation strategy, Spot Instances will be available. You can use Node Affinity in your manifest file to configure this, to prefer Spot Instances, but not require them. This would allow the pods to be scheduled on On-Demand nodes if no spot instances were available or correctly labelled. + +[,yaml] +---- + +affinity: +nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: lifecycle + operator: In + values: + - Ec2Spot +tolerations: +- key: "spotInstance" +operator: "Equal" +value: "true" +effect: "PreferNoSchedule" +---- + +You can do a complete workshop with EC2 spot instances at the https://ec2spotworkshops.com/using_ec2_spot_instances_with_eks.html[online EC2 Spot Workshop]. + +=== Use Compute Savings Plan + +Compute Savings Plans, a flexible discount model that provides you with the same discounts as Reserved Instances, in exchange for a commitment to use a specific amount (measured in dollars per hour) of compute power over a one or three year period. The details are covered in the https://aws.amazon.com/savingsplans/faq/[Savings Plan launch FAQ].The plans automatically apply to any EC2 worker node regardless of region, instance family, operating system, or tenancy, including those that are part of EKS clusters. For example, you can shift from C4 to C5 instances, move a workload from Dublin to London benefiting from Savings Plan prices along the way, without having to do anything. + +The AWS Cost Explorer will help you to choose a Savings Plan, and will guide you through the purchase process. +image:../images/Compute-savings-plan.png[Compute Savings Plan] + +Note - The compute savings plans now also applies to https://aws.amazon.com/about-aws/whats-new/2020/08/amazon-fargate-aws-eks-included-compute-savings-plan/[AWS Fargate for AWS Elastic Kubernetes Service (EKS)]. + +Note - The above pricing does not include the other AWS services like Data transfer charges, CloudWatch, Elastic Load Balancer and other AWS services that may be used by the Kubernetes applications. + +== Resources + +Refer to the following resources to learn more about best practices for cost optimization. + +=== Videos + +* https://www.youtube.com/watch?v=7q5AeoKsGJw[AWS re:Invent 2019: Save up to 90% and run production workloads on Spot Instances (CMP331-R1)] + +=== Documentation and Blogs + +* https://aws.amazon.com/blogs/containers/cost-optimization-for-kubernetes-on-aws/[Cost optimization for Kubernetes on AWS] +* https://aws.amazon.com/blogs/compute/cost-optimization-and-resilience-eks-with-spot-instances/[Building for Cost optimization and Resilience for EKS with Spot Instances] +* https://aws.amazon.com/blogs/containers/autoscaling-eks-on-fargate-with-custom-metrics/[Autoscaling EKS on Fargate with custom metrics] +* https://docs.aws.amazon.com/eks/latest/userguide/fargate.html[AWS Fargate considerations] +* https://ec2spotworkshops.com/using_ec2_spot_instances_with_eks.html[Using Spot Instances with EKS] +* https://aws.amazon.com/blogs/containers/eks-managed-node-groups/[Extending the EKS API: Managed Node Groups] +* https://docs.aws.amazon.com/eks/latest/userguide/autoscaling.html[Autoscaling with Amazon EKS] +* https://aws.amazon.com/eks/pricing/[Amazon EKS pricing] +* https://aws.amazon.com/fargate/pricing/[AWS Fargate pricing] +* https://docs.aws.amazon.com/savingsplans/latest/userguide/what-is-savings-plans.html[Savings Plan] +* https://srcco.de/posts/saving-cloud-costs-kubernetes-aws.html[Saving Cloud Costs with Kubernetes on AWS] + +=== Tools + +* https://github.com/hjacobs/kube-downscaler[Kube downscaler] +* https://github.com/kubernetes-sigs/descheduler[Kubernetes Descheduler] +* https://github.com/kubecost/cluster-turndown[Cluster TurnDown] diff --git a/latest/bpg/cost/cost_opt_compute.adoc b/latest/bpg/cost/cost_opt_compute.adoc new file mode 100644 index 000000000..e454514dd --- /dev/null +++ b/latest/bpg/cost/cost_opt_compute.adoc @@ -0,0 +1,312 @@ +//!!NODE_ROOT
+[."topic"] +[[cost-opt-compute,cost-opt-compute.title]] += Cost Optimization - Compute and Autoscaling +:info_doctype: section +:imagesdir: images/ +:info_title: Compute and Autoscaling +:info_abstract: Compute and Autoscaling +:info_titleabbrev: Compute and Autoscaling +:authors: ["Justin Garrison", "Rajdeep Saha"] +:date: 2023-09-29 + +As a developer, you'll make estimates about your application's resource requirements, e.g. CPU and memory, but if you're not continually adjusting them they may become outdated which could increase your costs and worsen performance and reliability. Continually adjusting an application's resource requirements is more important than getting them right the first time. + +The best practices mentioned below will help you build and operate cost-aware workloads that achieve business outcomes while minimizing costs and allowing your organization to maximize its return on investment. A high level order of importance for optimizing your cluster compute costs are: + +. Right-size workloads +. Reduce unused capacity +. Optimize compute capacity types (e.g. Spot) and accelerators (e.g. GPUs) + +== Right-size your workloads + +In most EKS clusters, the bulk of cost come from the EC2 instances that are used to run your containerized workloads. You will not be able to right-size your compute resources without understanding your workloads requirements. This is why it is essential that you use the appropriate requests and limits and make adjustments to those settings as necessary. In addition, dependencies, such as instance size and storage selection, may effect workload performance which can have a variety of unintended consequences on costs and reliability. + +_Requests_ should align with the actual utilization. If a container's requests are too high there will be unused capacity which is a large factor in total cluster costs. Each container in a pod, e.g. application and sidecars, should have their own requests and limits set to make sure the aggregate pod limits are as accurate as possible. + +Utilize tools such as https://www.youtube.com/watch?v=DfmQWYiwFDk[Goldilocks], https://www.youtube.com/watch?v=uITOzpf82RY[KRR], and https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/[Kubecost] which estimate resource requests and limits for your containers. Depending on the nature of the applications, performance/cost requirements, and complexity you need to evaluate which metrics are best to scale on, at what point your application performance degrades (saturation point), and how to tweak request and limits accordingly. Please refer to https://aws.github.io/aws-eks-best-practices/scalability/docs/node_efficiency/#application-right-sizing[Application right sizing] for further guidance on this topic. + +We recommend using the Horizontal Pod Autoscaler (HPA) to control how many replicas of your application should be running, the Vertical Pod Autoscaler (VPA) to adjust how many requests and limits your application needs per replica, and a node autoscaler like http://karpenter.sh/[Karpenter] or https://github.com/kubernetes/autoscaler[Cluster Autoscaler] to continually adjust the total number of nodes in your cluster. Cost optimization techniques using Karpenter and Cluster Autoscaler are documented in a later section of this document. + +The Vertical Pod Autoscaler can adjust the requests and limits assigned to containers so workloads run optimally. You should run the VPA in auditing mode so it does not automatically make changes and restart your pods. It will suggest changes based on observed metrics. With any changes that affect production workloads you should review and test those changes first in a non-production environment because these can have impact on your application's reliability and performance. + +== Reduce consumption + +The best way to save money is to provision fewer resources. One way to do that is to adjust workloads based on their current requirements. You should start any cost optimization efforts with making sure your workloads define their requirements and scale dynamically. This will require getting metrics from your applications and setting configurations such as https://kubernetes.io/docs/tasks/run-application/configure-pdb/[`PodDisruptionBudgets`] and https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.5/deploy/pod_readiness_gate/[Pod Readiness Gates] to make sure your application can safely scale up and down dynamically. Its important to consider that restrictive PodDisruptionBudgets can prevent Cluster Autoscaler and Karpenter from scaling down Nodes, since both Cluster Autoscaler and Karpenter respect PodDisruptionBudgets. The 'minAvailable' value in the PodDisruptionBudget should always be lower than the number of pods in the deployment and you should keep a good buffer between the two e.g. In a deployment of 6 pods where you want a minimum of 4 pods running at all times, set the 'minAvailable' in your PodDisruptionBidget to 4. This will allow Cluster Autoscaler and Karpenter to safely drain and evict pods from the under-utilized nodes during a Node scale-down event. Please refer to https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node[Cluster Autoscaler FAQ] doc. + +The Horizontal Pod Autoscaler is a flexible workload autoscaler that can adjust how many replicas are needed to meet the performance and reliability requirements of your application. It has a flexible model for defining when to scale up and down based on various metrics such as CPU, memory, or custom metrics e.g. queue depth, number of connections to a pod, etc. + +The Kubernetes Metrics Server enables scaling in response to built-in metrics like CPU and memory usage, but if you want to scale based on other metrics, such as Amazon CloudWatch or SQS queue depth, you should consider event driven autoscaling projects such as https://keda.sh/[KEDA]. Please refer to https://aws.amazon.com/blogs/mt/proactive-autoscaling-of-kubernetes-workloads-with-keda-using-metrics-ingested-into-amazon-cloudwatch/[this blog post] on how to use KEDA with CloudWatch metrics. If you are unsure, which metrics to monitor and scale based on, check out the https://aws-observability.github.io/observability-best-practices/guides/#monitor-what-matters[best practices on monitoring metrics that matters]. + +Reducing workload consumption creates excess capacity in a cluster and with proper autoscaling configuration allows you to scale down nodes automatically and reduce your total spend. We recommend you do not try to optimize compute capacity manually. The Kubernetes scheduler and node autoscalers were designed to handle this process for you. + +== Reduce unused capacity + +After you have determined the correct size for applications, reducing excess requests, you can begin to reduce the provisioned compute capacity. You should be able to do this dynamically if you have taken the time to correctly size your workloads from the sections above. There are two primary node autoscalers used with Kubernetes in AWS. + +=== Karpenter and Cluster Autoscaler + +Both Karpenter and the Kubernetes Cluster Autoscaler will scale the number of nodes in your cluster as pods are created or removed and compute requirements change. The primary goal of both is the same, but Karpenter takes a different approach for node management provisioning and de-provisioning which can help reduce costs and optimize cluster wide usage. + +As clusters grow in size and the variety of workloads increases it becomes more difficult to pre-configure node groups and instances. Just like with workload requests it's important to set an initial baseline and continually adjust as needed. + +If you are using Cluster Autoscaler, it will respect the "minimum" and "maximum" values of each Auto Scaling group (ASG) and only adjust the "desired" value. It's important to pay attention while setting these values for the underlying ASG since Cluster Autoscaler will not be able to scale down an ASG beyond its "minimum" count. Set the "desired" count as the number of nodes you need during normal business hours and "minimum" as the number of nodes you need during off-business hours. Please refer to https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup[Cluster Autoscaler FAQ] doc. + +=== Cluster Autoscaler Priority Expander + +The Kubernetes Cluster Autoscaler works by scaling groups of nodes -- called a node group -- up and down as applications scale up and down. If you are not dynamically scaling workloads then the Cluster Autoscaler will not help you save money. The Cluster Autoscaler requires a cluster admin to create node groups ahead of time for workloads to consume. The node groups need to configured to use instances that have the same "profile", i.e. roughly the same amount of CPU and memory. + +You can have multiple node groups and the Cluster Autoscaler can be configured to set priority scaling levels and each node group can contain different sized nodes. Node groups can have different capacity types and the priority expander can be used to scale less expensive groups first. + +Below is an example of a snippet of cluster configuration that uses a `ConfigMap`` to prioritize reserved capacity before using on-demand instances. You can use the same technique to prioritize Graviton or Spot Instances over other types. + +[,yaml] +---- +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig +metadata: + name: my-cluster +managedNodeGroups: + - name: managed-ondemand + minSize: 1 + maxSize: 7 + instanceType: m5.xlarge + - name: managed-reserved + minSize: 2 + maxSize: 10 + instanceType: c5.2xlarge +---- + +[,yaml] +---- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cluster-autoscaler-priority-expander + namespace: kube-system +data: + priorities: |- + 10: + - .*ondemand.* + 50: + - .*reserved.* +---- + +Using node groups can help the underlying compute resources do the expected thing by default, e.g. spread nodes across AZs, but not all workloads have the same requirements or expectations and it's better to let applications declare their requirements explicitly. For more information about Cluster Autoscaler, please see the https://aws.github.io/aws-eks-best-practices/cluster-autoscaling/[best practices section]. + +=== Descheduler + +The Cluster Autoscaler can add and remove node capacity from a cluster based on new pods needing to be scheduled or nodes being underutilized. It does not take a wholistic view of pod placement after it has been scheduled to a node. If you are using the Cluster Autoscaler you should also look at the https://github.com/kubernetes-sigs/descheduler[Kubernetes descheduler] to avoid wasting capacity in your cluster. + +If you have 10 nodes in a cluster and each node is 60% utilized you are not using 40% of the provisioned capacity in the cluster. With the Cluster Autoscaler you can set the utilization threashold per node to 60%, but that would only try to scale down a single node after utilization dropped below 60%. + +With the descheduler it can look at cluster capacity and utilization after pods have been scheduled or nodes have been added to the cluster. It attempts to keep the total capacity of the cluster above a specified threshold. It can also remove pods based on node taints or new nodes that join the cluster to make sure pods are running in their optimal compute environment. Note that, descheduler does not schedule replacement of evicted pods but relies on the default scheduler for that. + +=== Karpenter Consolidation + +Karpenter takes a "`groupless`" approach to node management. This approach is more flexible for different workload types and requires less up front configuration for cluster administrators. Instead of pre-defining groups and scaling each group as workloads need, Karpenter uses provisioners and node templates to define broadly what type of EC2 instances can be created and settings about the instances as they are created. + +Bin packing is the practice of utilizing more of the instance's resources by packing more workloads onto fewer, optimally sized, instances. While this helps to reduce your compute costs by only provisioning resources your workloads use, it has a trade-off. It can take longer to start new workloads because capacity has to be added to the cluster, especially during large scaling events. Consider the balance between cost optimization, performance, and availability when setting up bin packing. + +Karpenter can continuously monitor and binpack to improve instance resource utilization and lower your compute costs. Karpenter can also select a more cost efficient worker node for your workload. This can be achieved by turning on "`consolidation`" flag to true in the provisioner (sample code snippet below). The example below shows an example provisioner that enables consolidation. At the time of writing this guide, Karpenter won't replace a running Spot instance with a cheaper Spot instance. For further details on Karpenter consolidation, refer to https://aws.amazon.com/blogs/containers/optimizing-your-kubernetes-compute-costs-with-karpenter-consolidation/[this blog]. + +[,yaml] +---- +apiVersion: karpenter.sh/v1alpha5 +kind: Provisioner +metadata: + name: enable-binpacking +spec: + consolidation: + enabled: true +---- + +For workloads that might not be interruptible e.g. long running batch jobs without checkpointing, consider annotating pods with the `do-not-evict` annotation. By opting pods out of eviction, you are telling Karpenter that it should not voluntarily remove nodes containing this pod. However, if a `do-not-evict` pod is added to a node while the node is draining, the remaining pods will still evict, but that pod will block termination until it is removed. In either case, the node will be cordoned to prevent additional work from being scheduled on the node. Below is an example showing how set the annotation: + +```yaml hl_lines="8" +apiVersion: v1 +kind: Pod +metadata: + name: label-demo + labels: + environment: production + annotations: + + "karpenter.sh/do-not-evict": "true" +spec: + containers: + +* name: nginx +image: nginx +ports: + ** containerPort: 80 +``` + +=== Remove under-utilized nodes by adjusting Cluster Autoscaler parameters + +Node utilization is defined as the sum of requested resources divided by capacity. By default `scale-down-utilization-threshold` is set to 50%. This parameter can be used along with and `scale-down-unneeded-time`, which determines how long a node should be unneeded before it is eligible for scale down -- the default is 10 minutes. Pods still running on a node that was scaled down will get scheduled on other nodes by kube-scheduler. Adjusting these settings can help remove nodes that are underutilized, but it's important you test these values first so you don't force the cluster to scale down prematurely. + +You can prevent scale down from happening by ensuring that pods that are expensive to evict are protected by a label recognized by the Cluster Autoscaler. To do this, ensure that pods that are expensive to evict have the annotation `cluster-autoscaler.kubernetes.io/safe-to-evict=false`. Below is an example yaml to set the annotation: + +```yaml hl_lines="8" +apiVersion: v1 +kind: Pod +metadata: + name: label-demo + labels: + environment: production + annotations: + + "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" +spec: + containers: + +* name: nginx +image: nginx +ports: + ** containerPort: 80 +``` + +=== Tag nodes with Cluster Autoscaler and Karpenter + +AWS resource https://docs.aws.amazon.com/tag-editor/latest/userguide/tagging.html[tags] are used to organize your resources, and to track your AWS costs on a detailed level. They do not directly correlate with Kubernetes labels for cost tracking. It's recommended to start with Kubernetes resource labeling and utilize tools like https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/[Kubecost] to get infrastructure cost reporting based on Kubernetes labels on pods, namespaces etc. + +Worker nodes need to have tags to show billing information in AWS Cost Explorer. With Cluster Autoscaler, tag your worker nodes inside a managed node group using https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html[launch template]. For self managed node groups, tag your instances using https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-tagging.html[EC2 auto scaling group]. For instances provisioned by Karpenter, tag them using https://karpenter.sh/docs/concepts/nodeclasses/#spectags[spec.tags in the node template]. + +=== Multi-tenant clusters + +When working on clusters that are shared by different teams you may not have visibility to other workloads running on the same node. While resource requests can help isolate some "`noisy neighbor`" concerns, such as CPU sharing, they may not isolate all resource boundaries such as disk I/O exhaustion. Not every consumable resource by a workload can be isolated or limited. Workloads that consume shared resources at higher rates than other workloads should be isolated through node https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[taints and tolerations]. Another advanced technique for such workload is https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy[CPU pinning] which ensures exclusive CPU instead of shared CPU for the container. + +Isolating workloads at a node level can be more expensive, but it may be possible to schedule https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#besteffort[BestEffort] jobs or take advantage of additional savings by using https://aws.amazon.com/ec2/pricing/reserved-instances/[Reserved Instances], https://aws.amazon.com/ec2/graviton/[Graviton processors], or https://aws.amazon.com/ec2/spot/[Spot]. + +Shared clusters may also have cluster level resource constraints such as IP exhaustion, Kubernetes service limits, or API scaling requests. You should review the https://aws.github.io/aws-eks-best-practices/scalability/docs/control-plane/[scalability best practices guide] to make sure your clusters avoid these limits. + +You can isolate resources at a namespace or Karpenter provisioner level. https://kubernetes.io/docs/concepts/policy/resource-quotas/[Resource Quotas] provide a way to set limits on how many resources workloads in a namespace can consume. This can be a good initial guard rail but it should be continually evaluated to make sure it doesn't artificially restrict workloads from scaling. + +Karpenter provisioners can https://karpenter.sh/docs/concepts/nodepools/#speclimitsresources[set limits on some of the consumable resources] in a cluster (e.g. CPU, GPU), but you will need to configure tenant applications to use the appropriate provisioner. This can prevent a single provisioner from creating too many nodes in a cluster, but it should be continually evaluated to make sure the limit isn't set too low and in turn, prevent workloads from scaling. + +=== Scheduled Autoscaling + +You may have the need to scale down your clusters on weekends and off hours. This is particularly relevant for test and non-production clusters where you want to scale down to zero when they are not in use. Solutions like https://github.com/kubecost/cluster-turndown[cluster-turndown] and https://codeberg.org/hjacobs/kube-downscaler[kube-downscaler] can scale down the replicas to zero based on a cron schedule. + +== Optimize compute capacity types + +After optimizing the total capacity of compute in your cluster and utilizing bin packing, you should look at what type of compute you have provisioned in your clusters and how you pay for those resources. AWS has https://aws.amazon.com/savingsplans/compute-pricing/[Compute Savings plans] that can reduce the cost for your compute which we will categorize into the following capacity types: + +* Spot +* Savings Plans +* On-Demand +* Fargate + +Each capacity type has different trade-offs for management overhead, availability, and long term commitments and you will need to decide which is right for your environment. No environment should rely on a single capacity type and you can mix multiple run types in a single cluster to optimize specific workload requirements and cost. + +=== Spot + +The https://aws.amazon.com/ec2/spot/[spot] capacity type provisions EC2 instances from spare capacity in an Availability Zone. Spot offers the largest discounts--up to 90% -- but those instances can be interrupted when they are needed elsewhere. Additionally, there may not always be capacity to provision new Spot instances and existing Spot instances can be reclaimed with a https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html[2 minute interruption notice]. If your application has a long startup or shutdown process, Spot instances may not be the best option. + +Spot compute should use a wide variety of instance types to reduce the likelihood of not having spot capacity available. Instance interruptions need to be handled to safely shutdown nodes. Nodes provisioned with Karpenter or part of a Managed Node Group automatically support https://aws.github.io/aws-eks-best-practices/karpenter/#enable-interruption-handling-when-using-spot[instance interruption notifications]. If you are using self-managed nodes you will need to run the https://github.com/aws/aws-node-termination-handler[node termination handler] separately to gracefully shutdown spot instances. + +It is possible to balance spot and on-demand instances in a single cluster. With Karpenter you can create https://karpenter.sh/docs/concepts/scheduling/#on-demandspot-ratio-split[weighted provisioners] to achieve a balance of different capacity types. With Cluster Autoscaler you can create https://aws.amazon.com/blogs/containers/amazon-eks-now-supports-provisioning-and-managing-ec2-spot-instances-in-managed-node-groups/[mixed node groups with spot and on-demand or reserved instances]. + +Here is an example of using Karpenter to prioritize Spot instances ahead of On-Demand instances. When creating a provisioner, you can specify either Spot, On-Demand, or both (as shown below). When you specify both, and if the pod does not explicitly specify whether it needs to use Spot or On-Demand, then Karpenter prioritizes Spot when provisioning a node with https://aws.amazon.com/blogs/compute/introducing-price-capacity-optimized-allocation-strategy-for-ec2-spot-instances/[price-capacity-optimization allocation strategy] . + +---- +apiVersion: karpenter.sh/v1alpha5 +kind: Provisioner +metadata: + name: spot-prioritized +spec: + requirements: + - key: "karpenter.sh/capacity-type" + operator: In + values: ["spot", "on-demand"] + +---- + +=== Savings Plans, Reserved Instances, and AWS EDP + +You can reduce your compute spend by using a [compute savings plan](https://aws.amazon.com/savingsplans/compute-pricing/). Savings plans offer reduced prices for a 1 or 3 year commitment of compute usage. The usage can apply to EC2 instances in an EKS cluster but also applies to any compute usage such as Lambda and Fargate. With savings plans you can reduce costs and still pick any EC2 instance type during your commitment period. + +Compute savings plan can reduce your EC2 cost by up to 66% without requiring commitments on what instance types, families, or regions you want to use. Savings are automatically applied to instances as you use them. + +EC2 Instance Savings Plans provides up to 72% savings on compute with a commitment of usage in a specific region and EC2 family, e.g. instances from the C family. You can shift usage to any AZ within the region, use any generation of the instance family, e.g. c5 or c6, and use any size of instance within the family. The discount will automatically be applied for any instance in your account that matches the savings plan criteria. + +[Reserved Instances](https://aws.amazon.com/ec2/pricing/reserved-instances/) are similar to EC2 Instance Savings Plan but they also guarantee capacity in an Availability Zone or Region and reduce cost—up to 72% — over on-demand instances. Once you calculate how much reserved capacity you will need you can select how long you would like to reserve them for (1 year or 3 years). The discounts will automatically be applied as you run those EC2 instances in your account. + +Customers also have the option to enroll in an Enterprise Agreement with AWS. Enterprise Agreements give customers the option to tailor agreements that best suit their needs. Customers can enjoy discounts on the pricing based on AWS EDP (Enterprise Discount Program). For additional information on Enterprise Agreements please contact your AWS sales representative. + +=== On-Demand + +On-Demand EC2 instances have the benefit of availability without interruptions — compared to spot — and no long term commitments — compared to savings plans. If you are looking to reduce costs in a cluster you should reduce your usage of on-demand EC2 instances. + +After optimizing your workload requirements you should be able to calculate a minimum and maximum capacity for your clusters. This number may change over time but rarely goes down. Consider using a Savings Plan for everything under the minimum, and spot for capacity that will not affect your application’s availability. Anything else that may not be continuously used or is required for availability can use on-demand. + +As mentioned in this section, the best way to reduce your usage is to consume fewer resources and utilize the resources you provision to the fullest extent possible. With the Cluster Autoscaler you can remove underutilized nodes with the `scale-down-utilization-threshold` setting. With Karpenter it is recommended to enable consolidation. + +To manually identify EC2 instance types that can be used with your workloads you should use [ec2-instance-selector](https://github.com/aws/amazon-ec2-instance-selector) which can show instances that are available in each region as well as instances compatible with EKS. Example usage for instances with x86 process architecture, 4 Gb of memory, 2 vCPUs and available in the us-east-1 region. + +---- +ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 \ + -r us-east-1 --service eks +c5.large +c5a.large +c5ad.large +c5d.large +c6a.large +c6i.large +t2.medium +t3.medium +t3a.medium +---- + +For non-production environments you can automatically have clusters scaled down during unused hours such as night and weekends. The kubecost project https://github.com/kubecost/cluster-turndown[cluster-turndown] is an example of a controller that can automatically scale your cluster down based on a set schedule. + +=== Fargate compute + +Fargate compute is a fully managed compute option for EKS clusters. It provides pod isolation by scheduling one pod per node in a Kubernetes cluster. It allows you to size your compute nodes to the CPU and RAM requirements of your workload to tightly control workload usage in a cluster. + +Fargate can scale workloads as small as .25 vCPU with 0.5 GB memory and as large as 16 vCPU with 120 GB memory. There are limits on how many https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html[pod size variations] are available and you will need to understand how your workload best fits into a Fargate configuration. For example, if your workload requires 1 vCPU with 0.5 GB of memory the smallest Fargate pod will be 1 vCPU with 2 GB of memory. + +While Fargate has many benefits such as no EC2 instance or operating system management, it may require more compute capacity than traditional EC2 instances due to the fact that every deployed pod is isolated as a separate node in the cluster. This requires more duplication for things like the Kubelet, logging agents, and any DaemonSets you would typically deploy to a node. DaemonSets are not supported in Fargate and they will need to be converted into pod "`sidecars"` and run alongside the application. + +Fargate cannot benefit from bin packing or CPU over provisioning because the boundary for the workload is a node which is not burstable or shareable between workloads. Fargate will save you EC2 instance management time which itself has a cost, but CPU and memory costs may be more expensive than other EC2 capacity types. Fargate pods can take advantage of compute savings plan to reduce the on-demand cost. + +== Optimize Compute Usage + +Another way to save money on your compute infrastructure is to use more efficient compute for the workload. This can come from more performant general purpose compute like https://aws.amazon.com/ec2/graviton/[Graviton processors] which are up to 20% cheaper and 60% more energy efficient than x86--or workload specific accelerators such as GPUs and https://aws.amazon.com/ec2/instance-types/f1/[FPGAs]. You will need to build containers that can https://aws.amazon.com/blogs/containers/how-to-build-your-containers-for-arm-and-save-with-graviton-and-spot-instances-on-amazon-ecs/[run on arm architecture] and https://aws.amazon.com/blogs/compute/running-gpu-accelerated-kubernetes-workloads-on-p3-and-p2-ec2-instances-with-amazon-eks/[set up nodes with the right accelerators] for your workloads. + +EKS has the ability to run clusters with mixed architecture (e.g. amd64 and arm64) and if your containers are compiled for multiple architectures you can take advantage of Graviton processors with Karpenter by allowing both architectures in your provisioner. To keep consistent performance, however, it is recommended you keep each workload on a single compute architecture and only use different architecture if there is no additional capacity available. + +Provisioners can be configured with multiple architectures and workloads can also request specific architectures in their workload specification. + +[,yaml] +---- +apiVersion: karpenter.sh/v1alpha5 +kind: Provisioner +metadata: + name: default +spec: + requirements: + - key: "kubernetes.io/arch" + operator: In + values: ["arm64", "amd64"] +---- + +With Cluster Autoscaler you will need to create a node group for Graviton instances and set https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[node tolerations on your workload] to utilize the new capacity. + +GPUs and FPGAs can greatly increase the performance for your workload, but the workload will need to be optimized to use the accelerator. Many workload types for machine learning and artificial intelligence can use GPUs for compute and instances can be added to a cluster and mounted into a workload using resource requests. + +[,yaml] +---- +spec: + template: + spec: + - containers: + ... + resources: + limits: + nvidia.com/gpu: "1" +---- + +Some GPU hardware can be shared across multiple workloads so a single GPU can be provisioned and used. To see how to configure workload GPU sharing see the https://aws.amazon.com/blogs/opensource/virtual-gpu-device-plugin-for-inference-workload-in-kubernetes/[virtual GPU device plugin] for more information. You can also refer to the following blogs: + +* https://aws.amazon.com/blogs/containers/gpu-sharing-on-amazon-eks-with-nvidia-time-slicing-and-accelerated-ec2-instances/[GPU sharing on Amazon EKS with NVIDIA time-slicing and accelerated EC2 instances] +* https://aws.amazon.com/blogs/containers/maximizing-gpu-utilization-with-nvidias-multi-instance-gpu-mig-on-amazon-eks-running-more-pods-per-gpu-for-enhanced-performance/[Maximizing GPU utilization with NVIDIA's Multi-Instance GPU (MIG) on Amazon EKS: Running more pods per GPU for enhanced performance] diff --git a/latest/bpg/cost/cost_opt_networking.adoc b/latest/bpg/cost/cost_opt_networking.adoc new file mode 100644 index 000000000..e773c177c --- /dev/null +++ b/latest/bpg/cost/cost_opt_networking.adoc @@ -0,0 +1,484 @@ +//!!NODE_ROOT
+[."topic"] +[[cost-opt-networking,cost-opt-networking.title]] += Cost Optimization - Networking +:info_doctype: section +:imagesdir: images/ +:info_title: Networking +:info_abstract: Networking +:info_titleabbrev: Networking +:authors: ["Lukonde Mwila"] +:date: 2023-09-22 + +Architecting systems for high availability (HA) is a best practice in order to accomplish resilience and fault-tolerance. In practice, this means spreading your workloads and the underlying infrastructure across multiple Availability Zones (AZs) in a given AWS Region. Ensuring these characteristics are in place for your Amazon EKS environment will enhance the overall reliability of your system. In conjunction with this, your EKS environments will likely also be composed of a variety of constructs (i.e. VPCs), components (i.e. ELBs), and integrations (i.e. ECR and other container registries). + +The combination of highly available systems and other use-case specific components can play a significant role in how data is transferred and processed. This will in turn have an impact on the costs incurred due to data transfer and processing. + +The practices detailed below will help you design and optimize your EKS environments in order to achieve cost-effectiveness for different domains and use cases. + +== Pod to Pod Communication + +Depending on your setup, network communication and data transfer between Pods can have a significant impact on the overall cost of running Amazon EKS workloads. This section will cover different concepts and approaches to mitigating the costs tied to inter-pod communication, while considering highly available (HA) architectures, application performance and resilience. + +=== Restricting Traffic to an Availability Zone + +Frequent egress cross-zone traffic (traffic distributed between AZs) can have a major impact on your network-related costs. Below are some strategies on how to control the amount of cross-zone traffic between Pods in your EKS cluster. + +_If you want granular visibility into the amount of cross-zone traffic between Pods in your cluster (such as the amount of data transferred in bytes), https://aws.amazon.com/blogs/containers/getting-visibility-into-your-amazon-eks-cross-az-pod-to-pod-network-bytes/[refer to this post]._ + +*Using Topology Aware Routing (formerly known as Topology Aware Hints)* + +image::../images/topo_aware_routing.png[Topology aware routing] + +When using topology aware routing, it's important to understand how Services, EndpointSlices and the `kube-proxy` work together when routing traffic. As the diagram above depicts, Services are the stable network abstraction layer that receive traffic destined for your Pods. When a Service is created, multiple EndpointSlices are created. Each EndpointSlice has a list of endpoints containing a subset of Pod addresses along with the nodes they're running on and any additional topology information. `kube-proxy` is a daemonset that runs on every node in your cluster and also fulfills a role of internal routing, but it does so based on what it consumes from the created EndpointSlices. + +When https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/[_topology aware routing_] is enabled and implemented on a Kubernetes Service, the EndpointSlice controller will proportionally allocate endpoints to the different zones that your cluster is spread across. For each of those endpoints, the EndpointSlice controller will also set a _hint_ for the zone. _Hints_ describe which zone an endpoint should serve traffic for. `kube-proxy` will then route traffic from a zone to an endpoint based on the _hints_ that get applied. + +The diagram below shows how EndpointSlices with hints are organized in such a way that `kube-proxy` can know what destination they should go to based on their zonal point of origin. Without hints, there is no such allocation or organization and traffic will be proxied to different zonal destinations regardless of where it's coming from. + +image::../images/endpoint_slice.png[Endpoint Slice] + +In some cases, the EndpointSlice controller may apply a _hint_ for a different zone, meaning the endpoint could end up serving traffic originating from a different zone. The reason for this is to try and maintain an even distribution of traffic between endpoints in different zones. + +Below is a code snippet on how to enable _topology aware routing_ for a Service. + +```yaml hl_lines="6-7" +apiVersion: v1 +kind: Service +metadata: + name: orders-service + namespace: ecommerce + annotations: + service.kubernetes.io/topology-mode: Auto +spec: + selector: + app: orders + type: ClusterIP + ports: + +* protocol: TCP +port: 3003 +targetPort: 3003 +``` + +The screenshot below shows the result of the EndpointSlice controller having successfully applied a hint to an endpoint for a Pod replica running in the AZ `eu-west-1a`. + +image::../images/slice_shell.png[Slice shell] + +!!! note + It's important to note that topology aware routing is still in *beta*. Also, this feature is more predictable when workloads are widely and evenly distributed across the cluster topology. Therefore, it is highly recommended to use it in conjunction with scheduling constraints that increase the availability of an application such as https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/[pod topology spread constraints]. + +*Using Autoscalers: Provision Nodes to a Specific AZ* + +_We strongly recommend_ running your workloads in highly available environments across multiple AZs. This improves the reliability of your applications, especially when there is an incident of an issue with an AZ. In the case you're willing to sacrifice reliability for the sake of reducing their network-related costs, you can restrict your nodes to a single AZ. + +To run all your Pods in the same AZ, either provision the worker nodes in the same AZ or schedule the Pods on the worker nodes running on the same AZ. To provision nodes within a single AZ, define a node group with subnets belonging to the same AZ with https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler[Cluster Autoscaler (CA)]. For https://karpenter.sh/[Karpenter,] use "`http://topology.kubernetes.io/zone%E2%80%9D[_topology.kubernetes.io/zone`"_] and specify the AZ where you'd like to create the worker nodes. For example, the below Karpenter provisioner snippet provisions the nodes in the us-west-2a AZ. + +*Karpenter* + +```yaml hl_lines="5-9" +apiVersion: karpenter.sh/v1alpha5 +kind: Provisioner +metadata: +name: single-az +spec: + requirements: + +* key: "topology.kubernetes.io/zone"` +operator: In +values: ["us-west-2a"] +``` + +*Cluster Autoscaler (CA)* + +```yaml hl_lines="7-8" +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig +metadata: + name: my-ca-cluster + region: us-east-1 + version: "1.21" +availabilityZones: + +* us-east-1a +managedNodeGroups: +* name: managed-nodes +labels: + role: managed-nodes +instanceType: t3.medium +minSize: 1 +maxSize: 10 +desiredCapacity: 1 +... +``` + +*Using Pod Assignment and Node Affinity* + +Alternatively, if you have worker nodes running in multiple AZs, each node would have the label _http://topology.kubernetes.io/zone%E2%80%9D[topology.kubernetes.io/zone]_ with the value of its AZ (such as us-west-2a or us-west-2b). You can utilize `nodeSelector` or `nodeAffinity` to schedule Pods to the nodes in a single AZ. For example, the following manifest file will schedule the Pod inside a node running in AZ us-west-2a. + +```yaml hl_lines="7-9" +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + nodeSelector: + topology.kubernetes.io/zone: us-west-2a + containers: + +* name: nginx +image: nginx +imagePullPolicy: IfNotPresent +``` + +=== Restricting Traffic to a Node + +There are cases where restricting traffic at a zonal level isn't sufficient. Apart from reducing costs, you may have the added requirement of reducing network latency between certain applications that have frequent inter-communication. In order to achieve optimal network performance and reduce costs, you need a way to restrict traffic to a specific node. For example, Microservice A should always talk to Microservice B on Node 1, even in highly available (HA) setups. Having Microservice A on Node 1 talk to Microservice B on Node 2 may have a negative impact on the desired performance for applications of this nature, especially if Node 2 is in a separate AZ altogether. + +*Using the Service Internal Traffic Policy* + +In order to restrict Pod network traffic to a node, you can make use of the _https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/[Service internal traffic policy]_. By default, traffic sent to a workload's Service will be randomly distributed across the different generated endpoints. So in a HA architecture, that means traffic from Microservice A could go to any replica of Microservice B on any given node across the different AZs. However, with the Service's internal traffic policy set to `Local`, traffic will be restricted to endpoints on the node that the traffic originated from. This policy dictates the exclusive use of node-local endpoints. By implication, your network traffic-related costs for that workload will be lower than if the distribution was cluster wide. Also, the latency will be lower, making your application more performant. + +!!! note + It's important to note that this feature cannot be combined with topology aware routing in Kubernetes. + +image::../images/local_traffic.png[Local internal traffic] + +Below is a code snippet on how to set the _internal traffic policy_ for a Service. + +```yaml hl_lines="14" +apiVersion: v1 +kind: Service +metadata: + name: orders-service + namespace: ecommerce +spec: + selector: + app: orders + type: ClusterIP + ports: + +* protocol: TCP +port: 3003 +targetPort: 3003 + internalTrafficPolicy: Local +``` + +To avoid unexpected behaviour from your application due to traffic drops, you should consider the following approaches: + +* Run enough replicas for each of the communicating Pods +* Have a relatively even spread of Pods using https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/[topology spread constraints] +* Make use of https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity[pod-affinity rules] for co-location of communicating Pods + +In this example, you have 2 replicas of Microservice A and 3 replicas of Microservice B. If Microservice A has its replicas spread between Nodes 1 and 2, and Microservice B has all 3 of its replicas on Node 3, then they won't be able to communicate because of the `Local` internal traffic policy. When there are no available node-local endpoints the traffic is dropped. + +image::../images/no_node_local_1.png[node-local_no_peer] + +If Microservice B does have 2 of its 3 replicas on Nodes 1 and 2, then there will be communication between the peer applications. But you would still have an isolated replica of Microservice B without any peer replica to communicate with. + +image::../images/no_node_local_2.png[node-local_with_peer] + +!!! note + In some scenarios, an isolated replica like the one depicted in the above diagram may not be a cause for concern if it still serves a purpose (such as serving requests from external incoming traffic). + +*Using the Service Internal Traffic Policy with Topology Spread Constraints* + +Using the _internal traffic policy_ in conjunction with _topology spread constraints_ can be useful to ensure that you have the right number of replicas for communicating microservices on different nodes. + +---- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: express-test +spec: + replicas: 6 + selector: + matchLabels: + app: express-test + template: + metadata: + labels: + app: express-test + tier: backend + spec: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: "topology.kubernetes.io/zone" + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + app: express-test + +---- + +**Using the Service Internal Traffic Policy with Pod Affinity Rules** + +Another approach is to make use of Pod affinity rules when using the Service internal traffic policy. With Pod affinity, you can influence the scheduler to co-locate certain Pods because of their frequent communication. By applying strict scheduling constraints (`requiredDuringSchedulingIgnoredDuringExecution`) on certain Pods, this will give you better results for Pod co-location when the Scheduler is placing Pods on nodes. + +---- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: graphql + namespace: ecommerce + labels: + app.kubernetes.io/version: "0.1.6" + ... + spec: + serviceAccountName: graphql-service-account + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - orders + topologyKey: "kubernetes.io/hostname" +---- + +== Load Balancer to Pod Communication + +EKS workloads are typically fronted by a load balancer that distributes traffic to the relevant Pods in your EKS cluster. Your architecture may comprise internal and/or external facing load balancers. Depending on your architecture and network traffic configurations, the communication between load balancers and Pods can contribute a significant amount to data transfer charges. + +You can use the https://kubernetes-sigs.github.io/aws-load-balancer-controller[AWS Load Balancer Controller] to automatically manage the creation of ELB resources (ALB and NLB). The data transfer charges you incur in such setups will depend on the path taken by the network traffic. The AWS Load Balancer Controller supports two network traffic modes, _instance mode_, and _ip mode_. + +When using _instance mode_, a NodePort will be opened on each node in your EKS cluster. The load balancer will then proxy traffic evenly across the nodes. If a node has the destination Pod running on it, then there will be no data transfer costs incurred. However, if the destination Pod is on a separate node and in a different AZ than the NodePort receiving the traffic, then there will be an extra network hop from the kube-proxy to the destination Pod. In such a scenario, there will be cross-AZ data transfer charges. Because of the even distribution of traffic across the nodes, it is highly likely that there will be additional data transfer charges associated with cross-zone network traffic hops from kube-proxies to the relevant destination Pods. + +The diagram below depicts a network path for traffic flowing from the load balancer to the NodePort, and subsequently from the `kube-proxy` to the destination Pod on a separate node in a different AZ. This is an example of the _instance mode_ setting. + +image::../images/lb_2_pod.png[LB to Pod] + +When using _ip mode_, network traffic is proxied from the load balancer directly to the destination Pod. As a result, there are _no data transfer charges_ involved in this approach. + +!!! tip + It is recommended that you set your load balancer to _ip traffic mode_ to reduce data transfer charges. For this setup, it's also important to make sure that your load balancer is deployed across all the subnets in your VPC. + +The diagram below depicts network paths for traffic flowing from the load balancer to Pods in the network _ip mode_. + +image::../images/ip_mode.png[IP mode] + +== Data Transfer from Container Registry + +=== Amazon ECR + +Data transfer into the Amazon ECR private registry is free. _In-region data transfer incurs no cost_, but data transfer out to the internet and across regions will be charged at Internet Data Transfer rates on both sides of the transfer. + +You should utilize ECRs built-in https://docs.aws.amazon.com/AmazonECR/latest/userguide/replication.html[image replication feature] to replicate the relevant container images into the same region as your workloads. This way the replication would be charged once, and all the same region (intra-region) image pulls would be free. + +You can further reduce data transfer costs associated with pulling images from ECR (data transfer out) by _using https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html[Interface VPC Endpoints] to connect to the in-region ECR repositories_. The alternative approach of connecting to ECR's public AWS endpoint (via a NAT Gateway and an Internet Gateway) will incur higher data processing and transfer costs. The next section will cover reducing data transfer costs between your workloads and AWS Services in greater detail. + +If you're running workloads with especially large images, you can build your own custom Amazon Machine Images (AMIs) with pre-cached container images. This can reduce the initial image pull time and potential data transfer costs from a container registry to the EKS worker nodes. + +== Data Transfer to Internet & AWS Services + +It's a common practice to integrate Kubernetes workloads with other AWS services or third-party tools and platforms via the Internet. The underlying network infrastructure used to route traffic to and from the relevant destination can impact the costs incurred in the data transfer process. + +=== Using NAT Gateways + +NAT Gateways are network components that perform network address translation (NAT). The diagram below depicts Pods in an EKS cluster communicating with other AWS services (Amazon ECR, DynamoDB, and S3), and third-party platforms. In this example, the Pods are running in private subnets in separate AZs. To send and receive traffic from the Internet, a NAT Gateway is deployed to the public subnet of one AZ, allowing any resources with private IP addresses to share a single public IP address to access the Internet. This NAT Gateway in turn communicates with the Internet Gateway component, allowing for packets to be sent to their final destination. + +image::../images/nat_gw.png[NAT Gateway] + +When using NAT Gateways for such use cases, _you can minimize the data transfer costs by deploying a NAT Gateway in each AZ_. This way, traffic routed to the Internet will go through the NAT Gateway in the same AZ, avoiding inter-AZ data transfer. However, even though you'll save on the cost of inter-AZ data transfer, the implication of this setup is that you'll incur the cost of an additional NAT Gateway in your architecture. + +This recommended approach is depicted in the diagram below. + +image::../images/recommended_approach.png[Recommended approach] + +=== Using VPC Endpoints + +To further reduce costs in such architectures, _you should use https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html[VPC Endpoints] to establish connectivity between your workloads and AWS services_. VPC Endpoints allow you to access AWS services from within a VPC without data/network packets traversing the Internet. All traffic is internal and stays within the AWS network. There are two types of VPC Endpoints: Interface VPC Endpoints (https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-privatelink-support.html[supported by many AWS services]) and Gateway VPC Endpoints (only supported by S3 and DynamoDB). + +*Gateway VPC Endpoints* + +_There are no hourly or data transfer costs associated with Gateway VPC Endpoints_. When using Gateway VPC Endpoints, it's important to note that they are not extendable across VPC boundaries. They can't be used in VPC peering, VPN networking, or via Direct Connect. + +*Interface VPC Endpoint* + +VPC Endpoints have an https://aws.amazon.com/privatelink/pricing/[hourly charge] and, depending on the AWS service, may or may not have an additional charge associated with data processing via the underlying ENI. To reduce inter-AZ data transfer costs related to Interface VPC Endpoints, you can create a VPC Endpoint in each AZ. You can create multiple VPC Endpoints in the same VPC even if they're pointing to the same AWS service. + +The diagram below shows Pods communicating with AWS services via VPC Endpoints. + +image::../images/vpc_endpoints.png[VPC Endpoints] + +== Data Transfer between VPCs + +In some cases, you may have workloads in distinct VPCs (within the same AWS region) that need to communicate with each other. This can be accomplished by allowing traffic to traverse the public internet through Internet Gateways attached to the respective VPCs. Such communication can be enabled by deploying infrastructure components like EC2 instances, NAT Gateways or NAT instances in public subnets. However, a setup including these components will incur charges for processing/transferring data in and out of the VPCs. If the traffic to and from the separate VPCs is moving across AZs, then there will be an additional charge in the transfer of data. The diagram below depicts a setup that uses NAT Gateways and Internet Gateways to establish communication between workloads in different VPCs. + +image::../images/between_vpcs.png[Between VPCs] + +=== VPC Peering Connections + +To reduce costs for such use cases, you can make use of https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html[VPC Peering]. With a VPC Peering connection, there are no data transfer charges for network traffic that stays within the same AZ. If traffic crosses AZs, there will be a cost incurred. Nonetheless, the VPC Peering approach is recommended for cost-effective communication between workloads in separate VPCs within the same AWS region. However, it's important to note that VPC peering is primarily effective for 1:1 VPC connectivity because it doesn't allow for transitive networking. + +The diagram below is a high-level representation of workloads communication via a VPC peering connection. + +image::../images/peering.png[Peering] + +=== Transitive Networking Connections + +As pointed out in the previous section, VPC Peering connections do not allow for transitive networking connectivity. If you want to connect 3 or more VPCs with transitive networking requirements, then you should use a https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html[Transit Gateway] (TGW). This will enable you to overcome the limits of VPC Peering or any operational overhead associated with having multiple VPC Peering connections between multiple VPCs. You are https://aws.amazon.com/transit-gateway/pricing/[billed on an hourly basis] and for data sent to the TGW. _There is no destination cost associated with inter-AZ traffic that flows through the TGW._ + +The diagram below shows inter-AZ traffic flowing through a TGW between workloads in different VPCs but within the same AWS region. + +image::../images/transititive.png[Transitive] + +== Using a Service Mesh + +Service meshes offer powerful networking capabilities that can be used to reduce network related costs in your EKS cluster environments. However, you should carefully consider the operational tasks and complexity that a service mesh will introduce to your environment if you adopt one. + +=== Restricting Traffic to Availability Zones + +*Using Istio's Locality Weighted Distribution* + +Istio enables you to apply network policies to traffic _after_ routing occurs. This is done using https://istio.io/latest/docs/reference/config/networking/destination-rule/[Destination Rules] such as https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/distribute/[locality weighted distribution]. Using this feature, you can control the weight (expressed as a percentage) of traffic that can go to a certain destination based on its origin. The source of this traffic can either be from an external (or public facing) load balancer or a Pod within the cluster itself. When all the Pod endpoints are available, the locality will be selected based on a weighted round-robin load balancing algorithm. In the case that certain endpoints are unhealthy or unavailable, https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight.html[the locality weight will be automatically adjusted] to reflect this change in the available endpoints. + +!!! note + Before implementing locality weighted distribution, you should start by understanding your network traffic patterns and the implications that the Destination Rule policy may have on your application's behaviour. As such, it's important to have distributed tracing mechanisms in place with tools such as https://aws.amazon.com/xray/[AWS X-Ray] or https://www.jaegertracing.io/[Jaeger]. + +The Istio Destination Rules detailed above can also be applied to manage traffic from a load balancer to Pods in your EKS cluster. Locality weighted distribution rules can be applied to a Service that receives traffic from a highly available load balancer (specifically the Ingress Gateway). These rules allow you to control how much traffic goes where based on its zonal origin - the load balancer in this case. If configured correctly, less egress cross-zone traffic will be incurred compared to a load balancer that distributes traffic evenly or randomly to Pod replicas in different AZs. + +Below is a code block example of a Destination Rule resource in Istio. As can be seen below, this resource specifies weighted configurations for incoming traffic from 3 different AZs in the `eu-west-1` region. These configurations declare that a majority of the incoming traffic (70% in this case) from a given AZ should be proxied to a destination in the same AZ from which it originates. + +---- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: express-test-dr +spec: + host: express-test.default.svc.cluster.local + trafficPolicy: + loadBalancer: + + localityLbSetting: + distribute: + - from: eu-west-1/eu-west-1a/ + + to: + "eu-west-1/eu-west-1a/_": 70 + "eu-west-1/eu-west-1b/_": 20 + "eu-west-1/eu-west-1c/_": 10 + - from: eu-west-1/eu-west-1b/_ + + to: + "eu-west-1/eu-west-1a/_": 20 + "eu-west-1/eu-west-1b/_": 70 + "eu-west-1/eu-west-1c/_": 10 + - from: eu-west-1/eu-west-1c/_ + + to: + "eu-west-1/eu-west-1a/_": 20 + "eu-west-1/eu-west-1b/_": 10 + "eu-west-1/eu-west-1c/*": 70** + connectionPool: + http: + http2MaxRequests: 10 + maxRequestsPerConnection: 10 + outlierDetection: + consecutiveGatewayErrors: 1 + interval: 1m + baseEjectionTime: 30s + +---- + +!!! note + The minimum weight that can be distributed destination is 1%. The reason for this is to maintain failover regions and zones in the case that the endpoints in the main destination become unhealthy or unavailable. + +The diagram below depicts a scenario in which there is a highly available load balancer in the _eu-west-1_ region and locality weighted distribution is applied. The Destination Rule policy for this diagram is configured to send 60% of traffic coming from _eu-west-1a_ to Pods in the same AZ, whereas 40% of the traffic from _eu-west-1a_ should go to Pods in eu-west-1b. + +![Istio Traffic Control](../images/istio-traffic-control.png) + +### Restricting Traffic to Availability Zones and Nodes + +**Using the Service Internal Traffic Policy with Istio** + +To mitigate network costs associated with _external_ incoming traffic and _internal_ traffic between Pods, you can combine Istio’s Destination Rules and the Kubernetes Service _internal traffic policy_. The way to combine Istio destination rules with the service internal traffic policy will largely depend on 3 things: + +* The role of the microservices +* Network traffic patterns across the microservices +* How the microservices should be deployed across the Kubernetes cluster topology + +The diagram below shows what the network flow would look like in the case of a nested request and how the aforementioned policies would control the traffic. + +![External and Internal traffic policy](../images/external-and-internal-traffic-policy.png) + +1. The end user makes a request to **APP A,** which in turn makes a nested request to **APP C**. This request is first sent to a highly available load balancer, which has instances in AZ 1 and AZ 2 as the above diagram shows. +2. The external incoming request is then routed to the correct destination by the Istio Virtual Service. +3. After the request is routed, the Istio Destination Rule controls how much traffic goes to the respective AZs based on where it originated from (AZ 1 or AZ 2). +4. The traffic then goes to the Service for **APP A**, and is then proxied to the respective Pod endpoints. As shown in the diagram, 80% of the incoming traffic is sent to Pod endpoints in AZ 1, and 20% of the incoming traffic is sent to AZ 2. +5. **APP A** then makes an internal request to **APP C**. **APP C**'s Service has an internal traffic policy enabled (`internalTrafficPolicy``: Local`). +6. The internal request from **APP A** (on *NODE 1*) to **APP C** is successful because of the available node-local endpoint for **APP C**. +7. The internal request from **APP A** (on *NODE 3) to* **APP C** fails because there are no available _node-local endpoints_ for **APP C**. As the diagram shows, APP C has no replicas on NODE 3. **** + +The screenshots below are captured from a live example of this approach. The first set of screenshots demonstrate a successful external request to a `graphql` and a successful nested request from the `graphql` to a co-located `orders` replica on the node `ip-10-0-0-151.af-south-1.compute.internal`. + +![Before](../images/before.png) +![Before results](../images/before-results.png) + +With Istio, you can verify and export the statistics of any [upstream clusters](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/intro/terminology) and endpoints that your proxies are aware of. This can help provide a picture of the network flow as well as the share of distribution among the services of a workload. Continuing with the same example, the `orders` endpoints that the `graphql` proxy is aware of can be obtained using the following command: + + +---- +kubectl exec -it deploy/graphql -n ecommerce -c istio-proxy -- curl localhost:15000/clusters | grep orders +---- + +[,bash] +---- +... +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_error::0** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_success::119** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_timeout::0** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_total::119** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**health_flags::healthy** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**region::af-south-1** +orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**zone::af-south-1b** +... +---- + +In this case, the `graphql` proxy is only aware of the `orders` endpoint for the replica that it shares a node with. If you remove the `internalTrafficPolicy: Local` setting from the orders Service, and re-run a command like the one above, then the results will return all the endpoints of the replicas spread across the different nodes. Furthermore, by examining the `rq_total` for the respective endpoints, you'll notice a relatively even share in network distribution. Consequently, if the endpoints are associated with upstream services running in different AZs, then this network distribution across zones will result in higher costs. + +As mentioned in a previous section above, you can co-locate frequently communicating Pods by making use of pod-affinity. + +`+yaml hl_lines="11-20" +... +spec: +... + template: + metadata: + labels: + app: graphql + role: api + workload: ecommerce + spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - orders + topologyKey: "kubernetes.io/hostname" + nodeSelector: + managedBy: karpenter + billing-team: ecommerce +... ++` + +When the `graphql` and `orders` replicas don't co-exist on the same node (`ip-10-0-0-151.af-south-1.compute.internal`), the first request to `graphql` is successful as noted by the `200 response code` in the Postman screenshot below, whereas the second nested request from `graphql` to `orders` fails with a `503 response code`. + +image:../images/after.png[After] +image:../images/after-results.png[After results] + +== Additional Resources + +* https://aws.amazon.com/blogs/containers/addressing-latency-and-data-transfer-costs-on-eks-using-istio/[Addressing latency and data transfer costs on EKS using Istio] +* https://aws.amazon.com/blogs/containers/exploring-the-effect-of-topology-aware-hints-on-network-traffic-in-amazon-elastic-kubernetes-service/[Exploring the effect of Topology Aware Hints on network traffic in Amazon Elastic Kubernetes Service] +* https://aws.amazon.com/blogs/containers/getting-visibility-into-your-amazon-eks-cross-az-pod-to-pod-network-bytes/[Getting visibility into your Amazon EKS Cross-AZ pod to pod network bytes] +* https://youtu.be/EkpdKVm9kQY[Optimize AZ Traffic with Istio] +* https://youtu.be/KFgE_lNVfz4[Optimize AZ Traffic with Topology Aware Routing] +* https://youtu.be/-uiF_zixEro[Optimize Kubernetes Cost & Performance with Service Internal Traffic Policy] +* https://youtu.be/edSgEe7Rihc[Optimize Kubernetes Cost & Performance with Istio and Service Internal Traffic Policy] +* https://aws.amazon.com/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures/[Overview of Data Transfer Costs for Common Architectures] +* https://aws.amazon.com/blogs/containers/understanding-data-transfer-costs-for-aws-container-services/[Understanding data transfer costs for AWS container services] diff --git a/latest/bpg/cost/cost_opt_observability.adoc b/latest/bpg/cost/cost_opt_observability.adoc new file mode 100644 index 000000000..5f4e10ee3 --- /dev/null +++ b/latest/bpg/cost/cost_opt_observability.adoc @@ -0,0 +1,350 @@ +//!!NODE_ROOT
+[."topic"] +[[cost-opt-observability,cost-opt-observability.title]] += Cost Optimization - Observability +:info_doctype: section +:imagesdir: images/ +:info_title: Observability +:info_abstract: Observability +:info_titleabbrev: Observability +:authors: ["Rachel Leekin", "Nirmal Mehta"] +:date: 2023-09-29 + +== Introduction + +Observability tools help you efficiently detect, remediate and investigate your workloads. The cost of telemetry data naturally increases as your use of EKS increases. At times, it can be challenging to balance your operational needs and measuring what matters to your business and keeping observability costs in check. This guide focuses on cost optimization strategies for the three pillars of observability: logs, metrics and traces. Each of these best practices can be applied independently to fit your organization's optimization goals. + +== Logging + +Logging plays a vital role in monitoring and troubleshooting the applications in your cluster. There are several strategies that can be employed to optimize logging costs. The best practice strategies listed below include examining your log retention policies to implement granular controls on how long log data is kept, sending log data to different storage options based on importance, and utilizing log filtering to narrow down the types of logs messages that are stored. Efficiently managing log telemetry can lead to cost savings for your environments. + +== EKS Control Plane + +=== Optimize Your Control Plane Logs + +The Kubernetes control plane is a https://kubernetes.io/docs/concepts/overview/components/#control-plane-components[set of components] that manage the clusters and these components send different types of information as log streams to a log group in https://aws.amazon.com/cloudwatch/[Amazon CloudWatch]. While there are benefits to enabling all control plane log types, you should be aware of the information in each log and the associated costs to storing all the log telemetry. You are charged for the standard https://aws.amazon.com/cloudwatch/pricing/[CloudWatch Logs data ingestion and storage costs for logs] sent to Amazon CloudWatch Logs from your clusters. Before enabling them, evaluate whether each log stream is necessary. + +For example, in non-production clusters, selectively enable specific log types, such as the api server logs, only for analysis and deactivate afterward. But for production clusters, where you might not be able to reproduce events, and resolving issues requires more log information, then you can enable all log types. Further control plane cost optimization implementation details are in this https://aws.amazon.com/blogs/containers/understanding-and-cost-optimizing-amazon-eks-control-plane-logs/[blog] post. + +==== Stream Logs to S3 + +Another cost optimization best practice is streaming control plane logs to S3 via CloudWatch Logs subscriptions. Leveraging CloudWatch Logs https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Subscriptions.html[subscriptions] allows you to selectively forward logs to S3 which provides more cost efficient long term storage compared to retaining logs indefinitely in CloudWatch. For example, for production clusters, you can create a critical log group and leverage subscriptions to stream these logs to S3 after 15 days. This will ensure you have have quick access to the logs for analysis but also save on cost by moving logs to a more cost efficient storage. + +!!! attention + As of 9/5/2023 EKS logs are classified as Vended Logs in Amazon CloudWatch Logs. Vended Logs are specific AWS service logs natively published by AWS services on behalf of the customer and available at volume discount pricing. Please visit the https://aws.amazon.com/cloudwatch/pricing/[Amazon CloudWatch pricing page] to learn more about Vended Logs pricing. + +== EKS Data Plane + +=== Log Retention + +Amazon CloudWatch's default retention policy is to keep logs indefinitely and never expire, incurring storage costs applicable to your AWS region. In order to reduce the storage costs, you can customize the retention policy for each log group based on your workload requirements. + +In a development environment, a lengthy retention period may not be necessary. But in a production environment, you can set a longer retention policy to meet troubleshooting, compliance, and capacity planning requirements. For example, if you are running an e-commerce application during the peak holiday season the system is under heavier load and issues can arise that may not be immediately noticeable, you will want to set a longer log retention for detailed troubleshooting and post event analysis. + +You can https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention[configure your retention periods] in the AWS CloudWatch console or https://docs.aws.amazon.com/cli/latest/reference/logs/put-retention-policy.html[AWS API] with the duration from 1 day to 10 years based on each log group. Having a flexible retention period can save log storage costs, while also maintaining critical logs. + +=== Log Storage Options + +Storage is a large driver of observability costs therefore it is crucial to optimize your log storage strategy. Your strategies should align with your workloads requirements while maintaining performance and scalability. One strategy to reduce the costs of storing logs is to leverage AWS S3 buckets and its different storage tiers. + +==== Forward logs directly to S3 + +Consider forwarding less critical logs, such as development environments, directly to S3 instead of Cloudwatch. This can have an immediate impact on log storage costs. One option is to forward the logs straight to S3 using Fluentbit. You define this in the `[OUTPUT]` section, the destination where FluentBit transmits container logs for retention. Review additional configurations parameter https://docs.fluentbit.io/manual/pipeline/outputs/s3#worker-support[here]. + +---- +[OUTPUT] + Name eks_to_s3 + Match application.* + bucket $S3_BUCKET name + region us-east-2 + store_dir /var/log/fluentbit + total_file_size 30M + upload_timeout 3m +---- + +==== Forward logs to CloudWatch only for short term analysis + +For more critical logs, such as a production environments where you might need to perform immediate analysis on the data, consider forwarding the logs to CloudWatch. You define this in the `[OUTPUT]` section, the destination where FluentBit transmits container logs for retention. Review additional configurations parameter https://docs.fluentbit.io/manual/pipeline/outputs/cloudwatch[here]. + +---- +[OUTPUT] + Name eks_to_cloudwatch_logs + Match application.* + region us-east-2 + log_group_name fluent-bit-cloudwatch + log_stream_prefix from-fluent-bit- + auto_create_group On +---- + +However, this will not have an instant affect on your cost savings. For additional savings, you will have to export these logs to Amazon S3. + +==== Export to Amazon S3 from CloudWatch + +For storing Amazon CloudWatch logs long term, we recommend exporting your Amazon EKS CloudWatch logs to Amazon Simple Storage Service (Amazon S3). You can forward the logs to Amazon S3 bucket by creating an export task via the https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/S3ExportTasksConsole.html[Console] or the API. After you have done so, Amazon S3 presents many options to further reduce cost. You can define your own https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html[Amazon S3 Lifecycle rules] to move your logs to a storage class that a fits your needs, or leverage the https://aws.amazon.com/s3/storage-classes/intelligent-tiering/[Amazon S3 Intelligent-Tiering] storage class to have AWS automatically move data to long-term storage based on your usage pattern. Please refer to this https://aws.amazon.com/blogs/containers/understanding-and-cost-optimizing-amazon-eks-control-plane-logs/[blog] for more details. For example, for your production environment logs reside in CloudWatch for more than 30 days then exported to Amazon S3 bucket. You can then use Amazon Athena to query the data in Amazon S3 bucket if you need to refer back to the logs at a later time. + +=== Reduce Log Levels + +Practice selective logging for your application. Both your applications and nodes output logs by default. For your application logs, adjust the log levels to align with the criticality of the workload and environment. For example, the java application below is outputting `INFO` logs which is the typical default application configuration and depending on the code can result in a high volume of log data. + +---- +import org.apache.log4j.*; + +public class LogClass { + private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class); + +public static void main(String[] args) { + log.setLevel(Level.INFO); + + log.debug("This is a DEBUG message, check this out!"); + log.info("This is an INFO message, nothing to see here!"); + log.warn("This is a WARN message, investigate this!"); + log.error("This is an ERROR message, check this out!"); + log.fatal("This is a FATAL message, investigate this!"); } } +---- + +In a development environment, change your log level to `DEBUG`, as this can help you debug issues or catch potential ones before they get into production. + +[,java] +---- + log.setLevel(Level.DEBUG); +---- + +In a production environment, consider modifying your log level to `ERROR` or `FATAL`. This will output log only when your application has errors, reducing the log output and help you focus on important data about your application status. + +[,java] +---- + log.setLevel(Level.ERROR); +---- + +You can fine tune various Kubernetes components log levels. For example, if you are using https://bottlerocket.dev/[Bottlerocket] as your EKS Node operating system, there are configuration settings that allow you to adjust the kubelet process log level. A snippet of this configuration setting is below. Note the default https://github.com/bottlerocket-os/bottlerocket/blob/3f716bd68728f7fd825eb45621ada0972d0badbb/README.md?plain=1#L528[log level] of *2* which adjusts the logging verbosity of the `kubelet` process. + +---- +[settings.kubernetes] +log-level = "2" +image-gc-high-threshold-percent = "85" +image-gc-low-threshold-percent = "80" +---- + +For a development environment, you can set the log level greater than **2** in order to view additional events, this is good for debugging. For a production environment, you can set the level to **0** in order to view only critical events. + +=== Leverage Filters + +When using a default EKS Fluentbit configuration to send container logs to Cloudwatch, FluentBit captures and send **ALL** application container logs enriched with Kubernetes metadata to Cloudwatch as shown in the `[INPUT]` configuration block below. +---- + + [INPUT] + Name tail + Tag application.* + Exclude_Path /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy* + Path /var/log/containers/*.log + Docker_Mode On + Docker_Mode_Flush 5 + Docker_Mode_Parser container_firstline + Parser docker + DB /var/fluent-bit/state/flb_container.db + Mem_Buf_Limit 50MB + Skip_Long_Lines On + Refresh_Interval 10 + Rotate_Wait 30 + storage.type filesystem + Read_from_Head ${READ_FROM_HEAD} +---- + +The `[INPUT]` section above is ingesting all the container logs. This can generate a large amount of data that might not be necessary. Filtering out this data can reduce the amount of log data sent to CloudWatch therefore reducing your cost. You can apply a filter to you logs before it outputs to CloudWatch. Fluentbit defines this in the `[FILTER]` section. For example, filtering out the Kubernetes metadata from being appended to log events can reduce your log volume. + +---- + [FILTER] + Name nest + Match application.* + Operation lift + Nested_under kubernetes + Add_prefix Kube. + + [FILTER] + Name modify + Match application.* + Remove Kube. + Remove Kube. + Remove Kube. + + [FILTER] + Name nest + Match application.* + Operation nest + Wildcard Kube.* + Nested_under kubernetes + Remove_prefix Kube. +---- + +== Metrics + +https://aws-observability.github.io/observability-best-practices/signals/metrics/[Metrics] provide valuable information regarding the performance of your system. By consolidating all system-related or available resource metrics in a centralized location, you gain the capability to compare and analyze performance data. This centralized approach enables you to make more informed strategic decisions, such as scaling up or scaling down resources. Additionally, metrics play a crucial role in assessing the health of resources, allowing you to take proactive measures when necessary. Generally observability costs scale with telemetry data collection and retention. Below are a few strategies you can implement to reduce the cost of metric telemetry: collecting only metrics that matter, reducing the cardinality of your telemetry data, and fine tuning the granularity of your telemetry data collection. + +=== Monitor what matters and collect only what you need + +The first cost reduction strategy is to reduce the number of metrics you are collecting and in turn, reduce retention costs. + +. Begin by working backwards from your and/or your stakeholder's requirements to determine https://aws-observability.github.io/observability-best-practices/guides/#monitor-what-matters[the metrics that are most important]. Success metrics are different for everyone! Know what _good_ looks like and measure for it. +. Consider diving deep into the workloads you are supporting and identifying its Key Performance Indicators (KPIs) a.k.a 'Golden Signals'. These should align to business and stake-holder requirements. Calculating SLIs, SLOs, and SLAs using Amazon CloudWatch and Metric Math is crucial for managing service reliability. Follow the best practices outlined in this https://aws-observability.github.io/observability-best-practices/guides/operational/business/key-performance-indicators/#10-understanding-kpis-golden-signals[guide] to effectively monitor and maintain the performance of your EKS environment. +. Then continue through the different layers of infrastructure to https://aws-observability.github.io/observability-best-practices/signals/metrics/#correlate-with-operational-metric-data[connect and correlate] EKS cluster, node and additional infrastructure metrics to your workload KPIs. Store your business metrics and operational metrics in a system where you can correlate them together and draw conclusions based on observed impacts to both. +. EKS exposes metrics from the control plane, cluster kube-state-metrics, pods, and nodes. The relevance of all these metrics is dependent on your needs, however it's likely that you will not need every single metric across the different layers. You can use this https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/best-practices-metrics-collection/[EKS essential metrics] guide as a baseline for monitoring the overall health of an EKS cluster and your workloads. + +Here is an example prometheus scrape config where we are using the `relabel_config` to keep only kubelet metrics and `metric_relabel_config` to drop all container metrics. + +[,yaml] +---- + kubernetes_sd_configs: + - role: endpoints + namespaces: + names: + - kube-system + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + tls_config: + insecure_skip_verify: true + relabel_configs: + - source_labels: [__meta_kubernetes_service_label_k8s_app] + regex: kubelet + action: keep + + metric_relabel_configs: + - source_labels: [__name__] + regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) + action: drop +---- + +=== Reduce cardinality where applicable + +Cardinality refers to the uniqueness of the data values in combination with its dimensions (eg. prometheus labels) for a specific metrics set. High cardinality metrics have many dimensions and each dimension metric combination has higher uniqueness. Higher cardinality results in larger metric telemetry data size and storage needs which increases cost. + +In the high cardinality example below, we see that the Metric, Latency, has Dimensions, RequestID, CustomerID, and Service and each Dimension has many unique values. Cardinality is the measure of the combination of the number of possible values per Dimension. In Prometheus, each set of unique dimensions/labels are consider as a new metric, therefore high cardinality means more metrics. + +image::../images/high-cardinality.png[high cardinality] + +In EKS environments with many metrics and dimensions/labels per metric (Cluster, Namespace, Service, Pod, Container, etc), the cardinality tends to grow. In order to optimize cost, consider the cardinality of the metrics you are collecting carefully. For example, if you are aggregating a specific metric for visualization at the cluster level, then you can drop additional labels that are at a lower layer such as the namespace label. + +In order to identify high cardinality metrics in prometheus you can run the following PROMQL query to determine which scrape targets have the highest number of metrics (cardinality): + +[,promql] +---- +topk_max(5, max_over_time(scrape_samples_scraped[1h])) +---- + +and the following PROMQL query can help you determine which scrape targets have the highest metrics churn (how many new metrics series were created in a given scrape) rates : + +[,promql] +---- +topk_max(5, max_over_time(scrape_series_added[1h])) +---- + +If you are using grafana you can use Grafana Lab's Mimirtool to analyze your grafana dashboards and prometheus rules to identify unused high-cardinality metrics. Follow https://grafana.com/docs/grafana-cloud/account-management/billing-and-usage/control-prometheus-metrics-usage/usage-analysis-mimirtool/?pg=blog&plcmt=body-txt#analyze-and-reduce-metrics-usage-with-grafana-mimirtool[this guide] on how to use the `mimirtool analyze` and `mimirtool analyze prometheus` commands to identify active metrics which are not referenced in your dashboards. + +=== Consider metric granularity + +Collecting metrics at a higher granularity like every second vs every minute can have a big impact on how much telemetry is collected and stored which increases cost. Determine sensible scrape or metrics collection intervals that balance between enough granularity to see transient issues and low enough to be cost effective. Decrease granularity for metrics that are used for capacity planning and larger time window analysis. + +Below is a snippet from the default AWS Distro for Opentelemetry (ADOT) EKS Addon Collector https://docs.aws.amazon.com/eks/latest/userguide/deploy-deployment.html[configuration]. + +!!! attention + the global prometheus scrape interval is set to 15s. This scrape interval can be increased resulting in a decrease in the amount of metric data collected in prometheus. + +---- +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: my-collector-amp + +... + +config: | + extensions: + sigv4auth: + region: "++++++" service: "aps"++++++ + + receivers: + # + # Scrape configuration for the Prometheus Receiver + # This is the same configuration used when Prometheus is installed using the community Helm chart + # + prometheus: + config: + global: scrape_interval: 15s + scrape_timeout: 10s +---- + +== Tracing + +The primary cost associated with tracing stem from trace storage generation. With tracing, the aim is to gather sufficient data to diagnose and understand performance aspects. However, as X-Ray traces costs are based on data forwarded to to X-Ray, erasing traces after it has been forward will not reduce your costs. Let's review ways to lower your costs for tracing while maintaining data for you to perform proper analysis. + +=== Apply Sampling rules + +The X-Ray sampling rate is conservative by default. Define sampling rules where you can control the amount of data that you gather. This will improve performance efficiency while reducing costs. By https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html#xray-console-custom[decreasing the sampling rate], you can collect traces from the request only what your workloads needs while maintaining a lower cost structure. + +For example, you have java application that you want to debug the traces of all the requests for 1 problematic route. + +*Configure via the SDK to load sampling rules from a JSON document* + +[,json] +---- +{ +"version": 2, + "rules": [ + { +"description": "debug-eks", + "host": "*", + "http_method": "PUT", + "url_path": "/history/*", + "fixed_target": 0, + "rate": 1, + "service_type": "debug-eks" + } + ], + "default": { +"fixed_target": 1, + "rate": 0.1 + } +} +---- + +*Via the Console* + +image::../images/console.png[console] + +=== Apply Tail Sampling with AWS Distro for OpenTelemetry (ADOT) + +ADOT Tail Sampling allows you to control the volume of traces ingested in the service. However, Tail Sampling allows you to define the sampling policies after all the spans in the request have been completed instead of at the beginning. This further limits the amount of raw data transferred to CloudWatch, hence reducing cost. + +For example, if you're sampling 1% of traffic to a landing page and 10% of the requests to a payment page this might leave you with 300 traces for an 30 minute period. With an ADOT Tail Sampling rule of that filters specific errors, you could be left with 200 traces which decreases the number of traces stored. + +---- +processors: + groupbytrace: + wait_duration: 10s + num_traces: 300 + tail_sampling: + decision_wait: 1s # This value should be smaller than wait_duration + policies: + - ..... # Applicable policies** + batch/tracesampling: + timeout: 0s # No need to wait more since this will happen in previous processors + send_batch_max_size: 8196 # This will still allow us to limit the size of the batches sent to subsequent exporters + +service: + pipelines: + traces/tailsampling: + receivers: [otlp] + processors: [groupbytrace, tail_sampling, batch/tracesampling] + exporters: [awsxray] +---- + +=== Leverage Amazon S3 Storage options + +You should leverage AWS S3 bucket and its different storage classes to store the traces. Export traces to S3 before the retention period expires. Use Amazon S3 Lifecycle rules to move the trace data to the storage class that meets your requirements. + +For example, if you have traces that are 90 days old, https://aws.amazon.com/s3/storage-classes/intelligent-tiering/[Amazon S3 Intelligent-Tiering] can automatically move the data to long-term storage based on your usage pattern. You can use https://aws.amazon.com/athena/[Amazon Athena] to query the data in Amazon S3 if you need to refer back to the traces at a later time. This can further reduce your cost for distributed tracing. + +== Additional Resources: + +* https://aws-observability.github.io/observability-best-practices/guides/[Observability Best Practices Guide] +* https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/[Best Practices Metrics Collection] +* https://www.youtube.com/watch?v=zZPzXEBW4P8[AWS re:Invent 2022 - Observability best practices at Amazon (COP343)] +* https://www.youtube.com/watch?v=YiegAlC_yyc[AWS re:Invent 2022 - Observability: Best practices for modern applications (COP344)] diff --git a/latest/bpg/cost/cost_opt_storage.adoc b/latest/bpg/cost/cost_opt_storage.adoc new file mode 100644 index 000000000..e4ceba56f --- /dev/null +++ b/latest/bpg/cost/cost_opt_storage.adoc @@ -0,0 +1,167 @@ +//!!NODE_ROOT
+[."topic"] +[[cost-opt-storage,cost-opt-storage.title]] += Cost Optimization - Storage +:info_doctype: section +:imagesdir: images/ +:info_title: Storage +:info_abstract: Storage +:info_titleabbrev: Storage +:authors: ["Chance Lee"] +:date: 2023-10-31 + +== Overview + +There are scenarios where you may want to run applications that need to preserve data for a short or long term basis. For such use cases, volumes can be defined and mounted by Pods so that their containers can tap into different storage mechanisms. Kubernetes supports different types of https://kubernetes.io/docs/concepts/storage/volumes/[volumes] for ephemeral and persistent storage. The choice of storage largely depends on application requirements. For each approach, there are cost implications, and the practices detailed below which will help you accomplish cost efficiency for workloads needing some form of storage in your EKS environments. + +== Ephemeral Volumes + +Ephemeral volumes are for applications that require transient local volumes but don't require data to be persisted after restarts. Examples of this include requirements for scratch space, caching, and read-only input data like configuration data and secrets. You can find more details of Kubernetes ephemeral volumes https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/[here]. Most of ephemeral volumes (e.g. emptyDir, configMap, downwardAPI, secret, hostpath) are backed by locally-attached writable devices (usually the root disk) or RAM, so it's important to choose the most cost efficient and performant host volume. + +=== Using EBS Volumes + +_We recommend starting with https://aws.amazon.com/ebs/general-purpose/[gp3] as the host root volume._ It is the latest general purpose SSD volume offered by Amazon EBS and also offers a lower price (up to 20%) per GB compared to gp2 volumes. + +=== Using Amazon EC2 Instance Stores + +https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html[Amazon EC2 instance stores] provide temporary block-level storage for your EC2 instances. The storage provided by EC2 instance stores is accessible through disks that are physically attached to the hosts. Unlike Amazon EBS, you can only attach instance store volumes when the instance is launched, and these volumes only exist during the lifetime of the instance. They cannot be detached and re-attached to other instances. You can learn more about Amazon EC2 instance stores https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html[here]. _There are no additional fees associated with an instance store volume._ This makes them (instance store volumes) _more cost efficient_ than the the general EC2 instances with large EBS volumes. + +To use local store volumes in Kubernetes, you should partition, configure, and format the disks https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html[using the Amazon EC2 user-data] so that volumes can be mounted as a https://kubernetes.io/docs/concepts/storage/volumes/#hostpath[HostPath] in the pod spec. Alternatively, you can leverage the https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner[Local Persistent Volume Static Provisioner] to simplify local storage management. The Local Persistent Volume static provisioner allows you to access local instance store volumes through the standard Kubernetes PersistentVolumeClaim (PVC) interface. Furthermore, it will provision PersistentVolumes (PVs) that contains node affinity information to schedule Pods to the correct nodes. Although it uses Kubernetes PersistentVolumes, EC2 instance store volumes are ephemeral in nature. Data written to ephemeral disks is only available during the instance's lifetime. When the instance is terminated, so is the data. Please refer to this https://aws.amazon.com/blogs/containers/eks-persistent-volumes-for-instance-store/[blog] for more details. + +Keep in mind that when using Amazon EC2 instance store volumes, the total IOPS limit is shared with the host and it binds Pods to a specific host. You should thoroughly review your workload requirements before adopting Amazon EC2 instance store volumes. + +== Persistent Volumes + +Kubernetes is typically associated with running stateless applications. However, there are scenarios where you may want to run microservices that need to preserve persistent data or information from one request to the next. Databases are a common example for such use cases. However, Pods, and the containers or processes inside them, are ephemeral in nature. To persist data beyond the lifetime of a Pod, you can use PVs to define access to storage at a specific location that is independent from the Pod. _The costs associated with PVs is highly dependent on the type of storage being used and how applications are consuming it._ + +There are different types of storage options that support Kubernetes PVs on Amazon EKS listed https://docs.aws.amazon.com/eks/latest/userguide/storage.html[here]. The storage options covered below are Amazon EBS, Amazon EFS, Amazon FSx for Lustre, Amazon FSx for NetApp ONTAP. + +=== Amazon Elastic Block Store (EBS) Volumes + +Amazon EBS volumes can be consumed as Kubernetes PVs to provide block-level storage volumes. These are well suited for databases that rely on random reads & writes and throughput-intensive applications that perform long, continuous reads and writes. https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html[The Amazon Elastic Block Store Container Storage Interface (CSI) driver] allows Amazon EKS clusters to manage the lifecycle of Amazon EBS volumes for persistent volumes. The Container Storage Interface enables and facilitates interaction between Kubernetes and a storage system. When a CSI driver is deployed to your EKS cluster, you can access it's capabilities through the native Kubernetes storage resources such as Persistent Volumes (PVs), Persistent Volume Claims (PVCs) and Storage Classes (SCs). This https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes[link] provides practical examples of how to interact with Amazon EBS volumes with Amazon EBS CSI driver. + +==== Choosing the right volume + +_We recommend using the latest generation of block storage (gp3) as it provides the right balance between price and performance_. It also allows you to scale volume IOPS and throughput independently of volume size without needing to provision additional block storage capacity. If you're currently using gp2 volumes, we highly recommend migrating to gp3 volumes. This https://aws.amazon.com/blogs/containers/migrating-amazon-eks-clusters-from-gp2-to-gp3-ebs-volumes/[blog] explains how to migrate from _gp2_ on _gp3_ on Amazon EKS clusters. + +When you have applications that require higher performance and need volumes larger than what a single https://aws.amazon.com/ebs/general-purpose/[gp3 volume can support], you should consider using https://aws.amazon.com/ebs/provisioned-iops/[io2 block express]. This type of storage is ideal for your largest, most I/O intensive, and mission critical deployment such as SAP HANA or other large databases with low latency requirements. Keep in mind that an instance's EBS performance is bounded by the instance's performance limits, so not all the instances support io2 block express volumes. You can check the supported instance types and other considerations in this https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/provisioned-iops.html[doc]. + +_A single gp3 volume can support up to up to 16,000 max IOPS, 1,000 MiB/s max throughput, max 16TiB. The latest generation of Provisioned IOPS SSD volume that provides up to 256,000 IOPS, 4,000 MiB/s, throughput, and 64TiB._ + +Among these options, you should best tailor your storage performance and cost to the needs of your applications. + +==== Monitor and optimize over time + +It's important to understand your application's baseline performance and monitor it for selected volumes to check if it's meeting your requirements/expectations or if it's over-provisioned (e.g. a scenario where provisioned IOPS are not being fully utilized). + +Instead of allocating a large volume from the beginning, you can gradually increase the size of the volume as you accumulate data. You can dynamically re-size volumes using the https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes/resizing[volume resizing] feature in the Amazon Elastic Block Store CSI driver (aws-ebs-csi-driver). _Keep in mind that you can only increase the EBS volume size._ + +To identify and remove any dangling EBS volumes, you can use https://docs.aws.amazon.com/awssupport/latest/user/cost-optimization-checks.html[AWS trusted advisor's cost optimization category]. This feature helps you identify unattached volumes or volumes with very low write activity for a period of time. There is a cloud-native open-source, read-only tool called https://github.com/derailed/popeye[Popeye] that scans live Kubernetes clusters and reports potential issues with deployed resources and configurations. For example, it can scan for unused PVs and PVCs and check whether they are bound or whether there is any volume mount error. + +For a deep dive on monitoring, please refer to the https://aws.github.io/aws-eks-best-practices/cost_optimization/cost_opt_observability/[EKS cost optimization observability guide]. + +One other option you can consider is the https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-ebs-recommendations.html[AWS Compute Optimizer Amazon EBS volume recommendations]. This tool automatically identifies the optimal volume configuration and correct level of performance needed. For example, it can be used for optimal settings pertaining to provisioned IOPS, volume sizes, and types of EBS volumes based on the maximum utilization during the past 14 days. It also quantifies the potential monthly cost savings derived from its recommendations. You can review this https://aws.amazon.com/blogs/storage/cost-optimizing-amazon-ebs-volumes-using-aws-compute-optimizer/[blog] for more details. + +==== Backup retention policy + +You can back up the data on your Amazon EBS volumes by taking point-in-time snapshots. The Amazon EBS CSI driver supports volume snapshots. You can learn how to create a snapshot and restore an EBS PV using the steps outlined https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/examples/kubernetes/snapshot/README.md[here]. + +Subsequent snapshots are incremental backups, meaning that only the blocks on the device that have changed after your most recent snapshot are saved. This minimizes the time required to create the snapshot and saves on storage costs by not duplicating data. However, growing the number of old EBS snapshots without a proper retention policy can cause unexpected costs when operating at scale. If you're directly backing up Amazon EBS volumes through AWS API, you can leverage https://aws.amazon.com/ebs/data-lifecycle-manager/[Amazon Data Lifecycle Manager] (DLM) that provides an automated, policy-based lifecycle management solution for Amazon Elastic Block Store (EBS) Snapshots and EBS-backed Amazon Machine Images (AMIs). The console makes it easier to automate the creation, retention, and deletion of EBS Snapshots and AMIs. + +!!! note + There is currently no way to make use of Amazon DLM via the Amazon EBS CSI driver. + +In a Kubernetes environment, you can leverage an open-source tool called https://velero.io/[Velero] to backup your EBS Persistent Volumes. You can set a TTL flag when scheduling the job to expire backups. Here is a https://velero.io/docs/v1.12/how-velero-works/#set-a-backup-to-expire[guide] from Velero as an example. + +=== Amazon Elastic File System (EFS) + +https://aws.amazon.com/efs/[Amazon Elastic File System (EFS)] is a serverless, fully elastic file system that lets you share file data using standard file system interface and file system semantics for a broad spectrum of workloads and applications. Examples of workloads and applications include Wordpress and Drupal, developer tools like JIRA and Git, and shared notebook system such as Jupyter as well as home directories. + +One of main benefits of Amazon EFS is that it can be mounted by multiple containers spread across multiple nodes and multiple availability zones. Another benefit is that you only pay for the storage you use. EFS file systems will automatically grow and shrink as you add and remove files which eliminates the need for capacity planning. + +To use Amazon EFS in Kubernetes, you need to use the Amazon Elastic File System Container Storage Interface (CSI) Driver, https://github.com/kubernetes-sigs/aws-efs-csi-driver[aws-efs-csi-driver]. Currently, the driver can dynamically create https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html[access points]. However, the Amazon EFS file system has to be provisioned first and provided as an input to the Kubernetes storage class parameter. + +==== Choosing the right EFS storage class + +Amazon EFS offers https://docs.aws.amazon.com/efs/latest/ug/storage-classes.html[four storage classes]. + +Two standard storage classes: + +* Amazon EFS Standard +* https://aws.amazon.com/blogs/aws/optimize-storage-cost-with-reduced-pricing-for-amazon-efs-infrequent-access/[Amazon EFS Standard-Infrequent Access] (EFS Standard-IA) + +Two one-zone storage classes: + +* https://aws.amazon.com/blogs/aws/new-lower-cost-one-zone-storage-classes-for-amazon-elastic-file-system/[Amazon EFS One Zone] +* Amazon EFS One Zone-Infrequent Access (EFS One Zone-IA) + +The Infrequent Access (IA) storage classes are cost-optimized for files that are not accessed every day. With Amazon EFS lifecycle management, you can move files that have not been accessed for the duration of the lifecycle policy (7, 14, 30, 60, or 90 days) to the IA storage classes _which can reduce the storage cost by up to 92 percent compared to EFS Standard and EFS One Zone storage classes respectively_. + +With EFS Intelligent-Tiering, lifecycle management monitors the access patterns of your file system and automatically move files to the most optimal storage class. + +!!! note + aws-efs-csi-driver currently doesn't have a control on changing storage classes, lifecycle management or Intelligent-Tiering. Those should be setup manually in the AWS console or through the EFS APIs. + +!!! note + aws-efs-csi-driver isn't compatible with Window-based container images. + +!!! note + There is a known memory issue when _vol-metrics-opt-in_ (to emit volume metrics) is enabled due to the https://github.com/kubernetes/kubernetes/blob/ee265c92fec40cd69d1de010b477717e4c142492/pkg/volume/util/fs/fs.go#L66[DiskUsage] function that consumes an amount of memory that is proportional to the size of your filesystem. _Currently, we recommend to disable the_ _`--vol-metrics-opt-in` option on large filesystems to avoid consuming too much memory. Here is a github issue https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/1104[link] for more details._ + +=== Amazon FSx for Lustre + +Lustre is a high-performance parallel file system commonly used in workloads requiring throughput up to hundreds of GB/s and sub-millisecond per-operation latencies. It's used for scenarios such as machine learning training, financial modeling, HPC, and video processing. https://aws.amazon.com/fsx/lustre/[Amazon FSx for Lustre] provides a fully managed shared storage with the scalability and performance, seamlessly integrated with Amazon S3. + +You can use Kubernetes persistent storage volumes backed by FSx for Lustre using the https://github.com/kubernetes-sigs/aws-fsx-csi-driver[FSx for Lustre CSI driver] from Amazon EKS or your self-managed Kubernetes cluster on AWS. See the https://docs.aws.amazon.com/eks/latest/userguide/fsx-csi.html[Amazon EKS documentation] for more details and examples. + +==== Link to Amazon S3 + +It's recommended to link a highly durable long-term data repository residing on Amazon S3 with your FSx for Lustre file system. Once linked, large datasets are lazy-loaded as needed from Amazon S3 to FSx for Lustre file systems. You can also run your analyses and your results back to S3, and then delete your [Lustre] file system. + +==== Choosing the right deployment and storage options + +FSx for Lustre provides different deployment options. The first option is called _scratch_ and it doesn't replicate data, while the second option is called _persistent_ which, as the name implies, persists data. + +The first option (_scratch_) can be used _to reduce the cost of temporary shorter-term data processing._ The persistent deployment option _is designed for longer-term storage_ that automatically replicates data within an AWS Availability Zone. It also supports both SSD and HDD storage. + +You can configure the desired deployment type under parameters in the FSx for lustre filesystem's Kubernetes StorageClass. Here is an https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass[link] that provides sample templates. + +!!! note + For latency-sensitive workloads or workloads requiring the highest levels of IOPS/throughput, you should choose SSD storage. For throughput-focused workloads that aren't latency-sensitive, you should choose HDD storage. + +==== Enable data compression + +You can also enable data compression on your file system by specifying "`LZ4`" as the Data Compression Type. Once it's enabled, all newly-written files will be automatically compressed on FSx for Lustre before they are written to disk and uncompressed when they are read. LZ4 data compression algorithm is lossless so the original data can be fully reconstructed from the compressed data. + +You can configure the data compression type as LZ4 under parameters in the FSx for lustre filesystem's Kubernetes StorageClass. Compression is disabled when the value is set to NONE, which is default. This https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass[link] provides sample templates. + +!!! note + Amazon FSx for Lustre isn't compatible with Window-based container images. + +=== Amazon FSx for NetApp ONTAP + +https://aws.amazon.com/fsx/netapp-ontap/[Amazon FSx for NetApp ONTAP] is a fully managed shared storage built on NetApp's ONTAP file system. FSx for ONTAP provides feature-rich, fast, and flexible shared file storage that's broadly accessible from Linux, Windows, and macOS compute instances running in AWS or on premises. + +Amazon FSx for NetApp ONTAP supports two tiers of storage: _1/primary tier_ and _2/capacity pool tier._ + +The _primary tier_ is a provisioned, high-performance SSD-based tier for active, latency-sensitive data. The fully elastic _capacity pool tier_ is cost-optimized for infrequently accessed data, automatically scales as data is tiered to it, and offers virtually unlimited petabytes of capacity. You can enable data compression and deduplication on capacity pool storage and further reduce the amount of storage capacity your data consumes. NetApp's native, policy-based FabricPool feature continually monitors data access patterns, automatically transferring data bidirectionally between storage tiers to optimize performance and cost. + +NetApp's Astra Trident provides dynamic storage orchestration using a CSI driver which allows Amazon EKS clusters to manage the lifecycle of persistent volumes PVs backed by Amazon FSx for NetApp ONTAP file systems. To get started, see https://docs.netapp.com/us-en/trident/trident-use/trident-fsx.html[Use Astra Trident with Amazon FSx for NetApp ONTAP] in the Astra Trident documentation. + +== Other considerations + +=== Minimize the size of container image + +Once containers are deployed, container images are cached on the host as multiple layers. By reducing the size of images, the amount of storage required on the host can be reduced. + +By using slimmed-down base images such as https://hub.docker.com/_/scratch[scratch] images or https://github.com/GoogleContainerTools/distroless[distroless] container images (that contain only your application and its runtime dependencies) from the beginning, _you can reduce storage cost in addition to other ancillary benefits such as a reducing the attack surface area and shorter image pull times._ + +You should also consider using open source tools, such as https://www.slim.ai/docs/quickstart[Slim.ai] that provides an easy, secure way to create minimal images. + +Multiple layers of packages, tools, application dependencies, libraries can easily bloat the container image size. By using multi-stage builds, you can selectively copy artifacts from one stage to another, excluding everything that isn't necessary from the final image. You can check more image-building best practices https://docs.docker.com/get-started/09_image_best/[here]. + +Another thing to consider is how long to persist cached images. You may want to clean up the stale images from the image cache when a certain amount of disk is utilized. Doing so will help make sure you have enough space for the host's operation. By default, the https://kubernetes.io/docs/reference/generated/kubelet[kubelet] performs garbage collection on unused images every five minutes and on unused containers every minute. + +_To configure options for unused container and image garbage collection, tune the kubelet using a https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/[configuration file] and change the parameters related to garbage collection using the https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/[`KubeletConfiguration`] resource type._ + +You can learn more about it in the Kubernetes https://kubernetes.io/docs/concepts/architecture/garbage-collection/#containers-images[documentation]. diff --git a/latest/bpg/cost/cost_optimization_index.adoc b/latest/bpg/cost/cost_optimization_index.adoc new file mode 100644 index 000000000..5f429a5cb --- /dev/null +++ b/latest/bpg/cost/cost_optimization_index.adoc @@ -0,0 +1,41 @@ += Amazon EKS Best Practices Guide for Cost Optimization +:doctype: book + +Cost Optimization is achieving your business outcomes at the lowest price point. By following the documentation in this guide you will optimize your Amazon EKS workloads. + += General Guidelines + +In the cloud, there are a number of general guidelines that can help you achieve cost optimization of your microservices: + +* Ensure that workloads running on Amazon EKS are independent of specific infrastructure types for running your containers, this will give greater flexibility with regards to running them on the least expensive types of infrastructure. While using Amazon EKS with EC2, there can be exceptions when we have workloads that require specific type of EC2 Instance types like https://docs.aws.amazon.com/eks/latest/userguide/gpu-ami.html[requiring a GPU] or other instance types, due to the nature of the workload. +* Select optimally profiled container instances -- profile your production or pre-production environments and monitor critical metrics like CPU and memory, using services like https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html[Amazon CloudWatch Container Insights for Amazon EKS] or third party tools that are available in the Kubernetes ecosystem. This will ensure that we can allocate the right amount of resources and avoid wastage of resources. +* Take advantage of the different purchasing options that are available in AWS for running EKS with EC2, e.g. On-Demand, Spot and Savings Plan. + += EKS Cost Optimization Best Practices + +There are three general best practice areas for cost optimization in the cloud: + +* Cost-effective resources (Auto Scaling, Down Scaling, Policies and Purchasing Options) +* Expenditure awareness (Using AWS and third party tools) +* Optimizing over time (Right Sizing) + +As with any guidance there are trade-offs. Ensure you work with your organization to understand the priorities for this workload and which best practices are most important. + +== How to use this guide + +This guide is meant for devops teams who are responsible for implementing and managing the EKS clusters and the workloads they support. The guide is organized into different best practice areas for easier consumption. Each topic has a list of recommendations, tools to use and best practices for cost optimization of your EKS clusters. The topics do not need to read in a particular order. + +=== Key AWS Services and Kubernetes features + +Cost optimization is supported by the following AWS services and features: + +* EC2 Instance types, Savings Plan (and Reserved Instances) and Spot Instances, at different prices. +* Auto Scaling along with Kubernetes native Auto Scaling policies. Consider Savings Plan (Previously Reserved Instances) for predictable workloads. Use managed data stores like EBS and EFS, for elasticity and durability of the application data. +* The Billing and Cost Management console dashboard along with AWS Cost Explorer provides an overview of your AWS usage. Use AWS Organizations for granular billing details. Details of several third party tools have also been shared. +* Amazon CloudWatch Container Metrics provides metrics around usage of resources by the EKS cluster. In addition to the Kubernetes dashboard, there are several tools in the Kubernetes ecosystem that can be used to reduce wastage. + +This guide includes a set of recommendations that you can use to improve the cost optimization of your Amazon EKS cluster. + +== Feedback + +This guide is being released on GitHub so as to collect direct feedback and suggestions from the broader EKS/Kubernetes community. If you have a best practice that you feel we ought to include in the guide, please file an issue or submit a PR in the GitHub repository. Our intention is to update the guide periodically as new features are added to the service or when a new best practice evolves. diff --git a/latest/bpg/cost/optimizing.adoc b/latest/bpg/cost/optimizing.adoc new file mode 100644 index 000000000..b5826c249 --- /dev/null +++ b/latest/bpg/cost/optimizing.adoc @@ -0,0 +1,81 @@ += Optimizing over time (Right Sizing) + +Right Sizing as per the AWS Well-Architected Framework, is "`... using the lowest cost resource that still meets the technical specifications of a specific workload`". + +When you specify the resource `requests` for the Containers in a Pod, the scheduler uses this information to decide which node to place the Pod on. When you specify a resource `limits` for a Container, the kubelet enforces those limits so that the running container is not allowed to use more of that resource than the limit you set. The details of how Kubernetes manages resources for containers are given in the https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/[documentation]. + +In Kubernetes, this means setting the right compute resources (https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/[CPU and memory are collectively referred to as compute resources]) - setting the resource `requests` that align as close as possible to the actual utilization. The tools for getting the actual resource usags of Pods are given in the section on Rexommendations below. + +*Amazon EKS on AWS Fargate*: When pods are scheduled on Fargate, the vCPU and memory reservations within the pod specification determine how much CPU and memory to provision for the pod. If you do not specify a vCPU and memory combination, then the smallest available combination is used (.25 vCPU and 0.5 GB memory). The list of vCPU and memory combinations that are available for pods running on Fargate are listed in the https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html[Amazon EKS User Guide]. + +*Amazon EKS on EC2*: When you create a Pod, you can specify how much of each resource like CPU and Memory, a Container needs. It is important we do not over-provision (which will lead to wastage) or under-provision (will lead to throttling) the resources allocated to the containers. + +== Recommendations + +=== Use tools to help you allocate resources based on observed data + +There are tools like https://github.com/hjacobs/kube-resource-report[kube resource report] which can help with right sizing of pods deployed on Amazon EKS with EC2 nodes. + +Deployment steps for kube resource report: + + $ git clone https://github.com/hjacobs/kube-resource-report + $ cd kube-resource-report + $ helm install kube-resource-report ./unsupported/chart/kube-resource-report + $ helm status kube-resource-report + $ export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=kube-resource-report,app.kubernetes.io/instance=kube-resource-report" -o jsonpath="{.items[0].metadata.name}") + $ echo "Visit http://127.0.0.1:8080 to use your application" + $ kubectl port-forward $POD_NAME 8080:8080 + +Screenshots from a sample reports from this tool: + +image::../images/kube-resource-report1.png[Home Page] + +image::../images/kube-resource-report2.png[Cluster level data] + +image::../images/kube-resource-report3.png[Pod level data] + +*FairwindsOps Goldilocks*: The https://github.com/FairwindsOps/goldilocks[FairwindsOps Goldilocks] is a tool that creates a Vertical Pod Autoscaler (VPA) for each deployment in a namespace and then queries them for information. Once the VPAs are in place, we see recommendations appear in the Goldilocks dashboard. + +Deploy the Vertical Pod Autoscaler as per the https://docs.aws.amazon.com/eks/latest/userguide/vertical-pod-autoscaler.html[documentation]. + +Enable Namespace - Pick an application namespace and label it like so in order to see some data, in the following example we are specifying the default namespace: + + $ kubectl label ns default goldilocks.fairwinds.com/enabled=true + +Viewing the Dashboard - The default installation creates a ClusterIP service for the dashboard. You can access via port forward: + + $ kubectl -n goldilocks port-forward svc/goldilocks-dashboard 8080:80 + +Then open your browser to http://localhost:8080 + +image::../images/Goldilocks.png[Goldilocks recommendation Page] + +=== Use Application Profiling tools like CloudWatch Container Insights and Prometheus Metrics in Amazon CloudWatch + +Use https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html[CloudWatch Container Insights] to see how you can use native CloudWatch features to monitor your EKS Cluster performance. You can use CloudWatch Container Insights to collect, aggregate, and summarize metrics and logs from your containerized applications and microservices running on Amazon Elastic Kubernetes Service. The metrics include utilization for resources such as CPU, memory, disk, and network - which can help with right-sizing Pods and save costs. + +https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights-Prometheus-metrics.html[Container Insights Prometheus Metrics Monitoring] At present, support for Prometheus metrics is still in beta. CloudWatch Container Insights monitoring for Prometheus automates the discovery of Prometheus metrics from containerized systems and workloads. Prometheus is an open-source systems monitoring and alerting toolkit. All Prometheus metrics are collected in the ContainerInsights/Prometheus namespace. + +The Metrics provided by cAdvisor and kube-state-metrics can be used for monitoring pods on Amazon EKS on AWS Fargate using Prometheus and Grafana, which can then be used to implement *requests* in your containers. Please refer to https://aws.amazon.com/blogs/containers/monitoring-amazon-eks-on-aws-fargate-using-prometheus-and-grafana/[this blog] for more details. + +*Right Size Guide*: The https://mhausenblas.info/right-size-guide/[right size guide (rsg)] is a simple CLI tool that provides you with memory and CPU recommendations for your application. This tool works across container orchestrators, including Kubernetes and easy to deploy. + +By using tools like CloudWatch Container Insights, Kube Resource Report, Goldilocks and others, applications running in the Kubernetes cluster can be right sized and potentially lower your costs. + +== Resources + +Refer to the following resources to learn more about best practices for cost optimization. + +=== Documentation and Blogs + +* https://www.eksworkshop.com/intermediate/250_cloudwatch_container_insights/[Amazon EKS Workshop - Setting up EKS CloudWatch Container Insights] +* https://aws.amazon.com/blogs/containers/using-prometheus-metrics-in-amazon-cloudwatch/[Using Prometheus Metrics in Amazon CloudWatch] +* https://aws.amazon.com/blogs/containers/monitoring-amazon-eks-on-aws-fargate-using-prometheus-and-grafana/[Monitoring Amazon EKS on AWS Fargate using Prometheus and Grafana] + +=== Tools + +* https://github.com/hjacobs/kube-resource-report[Kube resource report] +* https://github.com/mhausenblas/right-size-guide[Right size guide] +* https://github.com/mreferre/fargatecount[Fargate count] +* https://github.com/FairwindsOps/goldilocks[FairwindsOps Goldilocks] +* https://learnk8s.io/research#choosing-node-size[Choose Right Node Size] From ef18d9b661690f031f61edde4198ab843c40b407 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Fri, 28 Jun 2024 22:37:59 +0000 Subject: [PATCH 19/56] fixup: --- latest/bpg/cost/cfm_framework.adoc | 12 ++++----- latest/bpg/cost/cost_opt_networking.adoc | 28 ++++++++++----------- latest/bpg/cost/cost_opt_observability.adoc | 4 +-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/latest/bpg/cost/cfm_framework.adoc b/latest/bpg/cost/cfm_framework.adoc index 947ec8065..d508752b5 100644 --- a/latest/bpg/cost/cfm_framework.adoc +++ b/latest/bpg/cost/cfm_framework.adoc @@ -17,7 +17,7 @@ AWS Cloud Economics is a discipline that helps customers increase efficiency and reduce their costs through the adoption of modern compute technologies like Amazon EKS. The discipline recommends following a methodology called the "`Cloud Financial Management (CFM) framework`" which consists of 4 pillars: -image::../images/cfm_framework.png[CFM Framework] +//image::../images/cfm_framework.png[CFM Framework] == The See pillar: Measurement and accountability @@ -32,7 +32,7 @@ Here is a brief overview of our best practices for the See pillar: * Allocate cloud costs to applications, Lines of Business (LoBs), and revenue streams. * Define, measure, and circulate efficiency/value KPIs with business stakeholders. For example, create a "`unit metric`" KPI that measures the cost per transaction, e.g. a ride sharing services might have a KPI for "`cost per ride`". -For more details on the recommended technologies and activities associated with this pillar, please see the xref:cost-opt-observability[Cost Optimization - Observability] section of this guide. +// For more details on the recommended technologies and activities associated with this pillar, please see the xref:cost-opt-observability[Cost Optimization - Observability] section of this guide. == The Save pillar: Cost optimization @@ -47,9 +47,9 @@ Since these activities are operational, they are highly dependent on your enviro Below is a prioritized list of the most common cost drivers for EKS clusters: -. *Compute costs:* Combining multiple types of instance families, purchasing options, and balancing scalability with availability require careful consideration. For further information, see the recommendations in the xref:cost-opt-compute[Cost Optimization - Compute] section of this guide. -. *Networking costs:* using 3 AZs for EKS clusters can potentially increase inter-AZ traffic costs. For our recommendations on how to balance HA requirements with keeping network traffic costs down, please consult the xref:cost-opt-networking[Cost Optimization - Networking] section of this guide. -. *Storage costs:* Depending on the stateful/stateless nature of the workloads in the EKS clusters, and how the different storage types are used, storage can be considered as part of the workload. For considerations relating to EKS storage costs, please consult the xref:cost-opt-storage[Cost Optimization - Storage] section of this guide. +// . *Compute costs:* Combining multiple types of instance families, purchasing options, and balancing scalability with availability require careful consideration. For further information, see the recommendations in the xref:cost-opt-compute[Cost Optimization - Compute] section of this guide. +// . *Networking costs:* using 3 AZs for EKS clusters can potentially increase inter-AZ traffic costs. For our recommendations on how to balance HA requirements with keeping network traffic costs down, please consult the xref:cost-opt-networking[Cost Optimization - Networking] section of this guide. +// . *Storage costs:* Depending on the stateful/stateless nature of the workloads in the EKS clusters, and how the different storage types are used, storage can be considered as part of the workload. For considerations relating to EKS storage costs, please consult the xref:cost-opt-storage[Cost Optimization - Storage] section of this guide. == The Plan pillar: Planning and forecasting @@ -63,7 +63,7 @@ Once the recommendations in the See pillar are implemented, clusters are optimiz Cost optimization is a continuous process and involves a flywheel of incremental improvements: -image::../images/flywheel.png[Cost optimization flywheel] +//image::../images/flywheel.png[Cost optimization flywheel] Securing executive sponsorship for these types of activities is crucial for integrating EKS cluster optimization into the organization's "`FinOps`" efforts. It allows stakeholder alignment through a shared understanding of EKS cluster costs, implementation of EKS cluster cost guardrails, and ensuring that the tooling, automation, and activities evolve with the organization's needs. diff --git a/latest/bpg/cost/cost_opt_networking.adoc b/latest/bpg/cost/cost_opt_networking.adoc index e773c177c..09b525a1a 100644 --- a/latest/bpg/cost/cost_opt_networking.adoc +++ b/latest/bpg/cost/cost_opt_networking.adoc @@ -28,7 +28,7 @@ _If you want granular visibility into the amount of cross-zone traffic between P *Using Topology Aware Routing (formerly known as Topology Aware Hints)* -image::../images/topo_aware_routing.png[Topology aware routing] +//image::../images/topo_aware_routing.png[Topology aware routing] When using topology aware routing, it's important to understand how Services, EndpointSlices and the `kube-proxy` work together when routing traffic. As the diagram above depicts, Services are the stable network abstraction layer that receive traffic destined for your Pods. When a Service is created, multiple EndpointSlices are created. Each EndpointSlice has a list of endpoints containing a subset of Pod addresses along with the nodes they're running on and any additional topology information. `kube-proxy` is a daemonset that runs on every node in your cluster and also fulfills a role of internal routing, but it does so based on what it consumes from the created EndpointSlices. @@ -36,7 +36,7 @@ When https://kubernetes.io/docs/concepts/services-networking/topology-aware-rout The diagram below shows how EndpointSlices with hints are organized in such a way that `kube-proxy` can know what destination they should go to based on their zonal point of origin. Without hints, there is no such allocation or organization and traffic will be proxied to different zonal destinations regardless of where it's coming from. -image::../images/endpoint_slice.png[Endpoint Slice] +//image::../images/endpoint_slice.png[Endpoint Slice] In some cases, the EndpointSlice controller may apply a _hint_ for a different zone, meaning the endpoint could end up serving traffic originating from a different zone. The reason for this is to try and maintain an even distribution of traffic between endpoints in different zones. @@ -63,7 +63,7 @@ targetPort: 3003 The screenshot below shows the result of the EndpointSlice controller having successfully applied a hint to an endpoint for a Pod replica running in the AZ `eu-west-1a`. -image::../images/slice_shell.png[Slice shell] +//image::../images/slice_shell.png[Slice shell] !!! note It's important to note that topology aware routing is still in *beta*. Also, this feature is more predictable when workloads are widely and evenly distributed across the cluster topology. Therefore, it is highly recommended to use it in conjunction with scheduling constraints that increase the availability of an application such as https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/[pod topology spread constraints]. @@ -144,7 +144,7 @@ In order to restrict Pod network traffic to a node, you can make use of the _htt !!! note It's important to note that this feature cannot be combined with topology aware routing in Kubernetes. -image::../images/local_traffic.png[Local internal traffic] +//image::../images/local_traffic.png[Local internal traffic] Below is a code snippet on how to set the _internal traffic policy_ for a Service. @@ -174,11 +174,11 @@ To avoid unexpected behaviour from your application due to traffic drops, you sh In this example, you have 2 replicas of Microservice A and 3 replicas of Microservice B. If Microservice A has its replicas spread between Nodes 1 and 2, and Microservice B has all 3 of its replicas on Node 3, then they won't be able to communicate because of the `Local` internal traffic policy. When there are no available node-local endpoints the traffic is dropped. -image::../images/no_node_local_1.png[node-local_no_peer] +//image::../images/no_node_local_1.png[node-local_no_peer] If Microservice B does have 2 of its 3 replicas on Nodes 1 and 2, then there will be communication between the peer applications. But you would still have an isolated replica of Microservice B without any peer replica to communicate with. -image::../images/no_node_local_2.png[node-local_with_peer] +//image::../images/no_node_local_2.png[node-local_with_peer] !!! note In some scenarios, an isolated replica like the one depicted in the above diagram may not be a cause for concern if it still serves a purpose (such as serving requests from external incoming traffic). @@ -250,7 +250,7 @@ When using _instance mode_, a NodePort will be opened on each node in your EKS c The diagram below depicts a network path for traffic flowing from the load balancer to the NodePort, and subsequently from the `kube-proxy` to the destination Pod on a separate node in a different AZ. This is an example of the _instance mode_ setting. -image::../images/lb_2_pod.png[LB to Pod] +//image::../images/lb_2_pod.png[LB to Pod] When using _ip mode_, network traffic is proxied from the load balancer directly to the destination Pod. As a result, there are _no data transfer charges_ involved in this approach. @@ -259,7 +259,7 @@ When using _ip mode_, network traffic is proxied from the load balancer directly The diagram below depicts network paths for traffic flowing from the load balancer to Pods in the network _ip mode_. -image::../images/ip_mode.png[IP mode] +//image::../images/ip_mode.png[IP mode] == Data Transfer from Container Registry @@ -281,13 +281,13 @@ It's a common practice to integrate Kubernetes workloads with other AWS services NAT Gateways are network components that perform network address translation (NAT). The diagram below depicts Pods in an EKS cluster communicating with other AWS services (Amazon ECR, DynamoDB, and S3), and third-party platforms. In this example, the Pods are running in private subnets in separate AZs. To send and receive traffic from the Internet, a NAT Gateway is deployed to the public subnet of one AZ, allowing any resources with private IP addresses to share a single public IP address to access the Internet. This NAT Gateway in turn communicates with the Internet Gateway component, allowing for packets to be sent to their final destination. -image::../images/nat_gw.png[NAT Gateway] +//image::../images/nat_gw.png[NAT Gateway] When using NAT Gateways for such use cases, _you can minimize the data transfer costs by deploying a NAT Gateway in each AZ_. This way, traffic routed to the Internet will go through the NAT Gateway in the same AZ, avoiding inter-AZ data transfer. However, even though you'll save on the cost of inter-AZ data transfer, the implication of this setup is that you'll incur the cost of an additional NAT Gateway in your architecture. This recommended approach is depicted in the diagram below. -image::../images/recommended_approach.png[Recommended approach] +//image::../images/recommended_approach.png[Recommended approach] === Using VPC Endpoints @@ -303,13 +303,13 @@ VPC Endpoints have an https://aws.amazon.com/privatelink/pricing/[hourly charge] The diagram below shows Pods communicating with AWS services via VPC Endpoints. -image::../images/vpc_endpoints.png[VPC Endpoints] +//image::../images/vpc_endpoints.png[VPC Endpoints] == Data Transfer between VPCs In some cases, you may have workloads in distinct VPCs (within the same AWS region) that need to communicate with each other. This can be accomplished by allowing traffic to traverse the public internet through Internet Gateways attached to the respective VPCs. Such communication can be enabled by deploying infrastructure components like EC2 instances, NAT Gateways or NAT instances in public subnets. However, a setup including these components will incur charges for processing/transferring data in and out of the VPCs. If the traffic to and from the separate VPCs is moving across AZs, then there will be an additional charge in the transfer of data. The diagram below depicts a setup that uses NAT Gateways and Internet Gateways to establish communication between workloads in different VPCs. -image::../images/between_vpcs.png[Between VPCs] +//image::../images/between_vpcs.png[Between VPCs] === VPC Peering Connections @@ -317,7 +317,7 @@ To reduce costs for such use cases, you can make use of https://docs.aws.amazon. The diagram below is a high-level representation of workloads communication via a VPC peering connection. -image::../images/peering.png[Peering] +//image::../images/peering.png[Peering] === Transitive Networking Connections @@ -325,7 +325,7 @@ As pointed out in the previous section, VPC Peering connections do not allow for The diagram below shows inter-AZ traffic flowing through a TGW between workloads in different VPCs but within the same AWS region. -image::../images/transititive.png[Transitive] +//image::../images/transititive.png[Transitive] == Using a Service Mesh diff --git a/latest/bpg/cost/cost_opt_observability.adoc b/latest/bpg/cost/cost_opt_observability.adoc index 5f4e10ee3..03946e6a4 100644 --- a/latest/bpg/cost/cost_opt_observability.adoc +++ b/latest/bpg/cost/cost_opt_observability.adoc @@ -218,7 +218,7 @@ Cardinality refers to the uniqueness of the data values in combination with its In the high cardinality example below, we see that the Metric, Latency, has Dimensions, RequestID, CustomerID, and Service and each Dimension has many unique values. Cardinality is the measure of the combination of the number of possible values per Dimension. In Prometheus, each set of unique dimensions/labels are consider as a new metric, therefore high cardinality means more metrics. -image::../images/high-cardinality.png[high cardinality] +//image::../images/high-cardinality.png[high cardinality] In EKS environments with many metrics and dimensions/labels per metric (Cluster, Namespace, Service, Pod, Container, etc), the cardinality tends to grow. In order to optimize cost, consider the cardinality of the metrics you are collecting carefully. For example, if you are aggregating a specific metric for visualization at the cluster level, then you can drop additional labels that are at a lower layer such as the namespace label. @@ -307,7 +307,7 @@ For example, you have java application that you want to debug the traces of all *Via the Console* -image::../images/console.png[console] +//image::../images/console.png[console] === Apply Tail Sampling with AWS Distro for OpenTelemetry (ADOT) From 2059e53de25de3c107f574ef47703e4df2f255e7 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 15:27:24 -0500 Subject: [PATCH 20/56] fixup --- latest/bpg/security/index.adoc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 06af18ed7..5b4dae796 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -142,15 +142,26 @@ https://catalog.workshops.aws/eks-security-immersionday/en-US[Amazon EKS Security Immersion Workshop] include::iam.adoc[leveloffset=+1] + //include::pods.adoc[leveloffset=+1] + //include::multitenancy.adoc[leveloffset=+1] + include::detective.adoc[leveloffset=+1] -include::network.adoc[leveloffset=+1] + +//include::network.adoc[leveloffset=+1] + include::data.adoc[leveloffset=+1] -include::runtime.adoc[leveloffset=+1] + +//include::runtime.adoc[leveloffset=+1] + //include::hosts.adoc[leveloffset=+1] + include::compliance.adoc[leveloffset=+1] -include::incidents.adoc[leveloffset=+1] + +//include::incidents.adoc[leveloffset=+1] + include::image.adoc[leveloffset=+1] -include::multiaccount.adoc[leveloffset=+1] + +//include::multiaccount.adoc[leveloffset=+1] From ad2fb6ca3f66a452c6f0a6326f0f65d76efba61b Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 20:37:26 +0000 Subject: [PATCH 21/56] working on pods.adoc --- latest/bpg/security/index.adoc | 2 +- latest/bpg/security/test.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 5b4dae796..359331020 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -143,7 +143,7 @@ Security Immersion Workshop] include::iam.adoc[leveloffset=+1] -//include::pods.adoc[leveloffset=+1] +include::pods.adoc[leveloffset=+1] //include::multitenancy.adoc[leveloffset=+1] diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index b4fa87f8c..120abf752 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -19,10 +19,10 @@ def run_build(header: str, content: str, test_description: str) -> bool: print("Building... (this may take about 30 seconds)") start_time = time.time() - if not os.path.exists('multitenancy.adoc.backup'): - shutil.copy2('multitenancy.adoc', 'multitenancy.adoc.backup') + if not os.path.exists('pods.adoc.backup'): + shutil.copy2('pods.adoc', 'pods.adoc.backup') - with open('multitenancy.adoc', 'w') as f: + with open('pods.adoc', 'w') as f: f.write(header + content) try: @@ -32,7 +32,7 @@ def run_build(header: str, content: str, test_description: str) -> bool: print(f"Build {'succeeded' if success else 'failed'} in {end_time - start_time:.2f} seconds") return success finally: - shutil.copy2('multitenancy.adoc.backup', 'multitenancy.adoc') + shutil.copy2('pods.adoc.backup', 'pods.adoc') def parse_sections(content: str) -> List[Section]: print("\nParsing AsciiDoc sections...") @@ -105,7 +105,7 @@ def suggest_fixes(section: Section) -> List[str]: def main(): print("Starting AsciiDoc debugging process...") - with open('multitenancy.adoc', 'r') as f: + with open('pods.adoc', 'r') as f: lines = f.readlines() header = ''.join(lines[:10]) content = ''.join(lines[10:]) @@ -131,7 +131,7 @@ def main(): print("\nNo specific problematic sections identified. The issue may be more complex or involve interactions between multiple sections.") print("\nDebugging process completed.") - print("Note: The original 'multitenancy.adoc' file has been restored.") + print("Note: The original 'pods.adoc' file has been restored.") if __name__ == "__main__": main() \ No newline at end of file From a45818b26a6d64e03edacb051a5c025b69328cf9 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 20:48:52 +0000 Subject: [PATCH 22/56] pods.adoc builing --- latest/bpg/security/pods.adoc | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/latest/bpg/security/pods.adoc b/latest/bpg/security/pods.adoc index d1c5ed25b..bff5134ae 100644 --- a/latest/bpg/security/pods.adoc +++ b/latest/bpg/security/pods.adoc @@ -717,20 +717,21 @@ from succeeding if incorrect settings are detected. Pod Security Standards can also be used to prevent pods from using privilege escalation. +// PROBLEM === Disable ServiceAccount token mounts For pods that do not need to access the Kubernetes API, you can disable the automatic mounting of a ServiceAccount token on a pod spec, or for all pods that use a particular ServiceAccount. -!!! Attention +// !!! Attention -Disabling ServiceAccount mounting does not prevent a pod from having -network access to the Kubernetes API. To prevent a pod from having any -network access to the Kubernetes API, you will need to modify the -https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS -cluster endpoint access] and use a -xref:iam-network-policy[NetworkPolicy] to block pod access. +// Disabling ServiceAccount mounting does not prevent a pod from having +// network access to the Kubernetes API. To prevent a pod from having any +// network access to the Kubernetes API, you will need to modify the +// https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[EKS +// cluster endpoint access] and use a +// xref:iam-network-policy[NetworkPolicy] to block pod access. [source,yaml] ---- @@ -765,15 +766,15 @@ underlying node's DNS resolution. See the https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy[Kubernetes docs on Pod DNS policy] for more information. -!!! Attention +// !!! Attention -Disabling service links and changing the pod's DNS policy does not -prevent a pod from having network access to the in-cluster DNS service. -An attacker can still enumerate services in a cluster by reaching the -in-cluster DNS service. (ex: -`dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP`) To prevent -in-cluster service discovery, use a -xref:iam-network-policy[NetworkPolicy] to block pod access +// Disabling service links and changing the pod's DNS policy does not +// prevent a pod from having network access to the in-cluster DNS service. +// An attacker can still enumerate services in a cluster by reaching the +// in-cluster DNS service. (ex: +// `dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP`) To prevent +// in-cluster service discovery, use a +// xref:iam-network-policy[NetworkPolicy] to block pod access [source,yaml] ---- From b0b032164d0fc3731b4e74e2ba21e235d385d916 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 21:39:23 +0000 Subject: [PATCH 23/56] revise --- latest/bpg/security/hosts.adoc | 264 +++++++++++++++---------------- latest/bpg/security/index.adoc | 10 +- latest/bpg/security/runtime.adoc | 18 +-- latest/bpg/security/test.py | 99 +++++++++--- 4 files changed, 226 insertions(+), 165 deletions(-) diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index 8d649880a..e47ef28b1 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -210,138 +210,138 @@ Fargate pods. == Alternatives -[[iam-se-linux,iam-se-linux.title]] -=== Run SELinux - -!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, -Bottlerocket, and Amazon Linux 2023 - -SELinux provides an additional layer of security to keep containers -isolated from each other and from the host. SELinux allows -administrators to enforce mandatory access controls (MAC) for every -user, application, process, and file. Think of it as a backstop that -restricts the operations that can be performed against to specific -resources based on a set of labels. On EKS, SELinux can be used to -prevent containers from accessing each other’s resources. - -Container SELinux policies are defined in the -https://github.com/containers/container-selinux[container-selinux] -package. Docker CE requires this package (along with its dependencies) -so that the processes and files created by Docker (or other container -runtimes) run with limited system access. Containers leverage the -`+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These -policies effectively prevent containers from accessing certain features -of the host. - -When you configure SELinux for Docker, Docker automatically labels -workloads `+container_t+` as a type and gives each container a unique -MCS level. This will isolate containers from one another. If you need -looser restrictions, you can create your own profile in SElinux which -grants a container permissions to specific areas of the file system. -This is similar to PSPs in that you can create different profiles for -different containers/pods. For example, you can have a profile for -general workloads with a set of restrictive controls and another for -things that require privileged access. - -SELinux for Containers has a set of options that can be configured to -modify the default restrictions. The following SELinux Booleans can be -enabled or disabled based on your needs: - -[width="100%",cols="30%,^40%,30%",options="header",] -|=== -|Boolean |Default |Description -|`+container_connect_any+` |`+off+` |Allow containers to access -privileged ports on the host. For example, if you have a container that -needs to map ports to 443 or 80 on the host. - -|`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup -configuration. For example, a container running systemd will need this -to be enabled. - -|`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file -system. -|=== - -By default, containers are allowed to read/execute under `+/usr+` and -read most content from `+/etc+`. The files under `+/var/lib/docker+` and -`+/var/lib/containers+` have the label `+container_var_lib_t+`. To view -a full list of default, labels see the -https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] -file. - -[source,bash] ----- -docker container run -it \ - -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ - centos:7 cat /host/repositories.json -# cat: /host/repositories.json: Permission denied - -docker container run -it \ - -v /etc/passwd:/host/etc/passwd \ - centos:7 cat /host/etc/passwd -# cat: /host/etc/passwd: Permission denied ----- - -Files labeled with `+container_file_t+` are the only files that are -writable by containers. If you want a volume mount to be writeable, you -will needed to specify `+:z+` or `+:Z+` at the end. - -* `+:z+` will re-label the files so that the container can read/write -* `+:Z+` will re-label the files so that *only* the container can -read/write - -[source,bash] ----- -ls -Z /var/lib/misc -# -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp - -docker container run -it \ - -v /var/lib/misc:/host/var/lib/misc:z \ - centos:7 echo "Relabeled!" - -ls -Z /var/lib/misc -#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp ----- - -[source,bash] ----- -docker container run -it \ - -v /var/log:/host/var/log:Z \ - fluentbit:latest ----- - -In Kubernetes, relabeling is slightly different. Rather than having -Docker automatically relabel the files, you can specify a custom MCS -label to run the pod. Volumes that support relabeling will automatically -be relabeled so that they are accessible. Pods with a matching MCS label -will be able to access the volume. If you need strict isolation, set a -different MCS label for each pod. - -[source,yaml] ----- -securityContext: - seLinuxOptions: - # Provide a unique MCS label per container - # You can specify user, role, and type also - # enforcement based on type and level (svert) - level: s0:c144:c154 ----- - -In this example `+s0:c144:c154+` corresponds to an MCS label assigned to -a file that the container is allowed to access. - -On EKS you could create policies that allow for privileged containers to -run, like FluentD and create an SELinux policy to allow it to read from -/var/log on the host without needing to relabel the host directory. Pods -with the same label will be able to access the same host volumes. - -We have implemented -https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for -Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These -AMIs were developed to demonstrate sample implementations that meet -requirements of highly regulated customers, such as STIG, CJIS, and C2S. - -!!! caution SELinux will ignore containers where the type is unconfined. +// [[iam-se-linux,iam-se-linux.title]] +// === Run SELinux + +// !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, +// Bottlerocket, and Amazon Linux 2023 + +// SELinux provides an additional layer of security to keep containers +// isolated from each other and from the host. SELinux allows +// administrators to enforce mandatory access controls (MAC) for every +// user, application, process, and file. Think of it as a backstop that +// restricts the operations that can be performed against to specific +// resources based on a set of labels. On EKS, SELinux can be used to +// prevent containers from accessing each other’s resources. + +// Container SELinux policies are defined in the +// https://github.com/containers/container-selinux[container-selinux] +// package. Docker CE requires this package (along with its dependencies) +// so that the processes and files created by Docker (or other container +// runtimes) run with limited system access. Containers leverage the +// `+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +// policies effectively prevent containers from accessing certain features +// of the host. + +// When you configure SELinux for Docker, Docker automatically labels +// workloads `+container_t+` as a type and gives each container a unique +// MCS level. This will isolate containers from one another. If you need +// looser restrictions, you can create your own profile in SElinux which +// grants a container permissions to specific areas of the file system. +// This is similar to PSPs in that you can create different profiles for +// different containers/pods. For example, you can have a profile for +// general workloads with a set of restrictive controls and another for +// things that require privileged access. + +// SELinux for Containers has a set of options that can be configured to +// modify the default restrictions. The following SELinux Booleans can be +// enabled or disabled based on your needs: + +// [width="100%",cols="30%,^40%,30%",options="header",] +// |=== +// |Boolean |Default |Description +// |`+container_connect_any+` |`+off+` |Allow containers to access +// privileged ports on the host. For example, if you have a container that +// needs to map ports to 443 or 80 on the host. + +// |`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +// configuration. For example, a container running systemd will need this +// to be enabled. + +// |`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file +// system. +// |=== + +// By default, containers are allowed to read/execute under `+/usr+` and +// read most content from `+/etc+`. The files under `+/var/lib/docker+` and +// `+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +// a full list of default, labels see the +// https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] +// file. + +// [source,bash] +// ---- +// docker container run -it \ +// -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ +// centos:7 cat /host/repositories.json +// # cat: /host/repositories.json: Permission denied + +// docker container run -it \ +// -v /etc/passwd:/host/etc/passwd \ +// centos:7 cat /host/etc/passwd +// # cat: /host/etc/passwd: Permission denied +// ---- + +// Files labeled with `+container_file_t+` are the only files that are +// writable by containers. If you want a volume mount to be writeable, you +// will needed to specify `+:z+` or `+:Z+` at the end. + +// * `+:z+` will re-label the files so that the container can read/write +// * `+:Z+` will re-label the files so that *only* the container can +// read/write + +// [source,bash] +// ---- +// ls -Z /var/lib/misc +// # -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp + +// docker container run -it \ +// -v /var/lib/misc:/host/var/lib/misc:z \ +// centos:7 echo "Relabeled!" + +// ls -Z /var/lib/misc +// #-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp +// ---- + +// [source,bash] +// ---- +// docker container run -it \ +// -v /var/log:/host/var/log:Z \ +// fluentbit:latest +// ---- + +// In Kubernetes, relabeling is slightly different. Rather than having +// Docker automatically relabel the files, you can specify a custom MCS +// label to run the pod. Volumes that support relabeling will automatically +// be relabeled so that they are accessible. Pods with a matching MCS label +// will be able to access the volume. If you need strict isolation, set a +// different MCS label for each pod. + +// [source,yaml] +// ---- +// securityContext: +// seLinuxOptions: +// # Provide a unique MCS label per container +// # You can specify user, role, and type also +// # enforcement based on type and level (svert) +// level: s0:c144:c154 +// ---- + +// In this example `+s0:c144:c154+` corresponds to an MCS label assigned to +// a file that the container is allowed to access. + +// On EKS you could create policies that allow for privileged containers to +// run, like FluentD and create an SELinux policy to allow it to read from +// /var/log on the host without needing to relabel the host directory. Pods +// with the same label will be able to access the same host volumes. + +// We have implemented +// https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for +// Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These +// AMIs were developed to demonstrate sample implementations that meet +// requirements of highly regulated customers, such as STIG, CJIS, and C2S. + +// !!! caution SELinux will ignore containers where the type is unconfined. == Tools and resources diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 359331020..44e2a68dd 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -145,17 +145,17 @@ include::iam.adoc[leveloffset=+1] include::pods.adoc[leveloffset=+1] -//include::multitenancy.adoc[leveloffset=+1] +include::multitenancy.adoc[leveloffset=+1] include::detective.adoc[leveloffset=+1] -//include::network.adoc[leveloffset=+1] +include::network.adoc[leveloffset=+1] include::data.adoc[leveloffset=+1] -//include::runtime.adoc[leveloffset=+1] +include::runtime.adoc[leveloffset=+1] -//include::hosts.adoc[leveloffset=+1] +include::hosts.adoc[leveloffset=+1] include::compliance.adoc[leveloffset=+1] @@ -163,5 +163,5 @@ include::compliance.adoc[leveloffset=+1] include::image.adoc[leveloffset=+1] -//include::multiaccount.adoc[leveloffset=+1] +include::multiaccount.adoc[leveloffset=+1] diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc index 7d2f6eb15..a1c7c4163 100644 --- a/latest/bpg/security/runtime.adoc +++ b/latest/bpg/security/runtime.adoc @@ -91,15 +91,15 @@ for use by Pods and containers. === AppArmor and SELinux -AppArmor and SELinux are known as -https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access -control or MAC systems]. They are similar in concept to seccomp but with -different APIs and abilities, allowing access control for e.g. specific -filesystem paths or network ports. Support for these tools depends on -the Linux distribution, with Debian/Ubuntu supporting AppArmor and -RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see -the xref:iam-se-linux[infrastructure security section] for -further discussion of SELinux. +// AppArmor and SELinux are known as +// https://en.wikipedia.org/wiki/Mandatory_access_control[mandatory access +// control or MAC systems]. They are similar in concept to seccomp but with +// different APIs and abilities, allowing access control for e.g. specific +// filesystem paths or network ports. Support for these tools depends on +// the Linux distribution, with Debian/Ubuntu supporting AppArmor and +// RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see +// the xref:iam-se-linux[infrastructure security section] for +// further discussion of SELinux. Both AppArmor and SELinux are integrated with Kubernetes, but as of Kubernetes 1.28 AppArmor profiles must be specified via diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index 120abf752..93c1964f1 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -3,9 +3,14 @@ import os import time import shutil +import signal +import sys from dataclasses import dataclass from typing import List, Tuple +# File to test +TEST_FILE = 'multiaccount.adoc' + @dataclass class Section: level: int @@ -14,15 +19,37 @@ class Section: start_line: int end_line: int -def run_build(header: str, content: str, test_description: str) -> bool: +# Global flag to indicate if the script should exit +should_exit = False + +def signal_handler(sig, frame): + global should_exit + print("\nInterrupt received. Cleaning up and exiting...") + should_exit = True + +signal.signal(signal.SIGINT, signal_handler) + +def safe_file_operations(func): + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except Exception as e: + print(f"An error occurred: {e}") + restore_original_file() + sys.exit(1) + return wrapper + +@safe_file_operations +def run_build(content: str, test_description: str, header: str) -> bool: + if should_exit: + restore_original_file() + sys.exit(0) + print(f"\nTesting: {test_description}") print("Building... (this may take about 30 seconds)") start_time = time.time() - if not os.path.exists('pods.adoc.backup'): - shutil.copy2('pods.adoc', 'pods.adoc.backup') - - with open('pods.adoc', 'w') as f: + with open(TEST_FILE, 'w') as f: f.write(header + content) try: @@ -31,9 +58,11 @@ def run_build(header: str, content: str, test_description: str) -> bool: success = result.returncode == 0 print(f"Build {'succeeded' if success else 'failed'} in {end_time - start_time:.2f} seconds") return success - finally: - shutil.copy2('pods.adoc.backup', 'pods.adoc') + except subprocess.CalledProcessError as e: + print(f"Build process error: {e}") + return False +@safe_file_operations def parse_sections(content: str) -> List[Section]: print("\nParsing AsciiDoc sections...") lines = content.split('\n') @@ -56,15 +85,20 @@ def parse_sections(content: str) -> List[Section]: print(f"Found {len(sections)} sections") return sections -def bisect_problematic_sections(header: str, sections: List[Section]) -> List[Section]: +@safe_file_operations +def bisect_problematic_sections(sections: List[Section], header: str) -> List[Section]: print("\nStarting bisection search for problematic sections...") all_content = '\n'.join(section.content for section in sections) - if run_build(header, all_content, "Full document"): + if run_build(all_content, "Full document", header): print("Full document builds successfully. No problematic sections identified.") return [] def bisect_recursive(start: int, end: int) -> List[Section]: + if should_exit: + restore_original_file() + sys.exit(0) + if start == end: return [sections[start]] @@ -74,10 +108,10 @@ def bisect_recursive(start: int, end: int) -> List[Section]: problematic_sections = [] - if not run_build(header, first_half, f"First half (sections {start+1}-{mid+1})"): + if not run_build(first_half, f"First half (sections {start+1}-{mid+1})", header): problematic_sections.extend(bisect_recursive(start, mid)) - if not run_build(header, second_half, f"Second half (sections {mid+2}-{end+1})"): + if not run_build(second_half, f"Second half (sections {mid+2}-{end+1})", header): problematic_sections.extend(bisect_recursive(mid+1, end)) return problematic_sections @@ -103,15 +137,42 @@ def suggest_fixes(section: Section) -> List[str]: print(f"Found {len(suggestions)} potential issues") return suggestions +def restore_original_file(): + if os.path.exists(f'{TEST_FILE}.backup'): + shutil.copy2(f'{TEST_FILE}.backup', TEST_FILE) + print(f"Original '{TEST_FILE}' file has been restored.") + +def print_sections_preview(sections: List[Section]): + print("\nSections preview:") + for i, section in enumerate(sections): + first_line = section.content.split('\n')[0].strip() + print(f"Section {i+1}: {section.title}") + print(f" First line: {first_line[:60]}{'...' if len(first_line) > 60 else ''}") + print(f" Lines: {section.start_line + 11}-{section.end_line + 11}") + print() + +@safe_file_operations def main(): - print("Starting AsciiDoc debugging process...") - with open('pods.adoc', 'r') as f: - lines = f.readlines() - header = ''.join(lines[:10]) - content = ''.join(lines[10:]) + print(f"Starting AsciiDoc debugging process for file: {TEST_FILE}") + + # Backup the original file + if not os.path.exists(f'{TEST_FILE}.backup'): + shutil.copy2(TEST_FILE, f'{TEST_FILE}.backup') + + with open(TEST_FILE, 'r') as f: + content = f.read() + + # Separate the header (first 10 lines) from the rest of the content + lines = content.split('\n') + header = '\n'.join(lines[:10]) + '\n' + main_content = '\n'.join(lines[10:]) + + sections = parse_sections(main_content) + print_sections_preview(sections) + + input("Press Enter to start the bisection search...") - sections = parse_sections(content) - problematic_sections = bisect_problematic_sections(header, sections) + problematic_sections = bisect_problematic_sections(sections, header) if problematic_sections: print("\nResults:") @@ -130,8 +191,8 @@ def main(): else: print("\nNo specific problematic sections identified. The issue may be more complex or involve interactions between multiple sections.") + restore_original_file() print("\nDebugging process completed.") - print("Note: The original 'pods.adoc' file has been restored.") if __name__ == "__main__": main() \ No newline at end of file From 59c88640a7c103db2bd3931debdb9594a9ed245d Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 21:40:09 +0000 Subject: [PATCH 24/56] remove backup files --- latest/bpg/security/iam.adoc.backup | 1445 --------------------------- 1 file changed, 1445 deletions(-) delete mode 100644 latest/bpg/security/iam.adoc.backup diff --git a/latest/bpg/security/iam.adoc.backup b/latest/bpg/security/iam.adoc.backup deleted file mode 100644 index 8a7d9e538..000000000 --- a/latest/bpg/security/iam.adoc.backup +++ /dev/null @@ -1,1445 +0,0 @@ -//!!NODE_ROOT
-[."topic"] -[[identity-and-access-management,identity-and-access-management.title]] -= Identity and Access Management -:info_doctype: section -:info_title: Identity and Access Management -:info_abstract: Identity and Access Management -:info_titleabbrev: Identity and Access Management -:imagesdir: images/ - -https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html[Identity -and Access Management] (IAM) is an AWS service that performs two -essential functions: Authentication and Authorization. Authentication -involves the verification of a identity whereas authorization governs -the actions that can be performed by AWS resources. Within AWS, a -resource can be another AWS service, e.g. EC2, or an AWS -https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html#intro-structure-principal[principal] -such as an -https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-users[IAM -User] or -https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html#id_iam-roles[Role]. -The rules governing the actions that a resource is allowed to perform -are expressed as -https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html[IAM -policies]. - -== Controlling Access to EKS Clusters - -The Kubernetes project supports a variety of different strategies to -authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, -X.509 certificates, OIDC, etc. EKS currently has native support for -https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication[webhook -token authentication], -https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens[service -account tokens], and as of February 21, 2021, OIDC authentication. - -The webhook authentication strategy calls a webhook that verifies bearer -tokens. On EKS, these bearer tokens are generated by the AWS CLI or the -https://github.com/kubernetes-sigs/aws-iam-authenticator[aws-iam-authenticator] -client when you run `+kubectl+` commands. As you execute commands, the -token is passed to the kube-apiserver which forwards it to the -authentication webhook. If the request is well-formed, the webhook calls -a pre-signed URL embedded in the token's body. This URL validates the -request's signature and returns information about the user, e.g. the -user's account, Arn, and UserId to the kube-apiserver. - -To manually generate a authentication token, type the following command -in a terminal window: - -[source,bash] ----- -aws eks get-token --cluster-name ----- - -You can also get a token programmatically. Below is an example written -in Go: - -[source,golang] ----- -package main - -import ( - "fmt" - "log" - "sigs.k8s.io/aws-iam-authenticator/pkg/token" -) - -func main() { - g, _ := token.NewGenerator(false, false) - tk, err := g.Get("") - if err != nil { - log.Fatal(err) - } - fmt.Println(tk) -} ----- - -The output should resemble this: - -[source,json] ----- -{ - "kind": "ExecCredential", - "apiVersion": "client.authentication.k8s.io/v1alpha1", - "spec": {}, - "status": { - "expirationTimestamp": "2020-02-19T16:08:27Z", - "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" - } -} ----- - -Each token starts with `+k8s-aws-v1.+` followed by a base64 encoded -string. The string, when decoded, should resemble to something similar -to this: - -[source,bash] ----- -https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393 ----- - -The token consists of a pre-signed URL that includes an Amazon -credential and signature. For additional details see -https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html. - -The token has a time to live (TTL) of 15 minutes after which a new token -will need to be generated. This is handled automatically when you use a -client like `+kubectl+`, however, if you're using the Kubernetes -dashboard, you will need to generate a new token and re-authenticate -each time the token expires. - -Once the user's identity has been authenticated by the AWS IAM service, -the kube-apiserver reads the `+aws-auth+` ConfigMap in the -`+kube-system+` Namespace to determine the RBAC group to associate with -the user. The `+aws-auth+` ConfigMap is used to create a static mapping -between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC -groups. RBAC groups can be referenced in Kubernetes RoleBindings or -ClusterRoleBindings. They are similar to IAM Roles in that they define a -set of actions (verbs) that can be performed against a collection of -Kubernetes resources (objects). - -=== Cluster Access Manager - -Cluster Access Manager, now the preferred way to manage access of AWS -IAM principals to Amazon EKS clusters, is a functionality of the AWS API -and is an opt-in feature for EKS v1.23 and later clusters (new or -existing). It simplifies identity mapping between AWS IAM and Kubernetes -RBACs, eliminating the need to switch between AWS and Kubernetes APIs or -editing the `+aws-auth+` ConfigMap for access management, reducing -operational overhead, and helping address misconfigurations. The tool -also enables cluster administrators to revoke or refine -`+cluster-admin+` permissions automatically granted to the AWS IAM -principal used to create the cluster. - -This API relies on two concepts: - -* *Access Entries:* A cluster identity directly linked to an AWS IAM -principal (user or role) allowed to authenticate to an Amazon EKS -cluster. -* *Access Policies:* Are Amazon EKS specific policies that provides the -authorization for an Access Entry to perform actions in the Amazon EKS -cluster. - -____ -At launch Amazon EKS supports only predefined and AWS managed policies. -Access policies are not IAM entities and are defined and managed by -Amazon EKS. -____ - -Cluster Access Manager allows the combination of upstream RBAC with -Access Policies supporting allow and pass (but not deny) on Kubernetes -AuthZ decisions regarding API server requests. A deny decision will -happen when both, the upstream RBAC and Amazon EKS authorizers can't -determine the outcome of a request evaluation. - -With this feature, Amazon EKS supports three modes of authentication: - -[arabic] -. `+CONFIG_MAP+` to continue using `+aws-auth+` configMap exclusively. -. `+API_AND_CONFIG_MAP+` to source authenticated IAM principals from -both EKS Access Entry APIs and the `+aws-auth+` configMap, prioritizing -the Access Entries. Ideal to migrate existing `+aws-auth+` permissions -to Access Entries. -. `+API+` to exclusively rely on EKS Access Entry APIs. This is the new -*recommended approach*. - -To get started, cluster administrators can create or update Amazon EKS -clusters, setting the preferred authentication to `+API_AND_CONFIG_MAP+` -or `+API+` method and define Access Entries to grant access the desired -AWS IAM principals. - -[source,bash] ----- -$ aws eks create-cluster \ - --name \ - --role-arn \ - --resources-vpc-config subnetIds=,endpointPublicAccess=true,endpointPrivateAccess=true \ - --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ - --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false ----- - -The above command is an example to create an Amazon EKS cluster already -without the admin permissions of the cluster creator. - -It is possible to update Amazon EKS clusters configuration to enable -`+API+` authenticationMode using the `+update-cluster-config+` command, -to do that on existing clusters using `+CONFIG_MAP+` you will have to -first update to `+API_AND_CONFIG_MAP+` and then to `+API+`. *These -operations cannot be reverted*, meaning that's not possible to switch -from `+API+` to `+API_AND_CONFIG_MAP+` or `+CONFIG_MAP+`, and also from -`+API_AND_CONFIG_MAP+` to `+CONFIG_MAP+`. - -[source,bash] ----- -$ aws eks update-cluster-config \ - --name \ - --access-config authenticationMode=API ----- - -The API support commands to add and revoke access to the cluster, as -well as validate the existing Access Policies and Access Entries for the -specified cluster. The default policies are created to match Kubernetes -RBACs as follows. - -[cols=",",options="header",] -|=== -|EKS Access Policy |Kubernetes RBAC -|AmazonEKSClusterAdminPolicy |cluster-admin -|AmazonEKSAdminPolicy |admin -|AmazonEKSEditPolicy |edit -|AmazonEKSViewPolicy |view -|=== - -[source,bash] ----- -$ aws eks list-access-policies -{ - "accessPolicies": [ - { - "name": "AmazonEKSAdminPolicy", - "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" - }, - { - "name": "AmazonEKSClusterAdminPolicy", - "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" - }, - { - "name": "AmazonEKSEditPolicy", - "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" - }, - { - "name": "AmazonEKSViewPolicy", - "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" - } - ] -} - -$ aws eks list-access-entries --cluster-name - -{ - "accessEntries": [] -} ----- - -____ -No Access Entries are available when the cluster is created without the -cluster creator admin permission, which is the only entry created by -default. -____ - -=== The `+aws-auth+` ConfigMap _(deprecated)_ - -One way Kubernetes integration with AWS authentication can be done is -via the `+aws-auth+` ConfigMap, which resides in the `+kube-system+` -Namespace. It is responsible for mapping the AWS IAM Identities (Users, -Groups, and Roles) authentication, to Kubernetes role-based access -control (RBAC) authorization. The `+aws-auth+` ConfigMap is -automatically created in your Amazon EKS cluster during its provisioning -phase. It was initially created to allow nodes to join your cluster, but -as mentioned you can also use this ConfigMap to add RBACs access to IAM -principals. - -To check your cluster's `+aws-auth+` ConfigMap, you can use the -following command. - -[source,bash] ----- -kubectl -n kube-system get configmap aws-auth -o yaml ----- - -This is a sample of a default configuration of the `+aws-auth+` -ConfigMap. - -[source,yaml] ----- -apiVersion: v1 -data: - mapRoles: | - - groups: - - system:bootstrappers - - system:nodes - - system:node-proxier - rolearn: arn:aws:iam:::role/kube-system- - username: system:node:{{SessionName}} -kind: ConfigMap -metadata: - creationTimestamp: "2023-10-22T18:19:30Z" - name: aws-auth - namespace: kube-system ----- - -The main session of this ConfigMap, is under `+data+` in the -`+mapRoles+` block, which is basically composed by 3 parameters. - -* *groups:* The Kubernetes group/groups to map the IAM Role to. This can be -a default group, or a custom group specified in a `+clusterrolebinding+` -or `+rolebinding+`. In the above example we have just system groups -declared. -* *rolearn:* The ARN of the AWS IAM Role be mapped to the Kubernetes -group/groups add, using the following format -`+arn::iam:::role/role-name+`. -* *username:* The username within Kubernetes to map to the AWS IAM role. -This can be any custom name. - -____ -It is also possible to map permissions for AWS IAM Users, defining a new -configuration block for `+mapUsers+`, under `+data+` in the `+aws-auth+` -ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a -*Best Practice* it's always recommended to user `+mapRoles+` instead. -____ - -To manage permissions, you can edit the `+aws-auth+` ConfigMap adding or -removing access to your Amazon EKS cluster. Although it's possible to -edit the `+aws-auth+` ConfigMap manually, it's recommended using tools -like `+eksctl+`, since this is a very senstitive configuration, and an -inaccurate configuration can lock you outside your Amazon EKS Cluster. -Check the subsection -https://aws.github.io/aws-eks-best-practices/security/docs/iam/#use-tools-to-make-changes-to-the-aws-auth-configmap[Use -tools to make changes to the aws-auth ConfigMap] below for more details. - -== Cluster Access Recommendations - -=== Make the EKS Cluster Endpoint private - -By default when you provision an EKS cluster, the API cluster endpoint -is set to public, i.e. it can be accessed from the Internet. Despite -being accessible from the Internet, the endpoint is still considered -secure because it requires all API requests to be authenticated by IAM -and then authorized by Kubernetes RBAC. That said, if your corporate -security policy mandates that you restrict access to the API from the -Internet or prevents you from routing traffic outside the cluster VPC, -you can: - -* Configure the EKS cluster endpoint to be private. See -https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html[Modifying -Cluster Endpoint Access] for further information on this topic. -* Leave the cluster endpoint public and specify which CIDR blocks can -communicate with the cluster endpoint. The blocks are effectively a -whitelisted set of public IP addresses that are allowed to access the -cluster endpoint. -* Configure public access with a set of whitelisted CIDR blocks and set -private endpoint access to enabled. This will allow public access from a -specific range of public IPs while forcing all network traffic between -the kubelets (workers) and the Kubernetes API through the cross-account -ENIs that get provisioned into the cluster VPC when the control plane is -provisioned. - -=== Don't use a service account token for authentication - -A service account token is a long-lived, static credential. If it is -compromised, lost, or stolen, an attacker may be able to perform all the -actions associated with that token until the service account is deleted. -At times, you may need to grant an exception for applications that have -to consume the Kubernetes API from outside the cluster, e.g. a CI/CD -pipeline application. If such applications run on AWS infrastructure, -like EC2 instances, consider using an instance profile and mapping that -to a Kubernetes RBAC role. - -=== Employ least privileged access to AWS Resources - -An IAM User does not need to be assigned privileges to AWS resources to -access the Kubernetes API. If you need to grant an IAM user access to an -EKS cluster, create an entry in the `+aws-auth+` ConfigMap for that user -that maps to a specific Kubernetes RBAC group. - -[[iam-cluster-creator,iam-cluster-creator.title]] -=== Remove the cluster-admin permissions from the cluster creator principal - -By default Amazon EKS clusters are created with a permanent -`+cluster-admin+` permission bound to the cluster creator principal. -With the Cluster Access Manager API, it's possible to create clusters -without this permission setting the -`+--access-config bootstrapClusterCreatorAdminPermissions+` to -`+false+`, when using `+API_AND_CONFIG_MAP+` or `+API+` authentication -mode. Revoke this access considered a best practice to avoid any -unwanted changes to the cluster configuration. The process to revoke -this access, follows the same process to revoke any other access to the -cluster. - -The API gives you flexibility to only disassociate an IAM principal from -an Access Policy, in this case the `+AmazonEKSClusterAdminPolicy+`. - -[source,bash] ----- -$ aws eks list-associated-access-policies \ - --cluster-name \ - --principal-arn - -$ aws eks disassociate-access-policy --cluster-name \ - --principal-arn - -{ - "accessEntries": [] -} - -$ aws eks delete-access-entry --cluster-name \ - --principal-arn ----- - -____ -This access can be granted again if needed during an incident, emergency -or break glass scenario where the cluster is otherwise inaccessible. -____ - -If the cluster still configured with the `+CONFIG_MAP+` authentication -method, all additional users should be granted access to the cluster -through the `+aws-auth+` ConfigMap, and after `+aws-auth+` ConfigMap is -configured, the role assigned to the entity that created the cluster, -can be deleted and only recreated in case of an incident, emergency or -break glass scenario, or where the `+aws-auth+` ConfigMap is corrupted -and the cluster is otherwise inaccessible. This can be particularly -useful in production clusters. - -=== Use IAM Roles when multiple users need identical access to the cluster - -Rather than creating an entry for each individual IAM User, allow those -users to assume an IAM Role and map that role to a Kubernetes RBAC -group. This will be easier to maintain, especially as the number of -users that require access grows. - -!!! attention When accessing the EKS cluster with the IAM entity mapped -by `+aws-auth+` ConfigMap, the username described is recorded in the -user field of the Kubernetes audit log. If you're using an IAM role, the -actual users who assume that role aren't recorded and can't be audited. - -If still using the `+aws-auth+` configMap as the authentication method, -when assigning K8s RBAC permissions to an IAM role, you should include -\{\{SessionName}} in your username. That way, the audit log will record -the session name so you can track who the actual user assume this role -along with the CloudTrail log. - -[source,yaml] ----- -- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole - username: testRole:{{SessionName}} - groups: - - system:masters ----- - -____ -In Kubernetes 1.20 and above, this change is no longer required, since -`+user.extra.sessionName.0+` was added to the Kubernetes audit log. -____ - -=== Employ least privileged access when creating RoleBindings and ClusterRoleBindings - -Like the earlier point about granting access to AWS Resources, -RoleBindings and ClusterRoleBindings should only include the set of -permissions necessary to perform a specific function. Avoid using -`+["*"]+` in your Roles and ClusterRoles unless it's absolutely -necessary. If you're unsure what permissions to assign, consider using a -tool like https://github.com/liggitt/audit2rbac[audit2rbac] to -automatically generate Roles and binding based on the observed API calls -in the Kubernetes Audit Log. - -=== Create cluster using an automated process - -As seen in earlier steps, when creating an Amazon EKS cluster, if not -using the using `+API_AND_CONFIG_MAP+` or `+API+` authentication mode, -and not opting out to delegate `+cluster-admin+` permissions to the -cluster creator, the IAM entity user or role, such as a federated -user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster's RBAC -configuration. Even being a best practice to remove this permission, as -described xref:iam-cluster-creator[here] if using the `+CONFIG_MAP+` authentication method, relying on -`+aws-auth+` ConfigMap, this access cannot be revoked. Therefore it is a -good idea to create the cluster with an infrastructure automation -pipeline tied to dedicated IAM role, with no permissions to be assumed -by other users or entities and regularly audit this role's permissions, -policies, and who has access to trigger the pipeline. Also, this role -should not be used to perform routine actions on the cluster, and be -exclusively used to cluster level actions triggered by the pipeline, via -SCM code changes for example. - -=== Create the cluster with a dedicated IAM role - -When you create an Amazon EKS cluster, the IAM entity user or role, such -as a federated user that creates the cluster, is automatically -granted `+system:masters+` permissions in the cluster's RBAC -configuration. This access cannot be removed and is not managed through -the `+aws-auth+` ConfigMap. Therefore it is a good idea to create the -cluster with a dedicated IAM role and regularly audit who can assume -this role. This role should not be used to perform routine actions on -the cluster, and instead additional users should be granted access to -the cluster through the `+aws-auth+` ConfigMap for this purpose. After -the `+aws-auth+` ConfigMap is configured, the role should be secured and -only used in temporary elevated privilege mode / break glass for -scenarios where the cluster is otherwise inaccessible. This can be -particularly useful in clusters which do not have direct user access -configured. - -=== Regularly audit access to the cluster - -Who requires access is likely to change over time. Plan to periodically -audit the `+aws-auth+` ConfigMap to see who has been granted access and -the rights they've been assigned. You can also use open source tooling -like https://github.com/aquasecurity/kubectl-who-can[kubectl-who-can], -or https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] to examine -the roles bound to a particular service account, user, or group. We'll -explore this topic further when we get to the section on -xref:auditing-and-logging[auditing]. Additional ideas can be found in this -https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2019/august/tools-and-methods-for-auditing-kubernetes-rbac-policies/?mkt_tok=eyJpIjoiWWpGa056SXlNV1E0WWpRNSIsInQiOiJBT1hyUTRHYkg1TGxBV0hTZnRibDAyRUZ0VzBxbndnRzNGbTAxZzI0WmFHckJJbWlKdE5WWDdUQlBrYVZpMnNuTFJ1R3hacVYrRCsxYWQ2RTRcL2pMN1BtRVA1ZFZcL0NtaEtIUDdZV3pENzNLcE1zWGVwUndEXC9Pb2tmSERcL1pUaGUifQ%3D%3D[article] -from NCC Group. - -=== If relying on `+aws-auth+` configMap use tools to make changes - -An improperly formatted aws-auth ConfigMap may cause you to lose access -to the cluster. If you need to make changes to the ConfigMap, use a -tool. - -*eksctl* The `+eksctl+` CLI includes a command for adding identity -mappings to the aws-auth ConfigMap. - -View CLI Help: - -[source,bash] ----- -$ eksctl create iamidentitymapping --help -... ----- - -Check the identities mapped to your Amazon EKS Cluster. - -[source,bash] ----- -$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION -ARN USERNAME GROUPS ACCOUNT -arn:aws:iam::788355785855:role/kube-system- system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier ----- - -Make an IAM Role a Cluster Admin: - -[source,bash] ----- -$ eksctl create iamidentitymapping --cluster --region= --arn arn:aws:iam::123456:role/testing --group system:masters --username admin -... ----- - -For more information, review -https://eksctl.io/usage/iam-identity-mappings/[`+eksctl+` docs] - -*https://github.com/keikoproj/aws-auth[aws-auth] by keikoproj* - -`+aws-auth+` by keikoproj includes both a cli and a go library. - -Download and view help CLI help: - -[source,bash] ----- -$ go get github.com/keikoproj/aws-auth -... -$ aws-auth help -... ----- - -Alternatively, install `+aws-auth+` with the -https://krew.sigs.k8s.io[krew plugin manager] for kubectl. - -[source,bash] ----- -$ kubectl krew install aws-auth -... -$ kubectl aws-auth -... ----- - -https://github.com/keikoproj/aws-auth/blob/master/README.md[Review the -aws-auth docs on GitHub] for more information, including the go library. - -*https://github.com/kubernetes-sigs/aws-iam-authenticator/tree/master/cmd/aws-iam-authenticator[AWS -IAM Authenticator CLI]* - -The `+aws-iam-authenticator+` project includes a CLI for updating the -ConfigMap. - -https://github.com/kubernetes-sigs/aws-iam-authenticator/releases[Download -a release] on GitHub. - -Add cluster permissions to an IAM Role: - -[source,bash] ----- -$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config -... ----- - -=== Alternative Approaches to Authentication and Access Management - -While IAM is the preferred way to authenticate users who need access to -an EKS cluster, it is possible to use an OIDC identity provider such as -GitHub using an authentication proxy and Kubernetes -https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation[impersonation]. -Posts for two such solutions have been published on the AWS Open Source -blog: - -* https://aws.amazon.com/blogs/opensource/authenticating-eks-github-credentials-teleport/[Authenticating -to EKS Using GitHub Credentials with Teleport] -* https://aws.amazon.com/blogs/opensource/consistent-oidc-authentication-across-multiple-eks-clusters-using-kube-oidc-proxy/[Consistent -OIDC authentication across multiple EKS clusters using kube-oidc-proxy] - -!!! attention EKS natively supports OIDC authentication without using a -proxy. For further information, please read the launch blog, -https://aws.amazon.com/blogs/containers/introducing-oidc-identity-provider-authentication-amazon-eks/[Introducing -OIDC identity provider authentication for Amazon EKS]. For an example -showing how to configure EKS with Dex, a popular open source OIDC -provider with connectors for a variety of different authention methods, -see -https://aws.amazon.com/blogs/containers/using-dex-dex-k8s-authenticator-to-authenticate-to-amazon-eks/[Using -Dex & dex-k8s-authenticator to authenticate to Amazon EKS]. As described -in the blogs, the username/group of users authenticated by an OIDC -provider will appear in the Kubernetes audit log. - -You can also use -https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html[AWS -SSO] to federate AWS with an external identity provider, e.g. Azure AD. -If you decide to use this, the AWS CLI v2.0 includes an option to create -a named profile that makes it easy to associate an SSO session with your -current CLI session and assume an IAM role. Know that you must assume a -role _prior_ to running `+kubectl+` as the IAM role is used to determine -the user's Kubernetes RBAC group. - -== Identities and Credentials for EKS pods - -Certain applications that run within a Kubernetes cluster need -permission to call the Kubernetes API to function properly. For example, -the https://github.com/kubernetes-sigs/aws-load-balancer-controller[AWS -Load Balancer Controller] needs to be able to list a Service's -Endpoints. The controller also needs to be able to invoke AWS APIs to -provision and configure an ALB. In this section we will explore the best -practices for assigning rights and privileges to Pods. - -=== Kubernetes Service Accounts - -A service account is a special type of object that allows you to assign -a Kubernetes RBAC role to a pod. A default service account is created -automatically for each Namespace within a cluster. When you deploy a pod -into a Namespace without referencing a specific service account, the -default service account for that Namespace will automatically get -assigned to the Pod and the Secret, i.e. the service account (JWT) token -for that service account, will get mounted to the pod as a volume at -`+/var/run/secrets/kubernetes.io/serviceaccount+`. Decoding the service -account token in that directory will reveal the following metadata: - -[source,json] ----- -{ - "iss": "kubernetes/serviceaccount", - "kubernetes.io/serviceaccount/namespace": "default", - "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", - "kubernetes.io/serviceaccount/service-account.name": "default", - "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", - "sub": "system:serviceaccount:default:default" -} ----- - -The default service account has the following permissions to the -Kubernetes API. - -[source,yaml] ----- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: - rbac.authorization.kubernetes.io/autoupdate: "true" - creationTimestamp: "2020-01-30T18:13:25Z" - labels: - kubernetes.io/bootstrapping: rbac-defaults - name: system:discovery - resourceVersion: "43" - selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery - uid: 350d2ab8-438c-11ea-9438-063a49b60fba -rules: -- nonResourceURLs: - - /api - - /api/* - - /apis - - /apis/* - - /healthz - - /openapi - - /openapi/* - - /version - - /version/ - verbs: - - get ----- - -This role authorizes unauthenticated and authenticated users to read API -information and is deemed safe to be publicly accessible. - -When an application running within a Pod calls the Kubernetes APIs, the -Pod needs to be assigned a service account that explicitly grants it -permission to call those APIs. Similar to guidelines for user access, -the Role or ClusterRole bound to a service account should be restricted -to the API resources and methods that the application needs to function -and nothing else. To use a non-default service account simply set the -`+spec.serviceAccountName+` field of a Pod to the name of the service -account you wish to use. For additional information about creating -service accounts, see -https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions. - -!!! note Prior to Kubernetes 1.24, Kubernetes would automatically create -a secret for each a service account. This secret was mounted to the pod -at /var/run/secrets/kubernetes.io/serviceaccount and would be used by -the pod to authenticate to the Kubernetes API server. In Kubernetes -1.24, a service account token is dynamically generated when the pod runs -and is only valid for an hour by default. A secret for the service -account will not be created. If you have an application that runs -outside the cluster that needs to authenticate to the Kubernetes API, -e.g. Jenkins, you will need to create a secret of type -`+kubernetes.io/service-account-token+` along with an annotation that -references the service account such as -`+metadata.annotations.kubernetes.io/service-account.name: +`. -Secrets created in this way do not expire. - -=== IAM Roles for Service Accounts (IRSA) - -IRSA is a feature that allows you to assign an IAM role to a Kubernetes -service account. It works by leveraging a Kubernetes feature known as -https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection[Service -Account Token Volume Projection]. When Pods are configured with a -Service Account that references an IAM Role, the Kubernetes API server -will call the public OIDC discovery endpoint for the cluster on startup. -The endpoint cryptographically signs the OIDC token issued by Kubernetes -and the resulting token mounted as a volume. This signed token allows -the Pod to call the AWS APIs associated IAM role. When an AWS API is -invoked, the AWS SDKs calls `+sts:AssumeRoleWithWebIdentity+`. After -validating the token's signature, IAM exchanges the Kubernetes issued -token for a temporary AWS role credential. - -When using IRSA, it is important to -xref:iam-reuse-sessions,[reuse AWS SDK sessions] to avoid -unneeded calls to AWS STS. - -Decoding the (JWT) token for IRSA will produce output similar to the -example you see below: - -[source,json] ----- -{ - "aud": [ - "sts.amazonaws.com" - ], - "exp": 1582306514, - "iat": 1582220114, - "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", - "kubernetes.io": { - "namespace": "default", - "pod": { - "name": "alpine-57b5664646-rf966", - "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" - }, - "serviceaccount": { - "name": "s3-read-only", - "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" - } - }, - "nbf": 1582220114, - "sub": "system:serviceaccount:default:s3-read-only" -} ----- - -This particular token grants the Pod view-only privileges to S3 by -assuming an IAM role. When the application attempts to read from S3, the -token is exchanged for a temporary set of IAM credentials that resembles -this: - -[source,json] ----- -{ - "AssumedRoleUser": { - "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", - "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" - }, - "Audience": "sts.amazonaws.com", - "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", - "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", - "Credentials": { - "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", - "Expiration": "2020-02-20T18:49:50Z", - "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" - } -} ----- - -A mutating webhook that runs as part of the EKS control plane injects -the AWS Role ARN and the path to a web identity token file into the Pod -as environment variables. These values can also be supplied manually. - -[source,bash] ----- -AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME -AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token ----- - -The kubelet will automatically rotate the projected token when it is -older than 80% of its total TTL, or after 24 hours. The AWS SDKs are -responsible for reloading the token when it rotates. For further -information about IRSA, see -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html. - -=== EKS Pod Identities - -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] is a feature launched at re:Invent 2023 that allows you -to assign an IAM role to a kubernetes service account, without the need -to configure an Open Id Connect (OIDC) identity provider(IDP) for each -cluster in your AWS account. To use EKS Pod Identity, you must deploy an -agent which runs as a DaemonSet pod on every eligible worker node. This -agent is made available to you as an EKS Add-on and is a pre-requisite -to use EKS Pod Identity feature. Your applications must use a -https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html[supported -version of the AWS SDK] to use this feature. - -When EKS Pod Identities are configured for a Pod, EKS will mount and -refresh a pod identity token at -`+/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token+`. -This token will be used by the AWS SDK to communicate with the EKS Pod -Identity Agent, which uses the pod identity token and the agent's IAM -role to create temporary credentials for your pods by calling the -https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html[AssumeRoleForPodIdentity -API]. The pod identity token delivered to your pods is a JWT issued from -your EKS cluster and cryptographically signed, with appropriate JWT -claims for use with EKS Pod Identities. - -To learn more about EKS Pod Identities, please see -https://aws.amazon.com/blogs/containers/amazon-eks-pod-identity-a-new-way-for-applications-on-eks-to-obtain-iam-credentials/[this -blog]. - -You do not have to make any modifications to your application code to -use EKS Pod Identities. Supported AWS SDK versions will automatically -discover credentials made available with EKS Pod Identities by using the -https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html[credential -provider chain]. Like IRSA, EKS pod identities sets variables within -your pods to direct them how to find AWS credentials. - -==== Working with IAM roles for EKS Pod Identities - -* EKS Pod Identities can only directly assume an IAM role that belongs -to the same AWS account as the EKS cluster. To access an IAM role in -another AWS account, you must assume that role by -https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html[configuring -a profile in your SDK configuration], or in your -https://docs.aws.amazon.com/IAM/latest/UserGuide/sts_example_sts_AssumeRole_section.html[application's -code]. -* When EKS Pod Identities are being configured for Service Accounts, the -person or process configuring the Pod Identity Association must have the -`+iam:PassRole+` entitlement for that role. -* Each Service Account may only have one IAM role associated with it -through EKS Pod Identities, however you can associate the same IAM role -with multiple service accounts. -* IAM roles used with EKS Pod Identities must allow the -`+pods.eks.amazonaws.com+` Service Principal to assume them, _and_ set -session tags. The following is an example role trust policy which allows -EKS Pod Identities to use an IAM role: - -[source,json] ----- -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "Service": "pods.eks.amazonaws.com" - }, - "Action": [ - "sts:AssumeRole", - "sts:TagSession" - ], - "Condition": { - "StringEquals": { - "aws:SourceOrgId": "${aws:ResourceOrgId}" - } - } - } - ] -} ----- - -AWS recommends using condition keys like `+aws:SourceOrgId+` to help -protect against the -https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention[cross-service -confused deputy problem]. In the above example role trust policy, the -`+ResourceOrgId+` is a variable equal to the AWS Organizations -Organization ID of the AWS Organization that the AWS account belongs to. -EKS will pass in a value for `+aws:SourceOrgId+` equal to that when -assuming a role with EKS Pod Identities. - -==== ABAC and EKS Pod Identities - -When EKS Pod Identities assumes an IAM role, it sets the following -session tags: - -[width="100%",cols="<50%,<50%",options="header",] -|=== -|EKS Pod Identities Session Tag |Value -|kubernetes-namespace |The namespace the pod associated with EKS Pod -Identities runs in. - -|kubernetes-service-account |The name of the kubernetes service account -associated with EKS Pod Identities - -|eks-cluster-arn |The ARN of the EKS cluster, -e.g. `+arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}+`. -The cluster ARN is unique, but if a cluster is deleted and recreated in -the same region with the same name, within the same AWS account, it will -have the same ARN. - -|eks-cluster-name |The name of the EKS cluster. Please note that EKS -cluster names can be same within your AWS account, and EKS clusters in -other AWS accounts. - -|kubernetes-pod-name |The name of the pod in EKS. - -|kubernetes-pod-uid |The UID of the pod in EKS. -|=== - -These session tags allow you to use -https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html[Attribute -Based Access Control(ABAC)] to grant access to your AWS resources to -only specific kubernetes service accounts. When doing so, it is _very -important_ to understand that kubernetes service accounts are only -unique within a namespace, and kubernetes namespaces are only unique -within an EKS cluster. These session tags can be accessed in AWS -policies by using the `+aws:PrincipalTag/+` global condition -key, such as `+aws:PrincipalTag/eks-cluster-arn+` - -For example, if you wanted to grant access to only a specific service -account to access an AWS resource in your account with an IAM or -resource policy, you would need to check `+eks-cluster-arn+` and -`+kubernetes-namespace+` tags as well as the -`+kubernetes-service-account+` to ensure that only that service accounts -from the intended cluster have access to that resource as other clusters -could have identical `+kubernetes-service-accounts+` and -`+kubernetes-namespaces+`. - -This example S3 Bucket policy only grants access to objects in the S3 -bucket it's attached to, only if `+kubernetes-service-account+`, -`+kubernetes-namespace+`, `+eks-cluster-arn+` all meet their expected -values, where the EKS cluster is hosted in the AWS account -`+111122223333+`. - -[source,json] ----- -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Principal": { - "AWS": "arn:aws:iam::111122223333:root" - }, - "Action": "s3:*", - "Resource": [ - "arn:aws:s3:::ExampleBucket/*" - ], - "Condition": { - "StringEquals": { - "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", - "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", - "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" - } - } - } - ] -} ----- - -=== EKS Pod Identities compared to IRSA - -Both EKS Pod Identities and IRSA are preferred ways to deliver temporary -AWS credentials to your EKS pods. Unless you have specific usecases for -IRSA, we recommend you use EKS Pod Identities when using EKS. This table -helps compare the two features. - -[width="100%",cols="<34%,<33%,<33%",options="header",] -|=== -|# |EKS Pod Identities |IRSA -|Requires permission to create an OIDC IDP in your AWS accounts? |No -|Yes - -|Requires unique IDP setup per cluster |No |Yes - -|Sets relevant session tags for use with ABAC |Yes |No - -|Requires an iam:PassRole Check? |Yes |No - -|Uses AWS STS Quota from your AWS account? |No |Yes - -|Can access other AWS accounts |Indirectly with role chaining |Directly -with sts:AssumeRoleWithWebIdentity - -|Compatible with AWS SDKs |Yes |Yes - -|Requires Pod Identity Agent Daemonset on nodes? |Yes |No -|=== - -== Identities and Credentials for EKS pods Recommendations - -=== Update the aws-node daemonset to use IRSA - -At present, the aws-node daemonset is configured to use a role assigned -to the EC2 instances to assign IPs to pods. This role includes several -AWS managed policies, e.g. AmazonEKS_CNI_Policy and -EC2ContainerRegistryReadOnly that effectively allow *all* pods running -on a node to attach/detach ENIs, assign/unassign IP addresses, or pull -images from ECR. Since this presents a risk to your cluster, it is -recommended that you update the aws-node daemonset to use IRSA. A script -for doing this can be found in the -https://github.com/aws/aws-eks-best-practices/tree/master/projects/enable-irsa/src[repository] -for this guide. - -The aws-node daemonset does not support EKS Pod Identities at this time. - -=== Restrict access to the instance profile assigned to the worker node - -When you use IRSA or EKS Pod Identities, it updates the credential chain -of the pod to use IRSA or EKS Pod Identities first, however, the pod -_can still inherit the rights of the instance profile assigned to the -worker node_. When using IRSA or EKS Pod Identities, it is *strongly* -recommended that you block access -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[instance -metadata] to help ensure that your applications only have the -permissions they require, and not their nodes. - -!!! caution Blocking access to instance metadata will prevent pods that -do not use IRSA or EKS Pod Identities from inheriting the role assigned -to the worker node. - -You can block access to instance metadata by requiring the instance to -use IMDSv2 only and updating the hop count to 1 as in the example below. -You can also include these settings in the node group's launch template. -Do *not* disable instance metadata as this will prevent components like -the node termination handler and other things that rely on instance -metadata from working properly. - -[source,bash] ----- -$ aws ec2 modify-instance-metadata-options --instance-id --http-tokens required --http-put-response-hop-limit 1 -... ----- - -If you are using Terraform to create launch templates for use with -Managed Node Groups, add the metadata block to configure the hop count -as seen in this code snippet: - -`+tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...+` - -You can also block a pod's access to EC2 metadata by manipulating -iptables on the node. For further information about this method, see -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-limiting-access[Limiting -access to the instance metadata service]. - -If you have an application that is using an older version of the AWS SDK -that doesn't support IRSA or EKS Pod Identities, you should update the -SDK version. - -=== Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster - -The trust policy can be scoped to a Namespace or a specific service -account within a Namespace. When using IRSA it's best to make the role -trust policy as explicit as possible by including the service account -name. This will effectively prevent other Pods within the same Namespace -from assuming the role. The CLI `+eksctl+` will do this automatically -when you use it to create service accounts/IAM roles. See -https://eksctl.io/usage/iamserviceaccounts/ for further information. - -When working with IAM directly, this is adding condition into the role's -trust policy that uses conditions to ensure the `+:sub+` claim are the -namespace and service account you expect. As an example, before we had -an IRSA token with a sub claim of -"`system:serviceaccount:default:s3-read-only`" . This is the `+default+` -namespace and the service account is `+s3-read-only+`. You would use a -condition like the following to ensure that only your service account in -a given namespace from your cluster can assume that role: - -[source,json] ----- - "Condition": { - "StringEquals": { - "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", - "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" - } - } ----- - -=== Use one IAM role per application - -With both IRSA and EKS Pod Identity, it is a best practice to give each -application its own IAM role. This gives you improved isolation as you -can modify one application without impacting another, and allows you to -apply the principal of least privilege by only granting an application -the permissions it needs. - -When using ABAC with EKS Pod Identity, you may use a common IAM role -across multiple service accounts and rely on their session attributes -for access control. This is especially useful when operating at scale, -as ABAC allows you to operate with fewer IAM roles. - -=== When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2 - -https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html[IMDSv2] -requires you use a PUT request to get a session token. The initial PUT -request has to include a TTL for the session token. Newer versions of -the AWS SDKs will handle this and the renewal of said token -automatically. It's also important to be aware that the default hop -limit on EC2 instances is intentionally set to 1 to prevent IP -forwarding. As a consequence, Pods that request a session token that are -run on EC2 instances may eventually time out and fallback to using the -IMDSv1 data flow. EKS adds support IMDSv2 by _enabling_ both v1 and v2 -and changing the hop limit to 2 on nodes provisioned by eksctl or with -the official CloudFormation templates. - -=== Disable auto-mounting of service account tokens - -If your application doesn't need to call the Kubernetes API set the -`+automountServiceAccountToken+` attribute to `+false+` in the PodSpec -for your application or patch the default service account in each -namespace so that it's no longer mounted to pods automatically. For -example: - -[source,bash] ----- -kubectl patch serviceaccount default -p $'automountServiceAccountToken: false' ----- - -=== Use dedicated service accounts for each application - -Each application should have its own dedicated service account. This -applies to service accounts for the Kubernetes API as well as IRSA and -EKS Pod Identity. - -!!! attention If you employ a blue/green approach to cluster upgrades -instead of performing an in-place cluster upgrade when using IRSA, you -will need to update the trust policy of each of the IRSA IAM roles with -the OIDC endpoint of the new cluster. A blue/green cluster upgrade is -where you create a cluster running a newer version of Kubernetes -alongside the old cluster and use a load balancer or a service mesh to -seamlessly shift traffic from services running on the old cluster to the -new cluster. When using blue/green cluster upgrades with EKS Pod -Identity, you would create pod identity associations between the IAM -roles and service accounts in the new cluster. And update the IAM role -trust policy if you have a `+sourceArn+` condition. - -=== Run the application as a non-root user - -Containers run as root by default. While this allows them to read the -web identity token file, running a container as root is not considered a -best practice. As an alternative, consider adding the -`+spec.securityContext.runAsUser+` attribute to the PodSpec. The value -of `+runAsUser+` is arbitrary value. - -In the following example, all processes within the Pod will run under -the user ID specified in the `+runAsUser+` field. - -[source,yaml] ----- -apiVersion: v1 -kind: Pod -metadata: - name: security-context-demo -spec: - securityContext: - runAsUser: 1000 - runAsGroup: 3000 - containers: - - name: sec-ctx-demo - image: busybox - command: [ "sh", "-c", "sleep 1h" ] ----- - -When you run a container as a non-root user, it prevents the container -from reading the IRSA service account token because the token is -assigned 0600 [root] permissions by default. If you update the -securityContext for your container to include fsgroup=65534 [Nobody] it -will allow the container to read the token. - -[source,yaml] ----- -spec: - securityContext: - fsGroup: 65534 ----- - -In Kubernetes 1.19 and above, this change is no longer required and -applications can read the IRSA service account token without adding them -to the Nobody group. - -=== Grant least privileged access to applications - -https://github.com/princespaghetti/actionhero[Action Hero] is a utility -that you can run alongside your application to identify the AWS API -calls and corresponding IAM permissions your application needs to -function properly. It is similar to -https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_access-advisor.html[IAM -Access Advisor] in that it helps you gradually limit the scope of IAM -roles assigned to applications. Consult the documentation on granting -https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege[least -privileged access] to AWS resources for further information. - -Consider setting a -https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html[permissions -boundary] on IAM roles used with IRSA and Pod Identities. You can use -the permissions boundary to ensure that the roles used by IRSA or Pod -Identities can not exceed a maximum level of permissions. For an example -guide on getting started with permissions boundaries with an example -permissions boundary policy, please see this -https://github.com/aws-samples/example-permissions-boundary[github -repo]. - -=== Review and revoke unnecessary anonymous access to your EKS cluster - -Ideally anonymous access should be disabled for all API actions. -Anonymous access is granted by creating a RoleBinding or -ClusterRoleBinding for the Kubernetes built-in user system:anonymous. -You can use the https://github.com/FairwindsOps/rbac-lookup[rbac-lookup] -tool to identify permissions that system:anonymous user has on your -cluster: - -[source,bash] ----- -./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' -system:anonymous cluster-wide ClusterRole/system:discovery -system:unauthenticated cluster-wide ClusterRole/system:discovery -system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer ----- - -Any role or ClusterRole other than system:public-info-viewer should not -be bound to system:anonymous user or system:unauthenticated group. - -There may be some legitimate reasons to enable anonymous access on -specific APIs. If this is the case for your cluster ensure that only -those specific APIs are accessible by anonymous user and exposing those -APIs without authentication doesn't make your cluster vulnerable. - -Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was -associated to system:discovery and system:basic-user ClusterRoles by -default. Note that even if you have updated your cluster to version 1.14 -or higher, these permissions may still be enabled on your cluster, since -cluster updates do not revoke these permissions. To check which -ClusterRoles have "`system:unauthenticated`" except -system:public-info-viewer you can run the following command (requires jq -util): - -[source,bash] ----- -kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name' ----- - -And "`system:unauthenticated`" can be removed from all the roles except -"`system:public-info-viewer`" using: - -[source,bash] ----- -kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f - ----- - -Alternatively, you can check and remove it manually by kubectl describe -and kubectl edit. To check if system:unauthenticated group has -system:discovery permissions on your cluster run the following command: - -[source,bash] ----- -kubectl describe clusterrolebindings system:discovery - -Name: system:discovery -Labels: kubernetes.io/bootstrapping=rbac-defaults -Annotations: rbac.authorization.kubernetes.io/autoupdate: true -Role: - Kind: ClusterRole - Name: system:discovery -Subjects: - Kind Name Namespace - ---- ---- --------- - Group system:authenticated - Group system:unauthenticated ----- - -To check if system:unauthenticated group has system:basic-user -permission on your cluster run the following command: - -[source,bash] ----- -kubectl describe clusterrolebindings system:basic-user - -Name: system:basic-user -Labels: kubernetes.io/bootstrapping=rbac-defaults -Annotations: rbac.authorization.kubernetes.io/autoupdate: true -Role: - Kind: ClusterRole - Name: system:basic-user -Subjects: - Kind Name Namespace - ---- ---- --------- - Group system:authenticated - Group system:unauthenticated ----- - -If system:unauthenticated group is bound to system:discovery and/or -system:basic-user ClusterRoles on your cluster, you should disassociate -these roles from system:unauthenticated group. Edit system:discovery -ClusterRoleBinding using the following command: - -[source,bash] ----- -kubectl edit clusterrolebindings system:discovery ----- - -The above command will open the current definition of system:discovery -ClusterRoleBinding in an editor as shown below: - -[source,yaml] ----- -# Please edit the object below. Lines beginning with a '#' will be ignored, -# and an empty file will abort the edit. If an error occurs while saving this file will be -# reopened with the relevant failures. -# -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - annotations: - rbac.authorization.kubernetes.io/autoupdate: "true" - creationTimestamp: "2021-06-17T20:50:49Z" - labels: - kubernetes.io/bootstrapping: rbac-defaults - name: system:discovery - resourceVersion: "24502985" - selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery - uid: b7936268-5043-431a-a0e1-171a423abeb6 -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:discovery -subjects: -- apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:authenticated -- apiGroup: rbac.authorization.k8s.io - kind: Group - name: system:unauthenticated ----- - -Delete the entry for system:unauthenticated group from the "`subjects`" -section in the above editor screen. - -Repeat the same steps for system:basic-user ClusterRoleBinding. - -[[iam-reuse-sessions,iam-reuse-sessions.title]] -=== Reuse AWS SDK sessions with IRSA - -When you use IRSA, applications written using the AWS SDK use the token -delivered to your pods to call `+sts:AssumeRoleWithWebIdentity+` to -generate temporary AWS credentials. This is different from other AWS -compute services, where the compute service delivers temporary AWS -credentials directly to the AWS compute resource, such as a lambda -function. This means that every time an AWS SDK session is initialized, -a call to AWS STS for `+AssumeRoleWithWebIdentity+` is made. If your -application scales rapidly and initializes many AWS SDK sessions, you -may experience throttling from AWS STS as your code will be making many -calls for `+AssumeRoleWithWebIdentity+`. - -To avoid this scenario, we recommend reusing AWS SDK sessions within -your application so that unnecessary calls to -`+AssumeRoleWithWebIdentity+` are not made. - -In the following example code, a session is created using the boto3 -python SDK, and that same session is used to create clients and interact -with both Amazon S3 and Amazon SQS. `+AssumeRoleWithWebIdentity+` is -only called once, and the AWS SDK will refresh the credentials of -`+my_session+` when they expire automatically. - -```python -import boto3 - -= Create your own session - -my_session = boto3.session.Session() - -= Now we can create low-level clients from our session - -sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') - -s3response = s3.list_buckets() sqsresponse = sqs.list_queues() - -#print the response from the S3 and SQS APIs print("`s3 response:`") -print(s3response) print("`—`") print("`sqs response:`") -print(sqsresponse) ``` -``` - - -If you're migrating an application from another AWS compute service, -such as EC2, to EKS with IRSA, this is a particularly important detail. -On other compute services initializing an AWS SDK session does not call -AWS STS unless you instruct it to. - -=== Alternative approaches - -While IRSA and EKS Pod Identities are the _preferred ways_ to assign an -AWS identity to a pod, they require that you include recent version of -the AWS SDKs in your application. For a complete listing of the SDKs -that currently support IRSA, see -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, -for EKS Pod Identities, see -https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. -If you have an application that you can't immediately update with a -compatible SDK, there are several community-built solutions available -for assigning IAM roles to Kubernetes pods, including -https://github.com/jtblin/kube2iam[kube2iam] and -https://github.com/uswitch/kiam[kiam]. Although AWS doesn't endorse, -condone, nor support the use of these solutions, they are frequently -used by the community at large to achieve similar results as IRSA and -EKS Pod Identities. - -If you need to use one of these non-aws provided solutions, please -exercise due diligence and ensure you understand security implications -of doing so. - -== Tools and Resources - -* https://catalog.workshops.aws/eks-security-immersionday/en-US/2-identity-and-access-management[Amazon -EKS Security Immersion Workshop - Identity and Access Management] -* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/fully-private-cluster[Terraform -EKS Blueprints Pattern - Fully Private Amazon EKS Cluster] -* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-iam-identity-center[Terraform -EKS Blueprints Pattern - IAM Identity Center Single Sign-On for Amazon -EKS Cluster] -* https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main/patterns/sso-okta[Terraform -EKS Blueprints Pattern - Okta Single Sign-On for Amazon EKS Cluster] -* https://github.com/liggitt/audit2rbac[audit2rbac] -* https://github.com/mhausenblas/rbac.dev[rbac.dev] A list of additional -resources, including blogs and tools, for Kubernetes RBAC -* https://github.com/princespaghetti/actionhero[Action Hero] -* https://github.com/jtblin/kube2iam[kube2iam] -* https://github.com/uswitch/kiam[kiam] From 5ae81b20008b35fc20de274c3a9fe3efddb48737 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 3 Jul 2024 00:40:02 +0000 Subject: [PATCH 25/56] revise --- latest/bpg/security/hosts.adoc.backup | 366 + latest/bpg/security/index.adoc | 2 +- latest/bpg/security/index.html | 9035 ------------------ latest/bpg/security/multiaccount.adoc | 56 +- latest/bpg/security/multiaccount.adoc.backup | 430 + latest/bpg/security/test.py | 2 +- 6 files changed, 826 insertions(+), 9065 deletions(-) create mode 100644 latest/bpg/security/hosts.adoc.backup delete mode 100644 latest/bpg/security/index.html create mode 100644 latest/bpg/security/multiaccount.adoc.backup diff --git a/latest/bpg/security/hosts.adoc.backup b/latest/bpg/security/hosts.adoc.backup new file mode 100644 index 000000000..e47ef28b1 --- /dev/null +++ b/latest/bpg/security/hosts.adoc.backup @@ -0,0 +1,366 @@ +//!!NODE_ROOT
+[."topic"] +[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] += Protecting the infrastructure (hosts) +:info_doctype: section +:info_title: Protecting the infrastructure (hosts) +:info_abstract: Protecting the infrastructure (hosts) +:info_titleabbrev: Protecting the infrastructure (hosts) +:imagesdir: images/ + +Inasmuch as it’s important to secure your container images, it’s equally +important to safeguard the infrastructure that runs them. This section +explores different ways to mitigate risks from attacks launched directly +against the host. These guidelines should be used in conjunction with +those outlined in the link:runtime.md[Runtime Security] section. + +== Recommendations + +=== Use an OS optimized for running containers + +Consider using Flatcar Linux, Project Atomic, RancherOS, and +https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a +special purpose OS from AWS designed for running Linux containers. It +includes a reduced attack surface, a disk image that is verified on +boot, and enforced permission boundaries using SELinux. + +Alternately, use the +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html[EKS +optimized AMI] for your Kubernetes worker nodes. The EKS optimized AMI +is released regularly and contains a minimal set of OS packages and +binaries necessary to run your containerized workloads. + +Please refer https://github.com/aws-samples/amazon-eks-ami-rhel[Amazon +EKS AMI RHEL Build Specification] for a sample configuration script +which can be used for building a custom Amazon EKS AMI running on Red +Hat Enterprise Linux using Hashicorp Packer. This script can be further +leveraged to build STIG compliant EKS custom AMIs. + +=== Keep your worker node OS updated + +Regardless of whether you use a container-optimized host OS like +Bottlerocket or a larger, but still minimalist, Amazon Machine Image +like the EKS optimized AMIs, it is best practice to keep these host OS +images up to date with the latest security patches. + +For the EKS optimized AMIs, regularly check the +https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md[CHANGELOG] +and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes +channel] and automate the rollout of updated worker node images into +your cluster. + +=== Treat your infrastructure as immutable and automate the replacement of your worker nodes + +Rather than performing in-place upgrades, replace your workers when a +new patch or update becomes available. This can be approached a couple +of ways. You can either add instances to an existing autoscaling group +using the latest AMI as you sequentially cordon and drain nodes until +all of the nodes in the group have been replaced with the latest AMI. +Alternatively, you can add instances to a new node group while you +sequentially cordon and drain nodes from the old node group until all of +the nodes have been replaced. EKS +https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed +node groups] uses the first approach and will display a message in the +console to upgrade your workers when a new AMI becomes available. +`+eksctl+` also has a mechanism for creating node groups with the latest +AMI and for gracefully cordoning and draining pods from nodes groups +before the instances are terminated. If you decide to use a different +method for replacing your worker nodes, it is strongly recommended that +you automate the process to minimize human oversight as you will likely +need to replace workers regularly as new updates/patches are released +and when the control plane is upgraded. + +With EKS Fargate, AWS will automatically update the underlying +infrastructure as updates become available. Oftentimes this can be done +seamlessly, but there may be times when an update will cause your pod to +be rescheduled. Hence, we recommend that you create deployments with +multiple replicas when running your application as a Fargate pod. + +=== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] + +kube-bench is an open source project from Aqua that evaluates your +cluster against the CIS benchmarks for Kubernetes. The benchmark +describes the best practices for securing unmanaged Kubernetes clusters. +The CIS Kubernetes Benchmark encompasses the control plane and the data +plane. Since Amazon EKS provides a fully managed control plane, not all +of the recommendations from the CIS Kubernetes Benchmark are applicable. +To ensure this scope reflects how Amazon EKS is implemented, AWS created +the _CIS Amazon EKS Benchmark_. The EKS benchmark inherits from CIS +Kubernetes Benchmark with additional inputs from the community with +specific configuration considerations for EKS clusters. + +When running https://github.com/aquasecurity/kube-bench[kube-bench] +against an EKS cluster, follow +https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster[these +instructions] from Aqua Security. For further information see +https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing +The CIS Amazon EKS Benchmark]. + +=== Minimize access to worker nodes + +Instead of enabling SSH access, use +https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM +Session Manager] when you need to remote into a host. Unlike SSH keys +which can be lost, copied, or shared, Session Manager allows you to +control access to EC2 instances using IAM. Moreover, it provides an +audit trail and log of the commands that were run on the instance. + +As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 +Launch Templates. This allows you to embed the SSM agent into the AMI or +install it as the worker node is being bootstrapped. If you rather not +modify the Optimized AMI or the ASG’s launch template, you can install +the SSM agent with a DaemonSet as in +https://github.com/aws-samples/ssm-agent-daemonset-installer[this +example]. + +==== Minimal IAM policy for SSM based SSH Access + +The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a +number of permissions that are not required for SSM Session Manager / +SSM RunCommand if you’re just looking to avoid SSH access. Of concern +specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which +would allow for the role to access all parameters in Parameter Store +(including SecureStrings with the AWS managed KMS key configured). + +The following IAM policy contains the minimal set of permissions to +enable node access via SSM Systems Manager. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "EnableAccessViaSSMSessionManager", + "Effect": "Allow", + "Action": [ + "ssmmessages:OpenDataChannel", + "ssmmessages:OpenControlChannel", + "ssmmessages:CreateDataChannel", + "ssmmessages:CreateControlChannel", + "ssm:UpdateInstanceInformation" + ], + "Resource": "*" + }, + { + "Sid": "EnableSSMRunCommand", + "Effect": "Allow", + "Action": [ + "ssm:UpdateInstanceInformation", + "ec2messages:SendReply", + "ec2messages:GetMessages", + "ec2messages:GetEndpoint", + "ec2messages:FailMessage", + "ec2messages:DeleteMessage", + "ec2messages:AcknowledgeMessage" + ], + "Resource": "*" + } + ] +} +---- + +With this policy in place and the +https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html[Session +Manager plugin] installed, you can then run + +[source,bash] +---- +aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE] +---- + +to access the node. + +!!! note You may also want to consider adding permissions to +https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable +Session Manager logging]. + +=== Deploy workers onto private subnets + +By deploying workers onto private subnets, you minimize their exposure +to the Internet where attacks often originate. Beginning April 22, 2020, +the assignment of public IP addresses to nodes in a managed node groups +will be controlled by the subnet they are deployed onto. Prior to this, +nodes in a Managed Node Group were automatically assigned a public IP. +If you choose to deploy your worker nodes on to public subnets, +implement restrictive AWS security group rules to limit their exposure. + +=== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices + +You can use +https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon +Inspector] to check for unintended network access to your nodes and for +vulnerabilities on the underlying Amazon EC2 instances. + +Amazon Inspector can provide common vulnerabilities and exposures (CVE) +data for your Amazon EC2 instances only if the Amazon EC2 Systems +Manager (SSM) agent is installed and enabled. This agent is preinstalled +on several +https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html[Amazon +Machine Images (AMIs)] including +https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS +optimized Amazon Linux AMIs]. Regardless of SSM agent status, all of +your Amazon EC2 instances are scanned for network reachability issues. +For more information about configuring scans for Amazon EC2, see +https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html[Scanning +Amazon EC2 instances]. + +!!! attention Inspector cannot be run on the infrastructure used to run +Fargate pods. + +== Alternatives + +// [[iam-se-linux,iam-se-linux.title]] +// === Run SELinux + +// !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, +// Bottlerocket, and Amazon Linux 2023 + +// SELinux provides an additional layer of security to keep containers +// isolated from each other and from the host. SELinux allows +// administrators to enforce mandatory access controls (MAC) for every +// user, application, process, and file. Think of it as a backstop that +// restricts the operations that can be performed against to specific +// resources based on a set of labels. On EKS, SELinux can be used to +// prevent containers from accessing each other’s resources. + +// Container SELinux policies are defined in the +// https://github.com/containers/container-selinux[container-selinux] +// package. Docker CE requires this package (along with its dependencies) +// so that the processes and files created by Docker (or other container +// runtimes) run with limited system access. Containers leverage the +// `+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +// policies effectively prevent containers from accessing certain features +// of the host. + +// When you configure SELinux for Docker, Docker automatically labels +// workloads `+container_t+` as a type and gives each container a unique +// MCS level. This will isolate containers from one another. If you need +// looser restrictions, you can create your own profile in SElinux which +// grants a container permissions to specific areas of the file system. +// This is similar to PSPs in that you can create different profiles for +// different containers/pods. For example, you can have a profile for +// general workloads with a set of restrictive controls and another for +// things that require privileged access. + +// SELinux for Containers has a set of options that can be configured to +// modify the default restrictions. The following SELinux Booleans can be +// enabled or disabled based on your needs: + +// [width="100%",cols="30%,^40%,30%",options="header",] +// |=== +// |Boolean |Default |Description +// |`+container_connect_any+` |`+off+` |Allow containers to access +// privileged ports on the host. For example, if you have a container that +// needs to map ports to 443 or 80 on the host. + +// |`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +// configuration. For example, a container running systemd will need this +// to be enabled. + +// |`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file +// system. +// |=== + +// By default, containers are allowed to read/execute under `+/usr+` and +// read most content from `+/etc+`. The files under `+/var/lib/docker+` and +// `+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +// a full list of default, labels see the +// https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] +// file. + +// [source,bash] +// ---- +// docker container run -it \ +// -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ +// centos:7 cat /host/repositories.json +// # cat: /host/repositories.json: Permission denied + +// docker container run -it \ +// -v /etc/passwd:/host/etc/passwd \ +// centos:7 cat /host/etc/passwd +// # cat: /host/etc/passwd: Permission denied +// ---- + +// Files labeled with `+container_file_t+` are the only files that are +// writable by containers. If you want a volume mount to be writeable, you +// will needed to specify `+:z+` or `+:Z+` at the end. + +// * `+:z+` will re-label the files so that the container can read/write +// * `+:Z+` will re-label the files so that *only* the container can +// read/write + +// [source,bash] +// ---- +// ls -Z /var/lib/misc +// # -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp + +// docker container run -it \ +// -v /var/lib/misc:/host/var/lib/misc:z \ +// centos:7 echo "Relabeled!" + +// ls -Z /var/lib/misc +// #-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp +// ---- + +// [source,bash] +// ---- +// docker container run -it \ +// -v /var/log:/host/var/log:Z \ +// fluentbit:latest +// ---- + +// In Kubernetes, relabeling is slightly different. Rather than having +// Docker automatically relabel the files, you can specify a custom MCS +// label to run the pod. Volumes that support relabeling will automatically +// be relabeled so that they are accessible. Pods with a matching MCS label +// will be able to access the volume. If you need strict isolation, set a +// different MCS label for each pod. + +// [source,yaml] +// ---- +// securityContext: +// seLinuxOptions: +// # Provide a unique MCS label per container +// # You can specify user, role, and type also +// # enforcement based on type and level (svert) +// level: s0:c144:c154 +// ---- + +// In this example `+s0:c144:c154+` corresponds to an MCS label assigned to +// a file that the container is allowed to access. + +// On EKS you could create policies that allow for privileged containers to +// run, like FluentD and create an SELinux policy to allow it to read from +// /var/log on the host without needing to relabel the host directory. Pods +// with the same label will be able to access the same host volumes. + +// We have implemented +// https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for +// Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These +// AMIs were developed to demonstrate sample implementations that meet +// requirements of highly regulated customers, such as STIG, CJIS, and C2S. + +// !!! caution SELinux will ignore containers where the type is unconfined. + +== Tools and resources + +* https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux +Kubernetes RBAC and Shipping Security Policies for On-prem Applications] +* https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html[Iterative +Hardening of Kubernetes] +* https://linux.die.net/man/1/audit2allow[Audit2Allow] +* https://linux.die.net/man/8/sealert[SEAlert] +* https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica[Generate +SELinux policies for containers with Udica] describes a tool that looks +at container spec files for Linux capabilities, ports, and mount points, +and generates a set of SELinux rules that allow the container to run +properly +* https://github.com/aws-samples/amazon-eks-custom-amis#hardening[AMI +Hardening] playbooks for hardening the OS to meet different regulatory +requirements +* https://github.com/keikoproj/upgrade-manager[Keiko Upgrade Manager] an +open source project from Intuit that orchestrates the rotation of worker +nodes. +* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] +* https://eksctl.io/[eksctl] diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 44e2a68dd..26f7e6c30 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -159,7 +159,7 @@ include::hosts.adoc[leveloffset=+1] include::compliance.adoc[leveloffset=+1] -//include::incidents.adoc[leveloffset=+1] +include::incidents.adoc[leveloffset=+1] include::image.adoc[leveloffset=+1] diff --git a/latest/bpg/security/index.html b/latest/bpg/security/index.html deleted file mode 100644 index a19658510..000000000 --- a/latest/bpg/security/index.html +++ /dev/null @@ -1,9035 +0,0 @@ - - - - - - - -Amazon EKS Best Practices Guide for Security - - - - - - -
-
-
-
-

This guide provides advice about protecting information, systems, and -assets that are reliant on EKS while delivering business value through -risk assessments and mitigation strategies. The guidance herein is part -of a series of best practices guides that AWS is publishing to help -customers implement EKS in accordance with best practices. Guides for -Performance, Operational Excellence, Cost Optimization, and Reliability -will be available in the coming months.

-
-
-
-
-

1. How to use this guide

-
-
-

This guide is meant for security practitioners who are responsible for -implementing and monitoring the effectiveness of security controls for -EKS clusters and the workloads they support. The guide is organized into -different topic areas for easier consumption. Each topic starts with a -brief overview, followed by a list of recommendations and best practices -for securing your EKS clusters. The topics do not need to be read in a -particular order.

-
-
-
-
-

2. Understanding the Shared Responsibility Model

-
-
-

Security and compliance are considered shared responsibilities when -using a managed service like EKS. Generally speaking, AWS is responsible -for security “of” the cloud whereas you, the customer, are responsible -for security “in” the cloud. With EKS, AWS is responsible for managing -of the EKS managed Kubernetes control plane. This includes the -Kubernetes control plane nodes, the ETCD database, and other -infrastructure necessary for AWS to deliver a secure and reliable -service. As a consumer of EKS, you are largely responsible for the -topics in this guide, e.g. IAM, pod security, runtime security, network -security, and so forth.

-
-
-

When it comes to infrastructure security, AWS will assume additional -responsibilities as you move from self-managed workers, to managed node -groups, to Fargate. For example, with Fargate, AWS becomes responsible -for securing the underlying instance/runtime used to run your Pods.

-
-
-
-Shared Responsibility Model - Fargate -
-
Figure 1. Shared Responsibility Model - Fargate
-
-
-

AWS will also assume responsibility of keeping the EKS optimized AMI up -to date with Kubernetes patch versions and security patches. Customers -using Managed Node Groups (MNG) are responsible for upgrading their -Nodegroups to the latest AMI via EKS API, CLI, Cloudformation or AWS -Console. Also unlike Fargate, MNGs will not automatically scale your -infrastructure/cluster. That can be handled by the -cluster-autoscaler -or other technologies such as Karpenter, native -AWS autoscaling, SpotInst’s -Ocean, or Atlassian’s -Escalator.

-
-
-
-Shared Responsibility Model - MNG -
-
Figure 2. Shared Responsibility Model - MNG
-
-
-

Before designing your system, it is important to know where the line of -demarcation is between your responsibilities and the provider of the -service (AWS).

-
-
-

For additional information about the shared responsibility model, see -https://aws.amazon.com/compliance/shared-responsibility-model/

-
-
-
-
-

3. Introduction

-
-
-

There are several security best practice areas that are pertinent when -using a managed Kubernetes service like EKS:

-
-
-
    -
  • -

    Identity and Access Management

    -
  • -
  • -

    Pod Security

    -
  • -
  • -

    Runtime Security

    -
  • -
  • -

    Network Security

    -
  • -
  • -

    Multi-tenancy

    -
  • -
  • -

    Multi Account for Multi-tenancy

    -
  • -
  • -

    Detective Controls

    -
  • -
  • -

    Infrastructure Security

    -
  • -
  • -

    Data Encryption and Secrets Management

    -
  • -
  • -

    Regulatory Compliance

    -
  • -
  • -

    Incident Response and Forensics

    -
  • -
  • -

    Image Security

    -
  • -
-
-
-

As part of designing any system, you need to think about its security -implications and the practices that can affect your security posture. -For example, you need to control who can perform actions against a set -of resources. You also need the ability to quickly identify security -incidents, protect your systems and services from unauthorized access, -and maintain the confidentiality and integrity of data through data -protection. Having a well-defined and rehearsed set of processes for -responding to security incidents will improve your security posture too. -These tools and techniques are important because they support objectives -such as preventing financial loss or complying with regulatory -obligations.

-
-
-

AWS helps organizations achieve their security and compliance goals by -offering a rich set of security services that have evolved based on -feedback from a broad set of security conscious customers. By offering a -highly secure foundation, customers can spend less time on -“undifferentiated heavy lifting” and more time on achieving their -business objectives.

-
-
-
-
-

4. Feedback

-
-
-

This guide is being released on GitHub so as to collect direct feedback -and suggestions from the broader EKS/Kubernetes community. If you have a -best practice that you feel we ought to include in the guide, please -file an issue or submit a PR in the GitHub repository. Our intention is -to update the guide periodically as new features are added to the -service or when a new best practice evolves.

-
-
-
-
-

5. Further Reading

-
-
-

Kubernetes -Security Whitepaper, sponsored by the Security Audit Working Group, -this Whitepaper describes key aspects of the Kubernetes attack surface -and security architecture with the aim of helping security practitioners -make sound design and implementation decisions.

-
-
-

The CNCF published also a -white -paper on cloud native security. The paper examines how the technology -landscape has evolved and advocates for the adoption of security -practices that align with DevOps processes and agile methodologies.

-
-
-
-
-

6. Tools and resources

- -
-
-

7. Identity and Access Management

-
-
-

Identity -and Access Management (IAM) is an AWS service that performs two -essential functions: Authentication and Authorization. Authentication -involves the verification of a identity whereas authorization governs -the actions that can be performed by AWS resources. Within AWS, a -resource can be another AWS service, e.g. EC2, or an AWS -principal -such as an -IAM -User or -Role. -The rules governing the actions that a resource is allowed to perform -are expressed as -IAM -policies.

-
-
-

7.1. Controlling Access to EKS Clusters

-
-

The Kubernetes project supports a variety of different strategies to -authenticate requests to the kube-apiserver service, e.g. Bearer Tokens, -X.509 certificates, OIDC, etc. EKS currently has native support for -webhook -token authentication, -service -account tokens, and as of February 21, 2021, OIDC authentication.

-
-
-

The webhook authentication strategy calls a webhook that verifies bearer -tokens. On EKS, these bearer tokens are generated by the AWS CLI or the -aws-iam-authenticator -client when you run kubectl commands. As you execute commands, the -token is passed to the kube-apiserver which forwards it to the -authentication webhook. If the request is well-formed, the webhook calls -a pre-signed URL embedded in the token’s body. This URL validates the -request’s signature and returns information about the user, e.g. the -user’s account, Arn, and UserId to the kube-apiserver.

-
-
-

To manually generate a authentication token, type the following command -in a terminal window:

-
-
-
-
aws eks get-token --cluster-name <cluster_name>
-
-
-
-

You can also get a token programmatically. Below is an example written -in Go:

-
-
-
-
package main
-
-import (
-  "fmt"
-  "log"
-  "sigs.k8s.io/aws-iam-authenticator/pkg/token"
-)
-
-func main()  {
-  g, _ := token.NewGenerator(false, false)
-  tk, err := g.Get("<cluster_name>")
-  if err != nil {
-    log.Fatal(err)
-  }
-  fmt.Println(tk)
-}
-
-
-
-

The output should resemble this:

-
-
-
-
{
-  "kind": "ExecCredential",
-  "apiVersion": "client.authentication.k8s.io/v1alpha1",
-  "spec": {},
-  "status": {
-    "expirationTimestamp": "2020-02-19T16:08:27Z",
-    "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz"
-  }
-}
-
-
-
-

Each token starts with k8s-aws-v1. followed by a base64 encoded -string. The string, when decoded, should resemble to something similar -to this:

-
-
-
-
https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393
-
-
-
-

The token consists of a pre-signed URL that includes an Amazon -credential and signature. For additional details see -https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html.

-
-
-

The token has a time to live (TTL) of 15 minutes after which a new token -will need to be generated. This is handled automatically when you use a -client like kubectl, however, if you’re using the Kubernetes -dashboard, you will need to generate a new token and re-authenticate -each time the token expires.

-
-
-

Once the user’s identity has been authenticated by the AWS IAM service, -the kube-apiserver reads the aws-auth ConfigMap in the -kube-system Namespace to determine the RBAC group to associate with -the user. The aws-auth ConfigMap is used to create a static mapping -between IAM principals, i.e. IAM Users and Roles, and Kubernetes RBAC -groups. RBAC groups can be referenced in Kubernetes RoleBindings or -ClusterRoleBindings. They are similar to IAM Roles in that they define a -set of actions (verbs) that can be performed against a collection of -Kubernetes resources (objects).

-
-
-

7.1.1. Cluster Access Manager

-
-

Cluster Access Manager, now the preferred way to manage access of AWS -IAM principals to Amazon EKS clusters, is a functionality of the AWS API -and is an opt-in feature for EKS v1.23 and later clusters (new or -existing). It simplifies identity mapping between AWS IAM and Kubernetes -RBACs, eliminating the need to switch between AWS and Kubernetes APIs or -editing the aws-auth ConfigMap for access management, reducing -operational overhead, and helping address misconfigurations. The tool -also enables cluster administrators to revoke or refine -cluster-admin permissions automatically granted to the AWS IAM -principal used to create the cluster.

-
-
-

This API relies on two concepts:

-
-
-
    -
  • -

    Access Entries: A cluster identity directly linked to an AWS IAM -principal (user or role) allowed to authenticate to an Amazon EKS -cluster.

    -
  • -
  • -

    Access Policies: Are Amazon EKS specific policies that provides the -authorization for an Access Entry to perform actions in the Amazon EKS -cluster.

    -
  • -
-
-
-
-
-

At launch Amazon EKS supports only predefined and AWS managed policies. -Access policies are not IAM entities and are defined and managed by -Amazon EKS.

-
-
-
-
-

Cluster Access Manager allows the combination of upstream RBAC with -Access Policies supporting allow and pass (but not deny) on Kubernetes -AuthZ decisions regarding API server requests. A deny decision will -happen when both, the upstream RBAC and Amazon EKS authorizers can’t -determine the outcome of a request evaluation.

-
-
-

With this feature, Amazon EKS supports three modes of authentication:

-
-
-
    -
  1. -

    CONFIG_MAP to continue using aws-auth configMap exclusively.

    -
  2. -
  3. -

    API_AND_CONFIG_MAP to source authenticated IAM principals from -both EKS Access Entry APIs and the aws-auth configMap, prioritizing -the Access Entries. Ideal to migrate existing aws-auth permissions -to Access Entries.

    -
  4. -
  5. -

    API to exclusively rely on EKS Access Entry APIs. This is the new -recommended approach.

    -
  6. -
-
-
-

To get started, cluster administrators can create or update Amazon EKS -clusters, setting the preferred authentication to API_AND_CONFIG_MAP -or API method and define Access Entries to grant access the desired -AWS IAM principals.

-
-
-
-
$ aws eks create-cluster \
-    --name <CLUSTER_NAME> \
-    --role-arn <CLUSTER_ROLE_ARN> \
-    --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \
-    --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \
-    --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false
-
-
-
-

The above command is an example to create an Amazon EKS cluster already -without the admin permissions of the cluster creator.

-
-
-

It is possible to update Amazon EKS clusters configuration to enable -API authenticationMode using the update-cluster-config command, -to do that on existing clusters using CONFIG_MAP you will have to -first update to API_AND_CONFIG_MAP and then to API. These -operations cannot be reverted, meaning that’s not possible to switch -from API to API_AND_CONFIG_MAP or CONFIG_MAP, and also from -API_AND_CONFIG_MAP to CONFIG_MAP.

-
-
-
-
$ aws eks update-cluster-config \
-    --name <CLUSTER_NAME> \
-    --access-config authenticationMode=API
-
-
-
-

The API support commands to add and revoke access to the cluster, as -well as validate the existing Access Policies and Access Entries for the -specified cluster. The default policies are created to match Kubernetes -RBACs as follows.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - -
EKS Access PolicyKubernetes RBAC

AmazonEKSClusterAdminPolicy

cluster-admin

AmazonEKSAdminPolicy

admin

AmazonEKSEditPolicy

edit

AmazonEKSViewPolicy

view

-
-
-
$ aws eks list-access-policies
-{
-    "accessPolicies": [
-        {
-            "name": "AmazonEKSAdminPolicy",
-            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy"
-        },
-        {
-            "name": "AmazonEKSClusterAdminPolicy",
-            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy"
-        },
-        {
-            "name": "AmazonEKSEditPolicy",
-            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy"
-        },
-        {
-            "name": "AmazonEKSViewPolicy",
-            "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
-        }
-    ]
-}
-
-$ aws eks list-access-entries --cluster-name <CLUSTER_NAME>
-
-{
-    "accessEntries": []
-}
-
-
-
-
-
-

No Access Entries are available when the cluster is created without the -cluster creator admin permission, which is the only entry created by -default.

-
-
-
-
-
-

7.1.2. The aws-auth ConfigMap (deprecated)

-
-

One way Kubernetes integration with AWS authentication can be done is -via the aws-auth ConfigMap, which resides in the kube-system -Namespace. It is responsible for mapping the AWS IAM Identities (Users, -Groups, and Roles) authentication, to Kubernetes role-based access -control (RBAC) authorization. The aws-auth ConfigMap is -automatically created in your Amazon EKS cluster during its provisioning -phase. It was initially created to allow nodes to join your cluster, but -as mentioned you can also use this ConfigMap to add RBACs access to IAM -principals.

-
-
-

To check your cluster’s aws-auth ConfigMap, you can use the -following command.

-
-
-
-
kubectl -n kube-system get configmap aws-auth -o yaml
-
-
-
-

This is a sample of a default configuration of the aws-auth -ConfigMap.

-
-
-
-
apiVersion: v1
-data:
-  mapRoles: |
-    - groups:
-      - system:bootstrappers
-      - system:nodes
-      - system:node-proxier
-      rolearn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/kube-system-<SELF_GENERATED_UUID>
-      username: system:node:{{SessionName}}
-kind: ConfigMap
-metadata:
-  creationTimestamp: "2023-10-22T18:19:30Z"
-  name: aws-auth
-  namespace: kube-system
-
-
-
-

The main session of this ConfigMap, is under data in the -mapRoles block, which is basically composed by 3 parameters.

-
-
-
    -
  • -

    groups: The Kubernetes group(s) to map the IAM Role to. This can be -a default group, or a custom group specified in a clusterrolebinding -or rolebinding. In the above example we have just system groups -declared.

    -
  • -
  • -

    rolearn: The ARN of the AWS IAM Role be mapped to the Kubernetes -group(s) add, using the following format -arn:<PARTITION>:iam::<AWS_ACCOUNT_ID>:role/role-name.

    -
  • -
  • -

    username: The username within Kubernetes to map to the AWS IAM role. -This can be any custom name.

    -
  • -
-
-
-
-
-

It is also possible to map permissions for AWS IAM Users, defining a new -configuration block for mapUsers, under data in the aws-auth -ConfigMap, replacing the rolearn parameter for userarn, however as a -Best Practice it’s always recommended to user mapRoles instead.

-
-
-
-
-

To manage permissions, you can edit the aws-auth ConfigMap adding or -removing access to your Amazon EKS cluster. Although it’s possible to -edit the aws-auth ConfigMap manually, it’s recommended using tools -like eksctl, since this is a very senstitive configuration, and an -inaccurate configuration can lock you outside your Amazon EKS Cluster. -Check the subsection -Use -tools to make changes to the aws-auth ConfigMap below for more details.

-
-
-
-
-

7.2. Cluster Access Recommendations

-
-

7.2.1. Make the EKS Cluster Endpoint private

-
-

By default when you provision an EKS cluster, the API cluster endpoint -is set to public, i.e. it can be accessed from the Internet. Despite -being accessible from the Internet, the endpoint is still considered -secure because it requires all API requests to be authenticated by IAM -and then authorized by Kubernetes RBAC. That said, if your corporate -security policy mandates that you restrict access to the API from the -Internet or prevents you from routing traffic outside the cluster VPC, -you can:

-
-
-
    -
  • -

    Configure the EKS cluster endpoint to be private. See -Modifying -Cluster Endpoint Access for further information on this topic.

    -
  • -
  • -

    Leave the cluster endpoint public and specify which CIDR blocks can -communicate with the cluster endpoint. The blocks are effectively a -whitelisted set of public IP addresses that are allowed to access the -cluster endpoint.

    -
  • -
  • -

    Configure public access with a set of whitelisted CIDR blocks and set -private endpoint access to enabled. This will allow public access from a -specific range of public IPs while forcing all network traffic between -the kubelets (workers) and the Kubernetes API through the cross-account -ENIs that get provisioned into the cluster VPC when the control plane is -provisioned.

    -
  • -
-
-
-
-

7.2.2. Don’t use a service account token for authentication

-
-

A service account token is a long-lived, static credential. If it is -compromised, lost, or stolen, an attacker may be able to perform all the -actions associated with that token until the service account is deleted. -At times, you may need to grant an exception for applications that have -to consume the Kubernetes API from outside the cluster, e.g. a CI/CD -pipeline application. If such applications run on AWS infrastructure, -like EC2 instances, consider using an instance profile and mapping that -to a Kubernetes RBAC role.

-
-
-
-

7.2.3. Employ least privileged access to AWS Resources

-
-

An IAM User does not need to be assigned privileges to AWS resources to -access the Kubernetes API. If you need to grant an IAM user access to an -EKS cluster, create an entry in the aws-auth ConfigMap for that user -that maps to a specific Kubernetes RBAC group.

-
-
-
-

7.2.4. Remove the cluster-admin permissions from the cluster creator principal

-
-

By default Amazon EKS clusters are created with a permanent -cluster-admin permission bound to the cluster creator principal. -With the Cluster Access Manager API, it’s possible to create clusters -without this permission setting the ---access-config bootstrapClusterCreatorAdminPermissions to -false, when using API_AND_CONFIG_MAP or API authentication -mode. Revoke this access considered a best practice to avoid any -unwanted changes to the cluster configuration. The process to revoke -this access, follows the same process to revoke any other access to the -cluster.

-
-
-

The API gives you flexibility to only disassociate an IAM principal from -an Access Policy, in this case the AmazonEKSClusterAdminPolicy.

-
-
-
-
$ aws eks list-associated-access-policies \
-    --cluster-name <CLUSTER_NAME> \
-    --principal-arn <IAM_PRINCIPAL_ARN>
-
-$ aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \
-    --principal-arn <IAM_PRINCIPAL_ARN. \
-    --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
-
-
-
-

Or completely removing the Access Entry associated with the -cluster-admin permission.

-
-
-
-
$ aws eks list-access-entries --cluster-name <CLUSTER_NAME>
-
-{
-    "accessEntries": []
-}
-
-$ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \
-  --principal-arn <IAM_PRINCIPAL_ARN>
-
-
-
-
-
-

This access can be granted again if needed during an incident, emergency -or break glass scenario where the cluster is otherwise inaccessible.

-
-
-
-
-

If the cluster still configured with the CONFIG_MAP authentication -method, all additional users should be granted access to the cluster -through the aws-auth ConfigMap, and after aws-auth ConfigMap is -configured, the role assigned to the entity that created the cluster, -can be deleted and only recreated in case of an incident, emergency or -break glass scenario, or where the aws-auth ConfigMap is corrupted -and the cluster is otherwise inaccessible. This can be particularly -useful in production clusters.

-
-
-
-

7.2.5. Use IAM Roles when multiple users need identical access to the cluster

-
-

Rather than creating an entry for each individual IAM User, allow those -users to assume an IAM Role and map that role to a Kubernetes RBAC -group. This will be easier to maintain, especially as the number of -users that require access grows.

-
-
-

!!! attention When accessing the EKS cluster with the IAM entity mapped -by aws-auth ConfigMap, the username described is recorded in the -user field of the Kubernetes audit log. If you’re using an IAM role, the -actual users who assume that role aren’t recorded and can’t be audited.

-
-
-

If still using the aws-auth configMap as the authentication method, -when assigning K8s RBAC permissions to an IAM role, you should include -\{{SessionName}} in your username. That way, the audit log will record -the session name so you can track who the actual user assume this role -along with the CloudTrail log.

-
-
-
-
- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole
-  username: testRole:{{SessionName}}
-  groups:
-    - system:masters
-
-
-
-
-
-

In Kubernetes 1.20 and above, this change is no longer required, since -user.extra.sessionName.0 was added to the Kubernetes audit log.

-
-
-
-
-
-

7.2.6. Employ least privileged access when creating RoleBindings and ClusterRoleBindings

-
-

Like the earlier point about granting access to AWS Resources, -RoleBindings and ClusterRoleBindings should only include the set of -permissions necessary to perform a specific function. Avoid using -["*"] in your Roles and ClusterRoles unless it’s absolutely -necessary. If you’re unsure what permissions to assign, consider using a -tool like audit2rbac to -automatically generate Roles and binding based on the observed API calls -in the Kubernetes Audit Log.

-
-
-
-

7.2.7. Create cluster using an automated process

-
-

As seen in earlier steps, when creating an Amazon EKS cluster, if not -using the using API_AND_CONFIG_MAP or API authentication mode, -and not opting out to delegate cluster-admin permissions to the -cluster creator, the IAM entity user or role, such as a federated -user that creates the cluster, is automatically -granted system:masters permissions in the cluster’s RBAC -configuration. Even being a best practice to remove this permission, as -described -here -if using the CONFIG_MAP authentication method, relying on -aws-auth ConfigMap, this access cannot be revoked. Therefore it is a -good idea to create the cluster with an infrastructure automation -pipeline tied to dedicated IAM role, with no permissions to be assumed -by other users or entities and regularly audit this role’s permissions, -policies, and who has access to trigger the pipeline. Also, this role -should not be used to perform routine actions on the cluster, and be -exclusively used to cluster level actions triggered by the pipeline, via -SCM code changes for example.

-
-
-
-

7.2.8. Create the cluster with a dedicated IAM role

-
-

When you create an Amazon EKS cluster, the IAM entity user or role, such -as a federated user that creates the cluster, is automatically -granted system:masters permissions in the cluster’s RBAC -configuration. This access cannot be removed and is not managed through -the aws-auth ConfigMap. Therefore it is a good idea to create the -cluster with a dedicated IAM role and regularly audit who can assume -this role. This role should not be used to perform routine actions on -the cluster, and instead additional users should be granted access to -the cluster through the aws-auth ConfigMap for this purpose. After -the aws-auth ConfigMap is configured, the role should be secured and -only used in temporary elevated privilege mode / break glass for -scenarios where the cluster is otherwise inaccessible. This can be -particularly useful in clusters which do not have direct user access -configured.

-
-
-
-

7.2.9. Regularly audit access to the cluster

-
-

Who requires access is likely to change over time. Plan to periodically -audit the aws-auth ConfigMap to see who has been granted access and -the rights they’ve been assigned. You can also use open source tooling -like kubectl-who-can, -or rbac-lookup to examine -the roles bound to a particular service account, user, or group. We’ll -explore this topic further when we get to the section on -auditing. Additional ideas can be found in this -article -from NCC Group.

-
-
-
-

7.2.10. If relying on aws-auth configMap use tools to make changes

-
-

An improperly formatted aws-auth ConfigMap may cause you to lose access -to the cluster. If you need to make changes to the ConfigMap, use a -tool.

-
-
-

eksctl The eksctl CLI includes a command for adding identity -mappings to the aws-auth ConfigMap.

-
-
-

View CLI Help:

-
-
-
-
$ eksctl create iamidentitymapping --help
-...
-
-
-
-

Check the identities mapped to your Amazon EKS Cluster.

-
-
-
-
$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION
-ARN                                                                   USERNAME                        GROUPS                                                  ACCOUNT
-arn:aws:iam::788355785855:role/kube-system-<SELF_GENERATED_UUID>      system:node:{{SessionName}}     system:bootstrappers,system:nodes,system:node-proxier
-
-
-
-

Make an IAM Role a Cluster Admin:

-
-
-
-
$ eksctl create iamidentitymapping --cluster  <CLUSTER_NAME> --region=<region> --arn arn:aws:iam::123456:role/testing --group system:masters --username admin
-...
-
-
-
-

For more information, review -eksctl docs

-
-
-

aws-auth by keikoproj

-
-
-

aws-auth by keikoproj includes both a cli and a go library.

-
-
-

Download and view help CLI help:

-
-
-
-
$ go get github.com/keikoproj/aws-auth
-...
-$ aws-auth help
-...
-
-
-
-

Alternatively, install aws-auth with the -krew plugin manager for kubectl.

-
-
-
-
$ kubectl krew install aws-auth
-...
-$ kubectl aws-auth
-...
-
-
-
-

Review the -aws-auth docs on GitHub for more information, including the go library.

-
- -
-

The aws-iam-authenticator project includes a CLI for updating the -ConfigMap.

-
-
-

Download -a release on GitHub.

-
-
-

Add cluster permissions to an IAM Role:

-
-
-
-
$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config
-...
-
-
-
-
-

7.2.11. Alternative Approaches to Authentication and Access Management

-
-

While IAM is the preferred way to authenticate users who need access to -an EKS cluster, it is possible to use an OIDC identity provider such as -GitHub using an authentication proxy and Kubernetes -impersonation. -Posts for two such solutions have been published on the AWS Open Source -blog:

-
- -
-

!!! attention EKS natively supports OIDC authentication without using a -proxy. For further information, please read the launch blog, -Introducing -OIDC identity provider authentication for Amazon EKS. For an example -showing how to configure EKS with Dex, a popular open source OIDC -provider with connectors for a variety of different authention methods, -see -Using -Dex & dex-k8s-authenticator to authenticate to Amazon EKS. As described -in the blogs, the username/group of users authenticated by an OIDC -provider will appear in the Kubernetes audit log.

-
-
-

You can also use -AWS -SSO to federate AWS with an external identity provider, e.g. Azure AD. -If you decide to use this, the AWS CLI v2.0 includes an option to create -a named profile that makes it easy to associate an SSO session with your -current CLI session and assume an IAM role. Know that you must assume a -role prior to running kubectl as the IAM role is used to determine -the user’s Kubernetes RBAC group.

-
-
-
-
-

7.3. Identities and Credentials for EKS pods

-
-

Certain applications that run within a Kubernetes cluster need -permission to call the Kubernetes API to function properly. For example, -the AWS -Load Balancer Controller needs to be able to list a Service’s -Endpoints. The controller also needs to be able to invoke AWS APIs to -provision and configure an ALB. In this section we will explore the best -practices for assigning rights and privileges to Pods.

-
-
-

7.3.1. Kubernetes Service Accounts

-
-

A service account is a special type of object that allows you to assign -a Kubernetes RBAC role to a pod. A default service account is created -automatically for each Namespace within a cluster. When you deploy a pod -into a Namespace without referencing a specific service account, the -default service account for that Namespace will automatically get -assigned to the Pod and the Secret, i.e. the service account (JWT) token -for that service account, will get mounted to the pod as a volume at -/var/run/secrets/kubernetes.io/serviceaccount. Decoding the service -account token in that directory will reveal the following metadata:

-
-
-
-
{
-  "iss": "kubernetes/serviceaccount",
-  "kubernetes.io/serviceaccount/namespace": "default",
-  "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z",
-  "kubernetes.io/serviceaccount/service-account.name": "default",
-  "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba",
-  "sub": "system:serviceaccount:default:default"
-}
-
-
-
-

The default service account has the following permissions to the -Kubernetes API.

-
-
-
-
apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
-  annotations:
-    rbac.authorization.kubernetes.io/autoupdate: "true"
-  creationTimestamp: "2020-01-30T18:13:25Z"
-  labels:
-    kubernetes.io/bootstrapping: rbac-defaults
-  name: system:discovery
-  resourceVersion: "43"
-  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery
-  uid: 350d2ab8-438c-11ea-9438-063a49b60fba
-rules:
-- nonResourceURLs:
-  - /api
-  - /api/*
-  - /apis
-  - /apis/*
-  - /healthz
-  - /openapi
-  - /openapi/*
-  - /version
-  - /version/
-  verbs:
-  - get
-
-
-
-

This role authorizes unauthenticated and authenticated users to read API -information and is deemed safe to be publicly accessible.

-
-
-

When an application running within a Pod calls the Kubernetes APIs, the -Pod needs to be assigned a service account that explicitly grants it -permission to call those APIs. Similar to guidelines for user access, -the Role or ClusterRole bound to a service account should be restricted -to the API resources and methods that the application needs to function -and nothing else. To use a non-default service account simply set the -spec.serviceAccountName field of a Pod to the name of the service -account you wish to use. For additional information about creating -service accounts, see -https://kubernetes.io/docs/reference/access-authn-authz/rbac/#service-account-permissions.

-
-
-

!!! note Prior to Kubernetes 1.24, Kubernetes would automatically create -a secret for each a service account. This secret was mounted to the pod -at /var/run/secrets/kubernetes.io/serviceaccount and would be used by -the pod to authenticate to the Kubernetes API server. In Kubernetes -1.24, a service account token is dynamically generated when the pod runs -and is only valid for an hour by default. A secret for the service -account will not be created. If you have an application that runs -outside the cluster that needs to authenticate to the Kubernetes API, -e.g. Jenkins, you will need to create a secret of type -kubernetes.io/service-account-token along with an annotation that -references the service account such as -metadata.annotations.kubernetes.io/service-account.name: <SERVICE_ACCOUNT_NAME>. -Secrets created in this way do not expire.

-
-
-
-

7.3.2. IAM Roles for Service Accounts (IRSA)

-
-

IRSA is a feature that allows you to assign an IAM role to a Kubernetes -service account. It works by leveraging a Kubernetes feature known as -Service -Account Token Volume Projection. When Pods are configured with a -Service Account that references an IAM Role, the Kubernetes API server -will call the public OIDC discovery endpoint for the cluster on startup. -The endpoint cryptographically signs the OIDC token issued by Kubernetes -and the resulting token mounted as a volume. This signed token allows -the Pod to call the AWS APIs associated IAM role. When an AWS API is -invoked, the AWS SDKs calls sts:AssumeRoleWithWebIdentity. After -validating the token’s signature, IAM exchanges the Kubernetes issued -token for a temporary AWS role credential.

-
-
-

When using IRSA, it is important to -reuse AWS SDK sessions to avoid -unneeded calls to AWS STS.

-
-
-

Decoding the (JWT) token for IRSA will produce output similar to the -example you see below:

-
-
-
-
{
-  "aud": [
-    "sts.amazonaws.com"
-  ],
-  "exp": 1582306514,
-  "iat": 1582220114,
-  "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128",
-  "kubernetes.io": {
-    "namespace": "default",
-    "pod": {
-      "name": "alpine-57b5664646-rf966",
-      "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436"
-    },
-    "serviceaccount": {
-      "name": "s3-read-only",
-      "uid": "a720ba5c-5406-11ea-9438-063a49b60fba"
-    }
-  },
-  "nbf": 1582220114,
-  "sub": "system:serviceaccount:default:s3-read-only"
-}
-
-
-
-

This particular token grants the Pod view-only privileges to S3 by -assuming an IAM role. When the application attempts to read from S3, the -token is exchanged for a temporary set of IAM credentials that resembles -this:

-
-
-
-
{
-    "AssumedRoleUser": {
-        "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc",
-        "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc"
-    },
-    "Audience": "sts.amazonaws.com",
-    "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128",
-    "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only",
-    "Credentials": {
-        "SecretAccessKey": "ORJ+8Adk+wW+nU8FETq7+mOqeA8Z6jlPihnV8hX1",
-        "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oes+l1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZe+uE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0H+bi/PWAtlI8YJcDX69cM30JAHDdQH+ltm/4scFptW1hlvMaP+WReCAaCrsHrAT+yka7ttw5YlUyvZ8EPog+j6fwHlxmrXM9h1BqdikomyJU00gm1++FJelfP+1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkW+sCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZG+CkyDLIa8MBn9KPXeJd/y+jTk5Ii+fIwO/+mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVC+M+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=",
-        "Expiration": "2020-02-20T18:49:50Z",
-        "AccessKeyId": "XXXX36C6WWEJUMHA3L7Z"
-    }
-}
-
-
-
-

A mutating webhook that runs as part of the EKS control plane injects -the AWS Role ARN and the path to a web identity token file into the Pod -as environment variables. These values can also be supplied manually.

-
-
-
-
AWS_ROLE_ARN=arn:aws:iam::AWS_ACCOUNT_ID:role/IAM_ROLE_NAME
-AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
-
-
-
-

The kubelet will automatically rotate the projected token when it is -older than 80% of its total TTL, or after 24 hours. The AWS SDKs are -responsible for reloading the token when it rotates. For further -information about IRSA, see -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html.

-
-
-
-

7.3.3. EKS Pod Identities

-
-

EKS -Pod Identities is a feature launched at re:Invent 2023 that allows you -to assign an IAM role to a kubernetes service account, without the need -to configure an Open Id Connect (OIDC) identity provider(IDP) for each -cluster in your AWS account. To use EKS Pod Identity, you must deploy an -agent which runs as a DaemonSet pod on every eligible worker node. This -agent is made available to you as an EKS Add-on and is a pre-requisite -to use EKS Pod Identity feature. Your applications must use a -supported -version of the AWS SDK to use this feature.

-
-
-

When EKS Pod Identities are configured for a Pod, EKS will mount and -refresh a pod identity token at -/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token. -This token will be used by the AWS SDK to communicate with the EKS Pod -Identity Agent, which uses the pod identity token and the agent’s IAM -role to create temporary credentials for your pods by calling the -AssumeRoleForPodIdentity -API. The pod identity token delivered to your pods is a JWT issued from -your EKS cluster and cryptographically signed, with appropriate JWT -claims for use with EKS Pod Identities.

-
-
-

To learn more about EKS Pod Identities, please see -this -blog.

-
-
-

You do not have to make any modifications to your application code to -use EKS Pod Identities. Supported AWS SDK versions will automatically -discover credentials made available with EKS Pod Identities by using the -credential -provider chain. Like IRSA, EKS pod identities sets variables within -your pods to direct them how to find AWS credentials.

-
-
-
Working with IAM roles for EKS Pod Identities
-
-
    -
  • -

    EKS Pod Identities can only directly assume an IAM role that belongs -to the same AWS account as the EKS cluster. To access an IAM role in -another AWS account, you must assume that role by -configuring -a profile in your SDK configuration, or in your -application’s -code.

    -
  • -
  • -

    When EKS Pod Identities are being configured for Service Accounts, the -person or process configuring the Pod Identity Association must have the -iam:PassRole entitlement for that role.

    -
  • -
  • -

    Each Service Account may only have one IAM role associated with it -through EKS Pod Identities, however you can associate the same IAM role -with multiple service accounts.

    -
  • -
  • -

    IAM roles used with EKS Pod Identities must allow the -pods.eks.amazonaws.com Service Principal to assume them, and set -session tags. The following is an example role trust policy which allows -EKS Pod Identities to use an IAM role:

    -
  • -
-
-
-
-
{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Principal": {
-        "Service": "pods.eks.amazonaws.com"
-      },
-      "Action": [
-        "sts:AssumeRole",
-        "sts:TagSession"
-      ],
-      "Condition": {
-        "StringEquals": {
-          "aws:SourceOrgId": "${aws:ResourceOrgId}"
-        }
-      }
-    }
-  ]
-}
-
-
-
-

AWS recommends using condition keys like aws:SourceOrgId to help -protect against the -cross-service -confused deputy problem. In the above example role trust policy, the -ResourceOrgId is a variable equal to the AWS Organizations -Organization ID of the AWS Organization that the AWS account belongs to. -EKS will pass in a value for aws:SourceOrgId equal to that when -assuming a role with EKS Pod Identities.

-
-
-
-
ABAC and EKS Pod Identities
-
-

When EKS Pod Identities assumes an IAM role, it sets the following -session tags:

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EKS Pod Identities Session TagValue

kubernetes-namespace

The namespace the pod associated with EKS Pod -Identities runs in.

kubernetes-service-account

The name of the kubernetes service account -associated with EKS Pod Identities

eks-cluster-arn

The ARN of the EKS cluster, -e.g. arn:${Partition}:eks:${Region}:${Account}:cluster/${ClusterName}. -The cluster ARN is unique, but if a cluster is deleted and recreated in -the same region with the same name, within the same AWS account, it will -have the same ARN.

eks-cluster-name

The name of the EKS cluster. Please note that EKS -cluster names can be same within your AWS account, and EKS clusters in -other AWS accounts.

kubernetes-pod-name

The name of the pod in EKS.

kubernetes-pod-uid

The UID of the pod in EKS.

-
-

These session tags allow you to use -Attribute -Based Access Control(ABAC) to grant access to your AWS resources to -only specific kubernetes service accounts. When doing so, it is very -important to understand that kubernetes service accounts are only -unique within a namespace, and kubernetes namespaces are only unique -within an EKS cluster. These session tags can be accessed in AWS -policies by using the aws:PrincipalTag/<tag-key> global condition -key, such as aws:PrincipalTag/eks-cluster-arn

-
-
-

For example, if you wanted to grant access to only a specific service -account to access an AWS resource in your account with an IAM or -resource policy, you would need to check eks-cluster-arn and -kubernetes-namespace tags as well as the -kubernetes-service-account to ensure that only that service accounts -from the intended cluster have access to that resource as other clusters -could have identical kubernetes-service-accounts and -kubernetes-namespaces.

-
-
-

This example S3 Bucket policy only grants access to objects in the S3 -bucket it’s attached to, only if kubernetes-service-account, -kubernetes-namespace, eks-cluster-arn all meet their expected -values, where the EKS cluster is hosted in the AWS account -111122223333.

-
-
-
-
{
-    "Version": "2012-10-17",
-    "Statement": [
-        {
-            "Effect": "Allow",
-            "Principal": {
-                "AWS": "arn:aws:iam::111122223333:root"
-            },
-            "Action": "s3:*",
-            "Resource":            [
-                "arn:aws:s3:::ExampleBucket/*"
-            ],
-            "Condition": {
-                "StringEquals": {
-                    "aws:PrincipalTag/kubernetes-service-account": "s3objectservice",
-                    "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster",
-                    "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace"
-                }
-            }
-        }
-    ]
-}
-
-
-
-
-
-

7.3.4. EKS Pod Identities compared to IRSA

-
-

Both EKS Pod Identities and IRSA are preferred ways to deliver temporary -AWS credentials to your EKS pods. Unless you have specific usecases for -IRSA, we recommend you use EKS Pod Identities when using EKS. This table -helps compare the two features.

-
- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#EKS Pod IdentitiesIRSA

Requires permission to create an OIDC IDP in your AWS accounts?

No

Yes

Requires unique IDP setup per cluster

No

Yes

Sets relevant session tags for use with ABAC

Yes

No

Requires an iam:PassRole Check?

Yes

No

Uses AWS STS Quota from your AWS account?

No

Yes

Can access other AWS accounts

Indirectly with role chaining

Directly -with sts:AssumeRoleWithWebIdentity

Compatible with AWS SDKs

Yes

Yes

Requires Pod Identity Agent Daemonset on nodes?

Yes

No

-
-
-
-

7.4. Identities and Credentials for EKS pods Recommendations

-
-

7.4.1. Update the aws-node daemonset to use IRSA

-
-

At present, the aws-node daemonset is configured to use a role assigned -to the EC2 instances to assign IPs to pods. This role includes several -AWS managed policies, e.g. AmazonEKS_CNI_Policy and -EC2ContainerRegistryReadOnly that effectively allow all pods running -on a node to attach/detach ENIs, assign/unassign IP addresses, or pull -images from ECR. Since this presents a risk to your cluster, it is -recommended that you update the aws-node daemonset to use IRSA. A script -for doing this can be found in the -repository -for this guide.

-
-
-

The aws-node daemonset does not support EKS Pod Identities at this time.

-
-
-
-

7.4.2. Restrict access to the instance profile assigned to the worker node

-
-

When you use IRSA or EKS Pod Identities, it updates the credential chain -of the pod to use IRSA or EKS Pod Identities first, however, the pod -can still inherit the rights of the instance profile assigned to the -worker node. When using IRSA or EKS Pod Identities, it is strongly -recommended that you block access -instance -metadata to help ensure that your applications only have the -permissions they require, and not their nodes.

-
-
-

!!! caution Blocking access to instance metadata will prevent pods that -do not use IRSA or EKS Pod Identities from inheriting the role assigned -to the worker node.

-
-
-

You can block access to instance metadata by requiring the instance to -use IMDSv2 only and updating the hop count to 1 as in the example below. -You can also include these settings in the node group’s launch template. -Do not disable instance metadata as this will prevent components like -the node termination handler and other things that rely on instance -metadata from working properly.

-
-
-
-
$ aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1
-...
-
-
-
-

If you are using Terraform to create launch templates for use with -Managed Node Groups, add the metadata block to configure the hop count -as seen in this code snippet:

-
-
-

tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" ... metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } ...

-
-
-

You can also block a pod’s access to EC2 metadata by manipulating -iptables on the node. For further information about this method, see -Limiting -access to the instance metadata service.

-
-
-

If you have an application that is using an older version of the AWS SDK -that doesn’t support IRSA or EKS Pod Identities, you should update the -SDK version.

-
-
-
-

7.4.3. Scope the IAM Role trust policy for IRSA Roles to the service account name, namespace, and cluster

-
-

The trust policy can be scoped to a Namespace or a specific service -account within a Namespace. When using IRSA it’s best to make the role -trust policy as explicit as possible by including the service account -name. This will effectively prevent other Pods within the same Namespace -from assuming the role. The CLI eksctl will do this automatically -when you use it to create service accounts/IAM roles. See -https://eksctl.io/usage/iamserviceaccounts/ for further information.

-
-
-

When working with IAM directly, this is adding condition into the role’s -trust policy that uses conditions to ensure the :sub claim are the -namespace and service account you expect. As an example, before we had -an IRSA token with a sub claim of -“system:serviceaccount:default:s3-read-only” . This is the default -namespace and the service account is s3-read-only. You would use a -condition like the following to ensure that only your service account in -a given namespace from your cluster can assume that role:

-
-
-
-
  "Condition": {
-      "StringEquals": {
-          "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com",
-          "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only"
-      }
-  }
-
-
-
-
-

7.4.4. Use one IAM role per application

-
-

With both IRSA and EKS Pod Identity, it is a best practice to give each -application its own IAM role. This gives you improved isolation as you -can modify one application without impacting another, and allows you to -apply the principal of least privilege by only granting an application -the permissions it needs.

-
-
-

When using ABAC with EKS Pod Identity, you may use a common IAM role -across multiple service accounts and rely on their session attributes -for access control. This is especially useful when operating at scale, -as ABAC allows you to operate with fewer IAM roles.

-
-
-
-

7.4.5. When your application needs access to IMDS, use IMDSv2 and increase the hop limit on EC2 instances to 2

-
-

IMDSv2 -requires you use a PUT request to get a session token. The initial PUT -request has to include a TTL for the session token. Newer versions of -the AWS SDKs will handle this and the renewal of said token -automatically. It’s also important to be aware that the default hop -limit on EC2 instances is intentionally set to 1 to prevent IP -forwarding. As a consequence, Pods that request a session token that are -run on EC2 instances may eventually time out and fallback to using the -IMDSv1 data flow. EKS adds support IMDSv2 by enabling both v1 and v2 -and changing the hop limit to 2 on nodes provisioned by eksctl or with -the official CloudFormation templates.

-
-
-
-

7.4.6. Disable auto-mounting of service account tokens

-
-

If your application doesn’t need to call the Kubernetes API set the -automountServiceAccountToken attribute to false in the PodSpec -for your application or patch the default service account in each -namespace so that it’s no longer mounted to pods automatically. For -example:

-
-
-
-
kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'
-
-
-
-
-

7.4.7. Use dedicated service accounts for each application

-
-

Each application should have its own dedicated service account. This -applies to service accounts for the Kubernetes API as well as IRSA and -EKS Pod Identity.

-
-
-

!!! attention If you employ a blue/green approach to cluster upgrades -instead of performing an in-place cluster upgrade when using IRSA, you -will need to update the trust policy of each of the IRSA IAM roles with -the OIDC endpoint of the new cluster. A blue/green cluster upgrade is -where you create a cluster running a newer version of Kubernetes -alongside the old cluster and use a load balancer or a service mesh to -seamlessly shift traffic from services running on the old cluster to the -new cluster. When using blue/green cluster upgrades with EKS Pod -Identity, you would create pod identity associations between the IAM -roles and service accounts in the new cluster. And update the IAM role -trust policy if you have a sourceArn condition.

-
-
-
-

7.4.8. Run the application as a non-root user

-
-

Containers run as root by default. While this allows them to read the -web identity token file, running a container as root is not considered a -best practice. As an alternative, consider adding the -spec.securityContext.runAsUser attribute to the PodSpec. The value -of runAsUser is arbitrary value.

-
-
-

In the following example, all processes within the Pod will run under -the user ID specified in the runAsUser field.

-
-
-
-
apiVersion: v1
-kind: Pod
-metadata:
-  name: security-context-demo
-spec:
-  securityContext:
-    runAsUser: 1000
-    runAsGroup: 3000
-  containers:
-  - name: sec-ctx-demo
-    image: busybox
-    command: [ "sh", "-c", "sleep 1h" ]
-
-
-
-

When you run a container as a non-root user, it prevents the container -from reading the IRSA service account token because the token is -assigned 0600 [root] permissions by default. If you update the -securityContext for your container to include fsgroup=65534 [Nobody] it -will allow the container to read the token.

-
-
-
-
spec:
-  securityContext:
-    fsGroup: 65534
-
-
-
-

In Kubernetes 1.19 and above, this change is no longer required and -applications can read the IRSA service account token without adding them -to the Nobody group.

-
-
-
-

7.4.9. Grant least privileged access to applications

-
-

Action Hero is a utility -that you can run alongside your application to identify the AWS API -calls and corresponding IAM permissions your application needs to -function properly. It is similar to -IAM -Access Advisor in that it helps you gradually limit the scope of IAM -roles assigned to applications. Consult the documentation on granting -least -privileged access to AWS resources for further information.

-
-
-

Consider setting a -permissions -boundary on IAM roles used with IRSA and Pod Identities. You can use -the permissions boundary to ensure that the roles used by IRSA or Pod -Identities can not exceed a maximum level of permissions. For an example -guide on getting started with permissions boundaries with an example -permissions boundary policy, please see this -github -repo.

-
-
-
-

7.4.10. Review and revoke unnecessary anonymous access to your EKS cluster

-
-

Ideally anonymous access should be disabled for all API actions. -Anonymous access is granted by creating a RoleBinding or -ClusterRoleBinding for the Kubernetes built-in user system:anonymous. -You can use the rbac-lookup -tool to identify permissions that system:anonymous user has on your -cluster:

-
-
-
-
./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)'
-system:anonymous               cluster-wide        ClusterRole/system:discovery
-system:unauthenticated         cluster-wide        ClusterRole/system:discovery
-system:unauthenticated         cluster-wide        ClusterRole/system:public-info-viewer
-
-
-
-

Any role or ClusterRole other than system:public-info-viewer should not -be bound to system:anonymous user or system:unauthenticated group.

-
-
-

There may be some legitimate reasons to enable anonymous access on -specific APIs. If this is the case for your cluster ensure that only -those specific APIs are accessible by anonymous user and exposing those -APIs without authentication doesn’t make your cluster vulnerable.

-
-
-

Prior to Kubernetes/EKS Version 1.14, system:unauthenticated group was -associated to system:discovery and system:basic-user ClusterRoles by -default. Note that even if you have updated your cluster to version 1.14 -or higher, these permissions may still be enabled on your cluster, since -cluster updates do not revoke these permissions. To check which -ClusterRoles have “system:unauthenticated” except -system:public-info-viewer you can run the following command (requires jq -util):

-
-
-
-
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name'
-
-
-
-

And “system:unauthenticated” can be removed from all the roles except -“system:public-info-viewer” using:

-
-
-
-
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f -
-
-
-
-

Alternatively, you can check and remove it manually by kubectl describe -and kubectl edit. To check if system:unauthenticated group has -system:discovery permissions on your cluster run the following command:

-
-
-
-
kubectl describe clusterrolebindings system:discovery
-
-Name:         system:discovery
-Labels:       kubernetes.io/bootstrapping=rbac-defaults
-Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
-Role:
-  Kind:  ClusterRole
-  Name:  system:discovery
-Subjects:
-  Kind   Name                    Namespace
-  ----   ----                    ---------
-  Group  system:authenticated
-  Group  system:unauthenticated
-
-
-
-

To check if system:unauthenticated group has system:basic-user -permission on your cluster run the following command:

-
-
-
-
kubectl describe clusterrolebindings system:basic-user
-
-Name:         system:basic-user
-Labels:       kubernetes.io/bootstrapping=rbac-defaults
-Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
-Role:
-  Kind:  ClusterRole
-  Name:  system:basic-user
-Subjects:
-  Kind   Name                    Namespace
-  ----   ----                    ---------
-  Group  system:authenticated
-  Group  system:unauthenticated
-
-
-
-

If system:unauthenticated group is bound to system:discovery and/or -system:basic-user ClusterRoles on your cluster, you should disassociate -these roles from system:unauthenticated group. Edit system:discovery -ClusterRoleBinding using the following command:

-
-
-
-
kubectl edit clusterrolebindings system:discovery
-
-
-
-

The above command will open the current definition of system:discovery -ClusterRoleBinding in an editor as shown below:

-
-
-
-
# Please edit the object below. Lines beginning with a '#' will be ignored,
-# and an empty file will abort the edit. If an error occurs while saving this file will be
-# reopened with the relevant failures.
-#
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
-  annotations:
-    rbac.authorization.kubernetes.io/autoupdate: "true"
-  creationTimestamp: "2021-06-17T20:50:49Z"
-  labels:
-    kubernetes.io/bootstrapping: rbac-defaults
-  name: system:discovery
-  resourceVersion: "24502985"
-  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery
-  uid: b7936268-5043-431a-a0e1-171a423abeb6
-roleRef:
-  apiGroup: rbac.authorization.k8s.io
-  kind: ClusterRole
-  name: system:discovery
-subjects:
-- apiGroup: rbac.authorization.k8s.io
-  kind: Group
-  name: system:authenticated
-- apiGroup: rbac.authorization.k8s.io
-  kind: Group
-  name: system:unauthenticated
-
-
-
-

Delete the entry for system:unauthenticated group from the “subjects” -section in the above editor screen.

-
-
-

Repeat the same steps for system:basic-user ClusterRoleBinding.

-
-
-
-

7.4.11. Reuse AWS SDK sessions with IRSA

-
-

When you use IRSA, applications written using the AWS SDK use the token -delivered to your pods to call sts:AssumeRoleWithWebIdentity to -generate temporary AWS credentials. This is different from other AWS -compute services, where the compute service delivers temporary AWS -credentials directly to the AWS compute resource, such as a lambda -function. This means that every time an AWS SDK session is initialized, -a call to AWS STS for AssumeRoleWithWebIdentity is made. If your -application scales rapidly and initializes many AWS SDK sessions, you -may experience throttling from AWS STS as your code will be making many -calls for AssumeRoleWithWebIdentity.

-
-
-

To avoid this scenario, we recommend reusing AWS SDK sessions within -your application so that unnecessary calls to -AssumeRoleWithWebIdentity are not made.

-
-
-

In the following example code, a session is created using the boto3 -python SDK, and that same session is used to create clients and interact -with both Amazon S3 and Amazon SQS. AssumeRoleWithWebIdentity is -only called once, and the AWS SDK will refresh the credentials of -my_session when they expire automatically.

-
-
-
-
import boto3
-
-= Create your own session
-
-my_session = boto3.session.Session()
-
-= Now we can create low-level clients from our session
-
-sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`')
-
-s3response = s3.list_buckets() sqsresponse = sqs.list_queues()
-
-#print the response from the S3 and SQS APIs print("`s3 response:`")
-print(s3response) print("`—`") print("`sqs response:`")
-print(sqsresponse) ```
-
-
-
-

If you’re migrating an application from another AWS compute service, -such as EC2, to EKS with IRSA, this is a particularly important detail. -On other compute services initializing an AWS SDK session does not call -AWS STS unless you instruct it to.

-
-
-
-

7.4.12. Alternative approaches

-
-

While IRSA and EKS Pod Identities are the preferred ways to assign an -AWS identity to a pod, they require that you include recent version of -the AWS SDKs in your application. For a complete listing of the SDKs -that currently support IRSA, see -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html, -for EKS Pod Identities, see -https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html. -If you have an application that you can’t immediately update with a -compatible SDK, there are several community-built solutions available -for assigning IAM roles to Kubernetes pods, including -kube2iam and -kiam. Although AWS doesn’t endorse, -condone, nor support the use of these solutions, they are frequently -used by the community at large to achieve similar results as IRSA and -EKS Pod Identities.

-
-
-

If you need to use one of these non-aws provided solutions, please -exercise due diligence and ensure you understand security implications -of doing so.

-
-
-
- -
-
-
-

8. Pod Security

-
-
-

The pod specification includes a variety of different attributes that -can strengthen or weaken your overall security posture. As a Kubernetes -practitioner your chief concern should be preventing a process that’s -running in a container from escaping the isolation boundaries of the -container runtime and gaining access to the underlying host.

-
-
-

8.1. Linux Capabilities

-
-

The processes that run within a container run under the context of the -[Linux] root user by default. Although the actions of root within a -container are partially constrained by the set of Linux capabilities -that the container runtime assigns to the containers, these default -privileges could allow an attacker to escalate their privileges and/or -gain access to sensitive information bound to the host, including -Secrets and ConfigMaps. Below is a list of the default capabilities -assigned to containers. For additional information about each -capability, see -http://man7.org/linux/man-pages/man7/capabilities.7.html.

-
-
-

CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT

-
-
-

!!! Info

-
-
-

EC2 and Fargate pods are assigned the aforementioned capabilities by -default. Additionally, Linux capabilities can only be dropped from -Fargate pods.

-
-
-

Pods that are run as privileged, inherit all of the Linux capabilities -associated with root on the host. This should be avoided if possible.

-
-
-

8.1.1. Node Authorization

-
-

All Kubernetes worker nodes use an authorization mode called -Node -Authorization. Node Authorization authorizes all API requests that -originate from the kubelet and allows nodes to perform the following -actions:

-
-
-

Read operations:

-
-
-
    -
  • -

    services

    -
  • -
  • -

    endpoints

    -
  • -
  • -

    nodes

    -
  • -
  • -

    pods

    -
  • -
  • -

    secrets, configmaps, persistent volume claims and persistent volumes -related to pods bound to the kubelet’s node

    -
  • -
-
-
-

Write operations:

-
-
-
    -
  • -

    nodes and node status (enable the NodeRestriction admission plugin -to limit a kubelet to modify its own node)

    -
  • -
  • -

    pods and pod status (enable the NodeRestriction admission plugin -to limit a kubelet to modify pods bound to itself)

    -
  • -
  • -

    events

    -
  • -
-
-
-

Auth-related operations:

-
-
-
    -
  • -

    Read/write access to the CertificateSigningRequest (CSR) API for TLS -bootstrapping

    -
  • -
  • -

    the ability to create TokenReview and SubjectAccessReview for -delegated authentication/authorization checks

    -
  • -
-
-
-

EKS uses the -node -restriction admission controller which only allows the node to modify a -limited set of node attributes and pod objects that are bound to the -node. Nevertheless, an attacker who manages to get access to the host -will still be able to glean sensitive information about the environment -from the Kubernetes API that could allow them to move laterally within -the cluster.

-
-
-
-
-

8.2. Pod Security Solutions

-
-

8.2.1. Pod Security Policy (PSP)

-
-

In the past, -Pod -Security Policy (PSP) resources were used to specify a set of -requirements that pods had to meet before they could be created. As of -Kubernetes version 1.21, PSP have been deprecated. They are scheduled -for removal in Kubernetes version 1.25.

-
-
-

!!! Attention

-
-
-

PSPs -are deprecated in Kubernetes version 1.21. You will have until version -1.25 or roughly 2 years to transition to an alternative. This -document -explains the motivation for this deprecation.

-
-
-
-

8.2.2. Migrating to a new pod security solution

-
-

Since PSPs have been removed as of Kubernetes v1.25, cluster -administrators and operators must replace those security controls. Two -solutions can fill this need:

-
-
- -
-
-

Both the PAC and PSS solutions can coexist with PSP; they can be used in -clusters before PSP is removed. This eases adoption when migrating from -PSP. Please see this -document -when considering migrating from PSP to PSS.

-
-
-

Kyverno, one of the PAC solutions outlined below, has specific guidance -outlined in a -blog -post when migrating from PSPs to its solution including analogous -policies, feature comparisons, and a migration procedure. Additional -information and guidance on migration to Kyverno with respect to Pod -Security Admission (PSA) has been published on the AWS blog -here.

-
-
-
-

8.2.3. Policy-as-code (PAC)

-
-

Policy-as-code (PAC) solutions provide guardrails to guide cluster -users, and prevent unwanted behaviors, through prescribed and automated -controls. PAC uses -Kubernetes -Dynamic Admission Controllers to intercept the Kubernetes API server -request flow, via a webhook call, and mutate and validate request -payloads, based on policies written and stored as code. Mutation and -validation happens before the API server request results in a change to -the cluster. PAC solutions use policies to match and act on API server -request payloads, based on taxonomy and values.

-
-
-

There are several open source PAC solutions available for Kubernetes. -These solutions are not part of the Kubernetes project; they are sourced -from the Kubernetes ecosystem. Some PAC solutions are listed below.

-
- -
-

For further information about PAC solutions and how to help you select -the appropriate solution for your needs, see the links below.

-
- -
-
-

8.2.4. Pod Security Standards (PSS) and Pod Security Admission (PSA)

-
-

In response to the PSP deprecation and the ongoing need to control pod -security out-of-the-box, with a built-in Kubernetes solution, the -Kubernetes -Auth -Special Interest Group created the -Pod -Security Standards (PSS) and -Pod -Security Admission (PSA). The PSA effort includes an -admission -controller webhook project that implements the controls defined in the -PSS. This admission controller approach resembles that used in the PAC -solutions.

-
-
-

According to the Kubernetes documentation, the PSS "`define three -different policies to broadly cover the security spectrum. These -policies are cumulative and range from highly-permissive to -highly-restrictive.`"

-
-
-

These policies are defined as:

-
-
-
    -
  • -

    Privileged: Unrestricted (unsecure) policy, providing the widest -possible level of permissions. This policy allows for known privilege -escalations. It is the absence of a policy. This is good for -applications such as logging agents, CNIs, storage drivers, and other -system wide applications that need privileged access.

    -
  • -
  • -

    Baseline: Minimally restrictive policy which prevents known -privilege escalations. Allows the default (minimally specified) Pod -configuration. The baseline policy prohibits use of hostNetwork, -hostPID, hostIPC, hostPath, hostPort, the inability to add Linux -capabilities, along with several other restrictions.

    -
  • -
  • -

    Restricted: Heavily restricted policy, following current Pod -hardening best practices. This policy inherits from the baseline and -adds further restrictions such as the inability to run as root or a -root-group. Restricted policies may impact an application’s ability to -function. They are primarily targeted at running security critical -applications.

    -
  • -
-
-
-

These policies define -profiles -for pod execution, arranged into three levels of privileged -vs. restricted access.

-
-
-

To implement the controls defined by the PSS, PSA operates in three -modes:

-
-
-
    -
  • -

    enforce: Policy violations will cause the pod to be rejected.

    -
  • -
  • -

    audit: Policy violations will trigger the addition of an audit -annotation to the event recorded in the audit log, but are otherwise -allowed.

    -
  • -
  • -

    warn: Policy violations will trigger a user-facing warning, but are -otherwise allowed.

    -
  • -
-
-
-

These modes and the profile (restriction) levels are configured at the -Kubernetes Namespace level, using labels, as seen in the below example.

-
-
-
-
apiVersion: v1
-kind: Namespace
-metadata:
-  name: policy-test
-  labels:
-    pod-security.kubernetes.io/enforce: restricted
-
-
-
-

When used independently, these operational modes have different -responses that result in different user experiences. The enforce mode -will prevent pods from being created if respective podSpecs violate the -configured restriction level. However, in this mode, non-pod Kubernetes -objects that create pods, such as Deployments, will not be prevented -from being applied to the cluster, even if the podSpec therein violates -the applied PSS. In this case the Deployment will be applied, while the -pod(s) will be prevented from being applied.

-
-
-

This is a difficult user experience, as there is no immediate indication -that the successfully applied Deployment object belies failed pod -creation. The offending podSpecs will not create pods. Inspecting the -Deployment resource with kubectl get deploy <DEPLOYMENT_NAME> -oyaml -will expose the message from the failed pod(s) .status.conditions -element, as seen below.

-
-
-
-
...
-status:
-  conditions:
-    - lastTransitionTime: "2022-01-20T01:02:08Z"
-      lastUpdateTime: "2022-01-20T01:02:08Z"
-      message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest":
-        allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false),
-        unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]),
-        runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true),
-        seccompProfile (pod or container "test" must set securityContext.seccompProfile.type
-        to "RuntimeDefault" or "Localhost")'
-      reason: FailedCreate
-      status: "True"
-      type: ReplicaFailure
-...
-
-
-
-

In both the audit and warn modes, the pod restrictions do not -prevent violating pods from being created and started. However, in these -modes audit annotations on API server audit log events and warnings to -API server clients, such as kubectl, are triggered, respectively, when -pods, as well as objects that create pods, contain podSpecs with -violations. A kubectl Warning message is seen below.

-
-
-
-
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
-deployment.apps/test created
-
-
-
-

The PSA audit and warn modes are useful when introducing the PSS -without negatively impacting cluster operations.

-
-
-

The PSA operational modes are not mutually exclusive, and can be used in -a cumulative manner. As seen below, the multiple modes can be configured -in a single namespace.

-
-
-
-
apiVersion: v1
-kind: Namespace
-metadata:
-  name: policy-test
-  labels:
-    pod-security.kubernetes.io/audit: restricted
-    pod-security.kubernetes.io/enforce: restricted
-    pod-security.kubernetes.io/warn: restricted
-
-
-
-

In the above example, the user-friendly warnings and audit annotations -are provided when applying Deployments, while the enforce of violations -are also provided at the pod level. In fact multiple PSA labels can use -different profile levels, as seen below.

-
-
-
-
apiVersion: v1
-kind: Namespace
-metadata:
-  name: policy-test
-  labels:
-    pod-security.kubernetes.io/enforce: baseline
-    pod-security.kubernetes.io/warn: restricted
-
-
-
-

In the above example, PSA is configured to allow the creation of all -pods that satisfy the baseline profile level, and then warn on pods -(and objects that create pods) that violate the restricted profile -level. This is a useful approach to determine the possible impacts when -changing from the baseline to restricted profiles.

-
-
-
Existing Pods
-
-

If a namespace with existing pods is modified to use a more restrictive -PSS profile, the audit and warn modes will produce appropriate -messages; however, enforce mode will not delete the pods. The warning -messages are seen below.

-
-
-
-
Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest"
-Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
-namespace/policy-test configured
-
-
-
-
-
Exemptions
-
-

PSA uses Exemptions to exclude enforcement of violations against pods -that would have otherwise been applied. These exemptions are listed -below.

-
-
-
    -
  • -

    Usernames: requests from users with an exempt authenticated (or -impersonated) username are ignored.

    -
  • -
  • -

    RuntimeClassNames: pods and workload resources specifying an exempt -runtime class name are ignored.

    -
  • -
  • -

    Namespaces: pods and workload resources in an exempt namespace are -ignored.

    -
  • -
-
-
-

These exemptions are applied statically in the -PSA -admission controller configuration as part of the API server -configuration.

-
-
-

In the Validating Webhook implementation the exemptions can be -configured within a Kubernetes -ConfigMap -resource that gets mounted as a volume into the -pod-security-webhook -container.

-
-
-
-
apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: pod-security-webhook
-  namespace: pod-security-webhook
-data:
-  podsecurityconfiguration.yaml: |
-    apiVersion: pod-security.admission.config.k8s.io/v1
-    kind: PodSecurityConfiguration
-    defaults:
-      enforce: "restricted"
-      enforce-version: "latest"
-      audit: "restricted"
-      audit-version: "latest"
-      warn: "restricted"
-      warn-version: "latest"
-    exemptions:
-      # Array of authenticated usernames to exempt.
-      usernames: []
-      # Array of runtime class names to exempt.
-      runtimeClasses: []
-      # Array of namespaces to exempt.
-      namespaces: ["kube-system","policy-test1"]
-
-
-
-

As seen in the above ConfigMap YAML the cluster-wide default PSS level -has been set to restricted for all PSA modes, audit, enforce, and -warn. This affects all namespaces, except those exempted: -namespaces: ["kube-system","policy-test1"]. Additionally, in the -ValidatingWebhookConfiguration resource, seen below, the -pod-security-webhook namespace is also exempted from configured PSS.

-
-
-
-
...
-webhooks:
-  # Audit annotations will be prefixed with this name
-  - name: "pod-security-webhook.kubernetes.io"
-    # Fail-closed admission webhooks can present operational challenges.
-    # You may want to consider using a failure policy of Ignore, but should
-    # consider the security tradeoffs.
-    failurePolicy: Fail
-    namespaceSelector:
-      # Exempt the webhook itself to avoid a circular dependency.
-      matchExpressions:
-        - key: kubernetes.io/metadata.name
-          operator: NotIn
-          values: ["pod-security-webhook"]
-...
-
-
-
-

!!! Attention

-
-
-

Pod Security Admissions graduated to stable in Kubernetes v1.25. If you -wanted to use the Pod Security Admission feature prior to it being -enabled by default, you needed to install the dynamic admission -controller (mutating webhook). The instructions for installing and -configuring the webhook can be found -here.

-
-
-
-
-

8.2.5. Choosing between policy-as-code and Pod Security Standards

-
-

The Pod Security Standards (PSS) were developed to replace the Pod -Security Policy (PSP), by providing a solution that was built-in to -Kubernetes and did not require solutions from the Kubernetes ecosystem. -That being said, policy-as-code (PAC) solutions are considerably more -flexible.

-
-
-

The following list of Pros and Cons is designed help you make a more -informed decision about your pod security solution.

-
-
-
Policy-as-code (as compared to Pod Security Standards)
-
-

Pros:

-
-
-
    -
  • -

    More flexible and more granular (down to attributes of resources if -need be)

    -
  • -
  • -

    Not just focused on pods, can be used against different resources and -actions

    -
  • -
  • -

    Not just applied at the namespace level

    -
  • -
  • -

    More mature than the Pod Security Standards

    -
  • -
  • -

    Decisions can be based on anything in the API server request payload, -as well as existing cluster resources and external data (solution -dependent)

    -
  • -
  • -

    Supports mutating API server requests before validation (solution -dependent)

    -
  • -
  • -

    Can generate complementary policies and Kubernetes resources (solution -dependent - From pod policies, Kyverno can -auto-gen policies for -higher-level controllers, such as Deployments. Kyverno can also generate -additional Kubernetes resources "`when a new resource is created or -when the source is updated`" by using -Generate Rules.)

    -
  • -
  • -

    Can be used to shift left, into CICD pipelines, before making calls to -the Kubernetes API server (solution dependent)

    -
  • -
  • -

    Can be used to implement behaviors that are not necessarily security -related, such as best practices, organizational standards, etc.

    -
  • -
  • -

    Can be used in non-Kubernetes use cases (solution dependent)

    -
  • -
  • -

    Because of flexibility, the user experience can be tuned to users’ -needs

    -
  • -
-
-
-

Cons:

-
-
-
    -
  • -

    Not built into Kubernetes

    -
  • -
  • -

    More complex to learn, configure, and support

    -
  • -
  • -

    Policy authoring may require new skills/languages/capabilities

    -
  • -
-
-
-
-
Pod Security Admission (as compared to policy-as-code)
-
-

Pros:

-
-
-
    -
  • -

    Built into Kubernetes

    -
  • -
  • -

    Simpler to configure

    -
  • -
  • -

    No new languages to use or policies to author

    -
  • -
  • -

    If the cluster default admission level is configured to privileged, -namespace labels can be used to opt namespaces into the pod security -profiles.

    -
  • -
-
-
-

Cons:

-
-
-
    -
  • -

    Not as flexible or granular as policy-as-code

    -
  • -
  • -

    Only 3 levels of restrictions

    -
  • -
  • -

    Primarily focused on pods

    -
  • -
-
-
-
-
Summary
-
-

If you currently do not have a pod security solution, beyond PSP, and -your required pod security posture fits the model defined in the Pod -Security Standards (PSS), then an easier path may be to adopt the PSS, -in lieu of a policy-as-code solution. However, if your pod security -posture does not fit the PSS model, or you envision adding additional -controls, beyond that defined by PSS, then a policy-as-code solution -would seem a better fit.

-
-
-
-
-
-

8.3. Recommendations

-
-

8.3.1. Use multiple Pod Security Admission (PSA) modes for a better user experience

-
-

As mentioned earlier, PSA enforce mode prevents pods with PSS -violations from being applied, but does not stop higher-level -controllers, such as Deployments. In fact, the Deployment will be -applied successfully without any indication that the pods failed to be -applied. While you can use kubectl to inspect the Deployment object, -and discover the failed pods message from the PSA, the user experience -could be better. To make the user experience better, multiple PSA modes -(audit, enforce, warn) should be used.

-
-
-
-
apiVersion: v1
-kind: Namespace
-metadata:
-  name: policy-test
-  labels:
-    pod-security.kubernetes.io/audit: restricted
-    pod-security.kubernetes.io/enforce: restricted
-    pod-security.kubernetes.io/warn: restricted
-
-
-
-

In the above example, with enforce mode defined, when a Deployment -manifest with PSS violations in the respective podSpec is attempted to -be applied to the Kubernetes API server, the Deployment will be -successfully applied, but the pods will not. And, since the audit and -warn modes are also enabled, the API server client will receive a -warning message and the API server audit log event will be annotated -with a message as well.

-
-
-
-

8.3.2. Restrict the containers that can run as privileged

-
-

As mentioned, containers that run as privileged inherit all of the Linux -capabilities assigned to root on the host. Seldom do containers need -these types of privileges to function properly. There are multiple -methods that can be used to restrict the permissions and capabilities of -containers.

-
-
-

!!! Attention

-
-
-

Fargate is a launch type that enables you to run “serverless” -container(s) where the containers of a pod are run on infrastructure -that AWS manages. With Fargate, you cannot run a privileged container or -configure your pod to use hostNetwork or hostPort.

-
-
-
-

8.3.3. Do not run processes in containers as root

-
-

All containers run as root by default. This could be problematic if an -attacker is able to exploit a vulnerability in the application and get -shell access to the running container. You can mitigate this risk a -variety of ways. First, by removing the shell from the container image. -Second, adding the USER directive to your Dockerfile or running the -containers in the pod as a non-root user. The Kubernetes podSpec -includes a set of fields, under spec.securityContext, that let you -specify the user and/or group under which to run your application. These -fields are runAsUser and runAsGroup respectively.

-
-
-

To enforce the use of the spec.securityContext, and its associated -elements, within the Kubernetes podSpec, policy-as-code or Pod Security -Standards can be added to clusters. These solutions allow you to write -and/or use policies or profiles that can validate inbound Kubernetes API -server request payloads, before they are persisted into etcd. -Furthermore, policy-as-code solutions can mutate inbound requests, and -in some cases, generate new requests.

-
-
-
-

8.3.4. Never run Docker in Docker or mount the socket in the container

-
-

While this conveniently lets you to build/run images in Docker -containers, you’re basically relinquishing complete control of the node -to the process running in the container. If you need to build container -images on Kubernetes use -Kaniko, -buildah, or a build service like -CodeBuild -instead.

-
-
-

!!! Tip

-
-
-

Kubernetes clusters used for CICD processing, such as building container -images, should be isolated from clusters running more generalized -workloads.

-
-
-
-

8.3.5. Restrict the use of hostPath or if hostPath is necessary restrict which prefixes can be used and configure the volume as read-only

-
-

hostPath is a volume that mounts a directory from the host directly -to the container. Rarely will pods need this type of access, but if they -do, you need to be aware of the risks. By default pods that run as root -will have write access to the file system exposed by hostPath. This -could allow an attacker to modify the kubelet settings, create symbolic -links to directories or files not directly exposed by the hostPath, -e.g. /etc/shadow, install ssh keys, read secrets mounted to the host, -and other malicious things. To mitigate the risks from hostPath, -configure the spec.containers.volumeMounts as readOnly, for -example:

-
-
-
-
volumeMounts:
-- name: hostPath-volume
-    readOnly: true
-    mountPath: /host-path
-
-
-
-

You should also use policy-as-code solutions to restrict the directories -that can be used by hostPath volumes, or prevent hostPath usage -altogether. You can use the Pod Security Standards Baseline or -Restricted policies to prevent the use of hostPath.

-
-
-

For further information about the dangers of privileged escalation, read -Seth Art’s blog -Bad -Pods: Kubernetes Pod Privilege Escalation.

-
-
-
-

8.3.6. Set requests and limits for each container to avoid resource contention and DoS attacks

-
-

A pod without requests or limits can theoretically consume all of the -resources available on a host. As additional pods are scheduled onto a -node, the node may experience CPU or memory pressure which can cause the -Kubelet to terminate or evict pods from the node. While you can’t -prevent this from happening all together, setting requests and limits -will help minimize resource contention and mitigate the risk from poorly -written applications that consume an excessive amount of resources.

-
-
-

The podSpec allows you to specify requests and limits for CPU and -memory. CPU is considered a compressible resource because it can be -oversubscribed. Memory is incompressible, i.e. it cannot be shared among -multiple containers.

-
-
-

When you specify requests for CPU or memory, you’re essentially -designating the amount of memory that containers are guaranteed to -get. Kubernetes aggregates the requests of all the containers in a pod -to determine which node to schedule the pod onto. If a container exceeds -the requested amount of memory it may be subject to termination if -there’s memory pressure on the node.

-
-
-

Limits are the maximum amount of CPU and memory resources that a -container is allowed to consume and directly corresponds to the -memory.limit_in_bytes value of the cgroup created for the container. -A container that exceeds the memory limit will be OOM killed. If a -container exceeds its CPU limit, it will be throttled.

-
-
-

!!! Tip

-
-
-

When using container resources.limits it is strongly recommended -that container resource usage (a.k.a. Resource Footprints) be -data-driven and accurate, based on load testing. Absent an accurate and -trusted resource footprint, container resources.limits can be -padded. For example, resources.limits.memory could be padded 20-30% -higher than observable maximums, to account for potential memory -resource limit inaccuracies.

-
-
-

Kubernetes uses three Quality of Service (QoS) classes to prioritize the -workloads running on a node. These include:

-
-
-
    -
  • -

    guaranteed

    -
  • -
  • -

    burstable

    -
  • -
  • -

    best-effort

    -
  • -
-
-
-

If limits and requests are not set, the pod is configured as -best-effort (lowest priority). Best-effort pods are the first to get -killed when there is insufficient memory. If limits are set on all -containers within the pod, or if the requests and limits are set to the -same values and not equal to 0, the pod is configured as guaranteed -(highest priority). Guaranteed pods will not be killed unless they -exceed their configured memory limits. If the limits and requests are -configured with different values and not equal to 0, or one container -within the pod sets limits and the others don’t or have limits set for -different resources, the pods are configured as burstable (medium -priority). These pods have some resource guarantees, but can be killed -once they exceed their requested memory.

-
-
-

!!! Attention

-
-
-

Requests don’t affect the memory_limit_in_bytes value of the -container’s cgroup; the cgroup limit is set to the amount of memory -available on the host. Nevertheless, setting the requests value too low -could cause the pod to be targeted for termination by the kubelet if the -node undergoes memory pressure.

-
- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassPriorityConditionKill Condition

Guaranteed

highest

limit = request != 0

Only exceed memory limits

Burstable

medium

limit != request != 0

Can be killed if exceed -request memory

Best-Effort

lowest

limit & request Not Set

First to get killed when -there’s insufficient memory

-
-

For additional information about resource QoS, please refer to the -Kubernetes -documentation.

-
-
-

You can force the use of requests and limits by setting a -resource -quota on a namespace or by creating a -limit range. A -resource quota allows you to specify the total amount of resources, -e.g. CPU and RAM, allocated to a namespace. When it’s applied to a -namespace, it forces you to specify requests and limits for all -containers deployed into that namespace. By contrast, limit ranges give -you more granular control of the allocation of resources. With limit -ranges you can min/max for CPU and memory resources per pod or per -container within a namespace. You can also use them to set default -request/limit values if none are provided.

-
-
-

Policy-as-code solutions can be used enforce requests and limits. or to -even create the resource quotas and limit ranges when namespaces are -created.

-
-
-
-

8.3.7. Do not allow privileged escalation

-
-

Privileged escalation allows a process to change the security context -under which its running. Sudo is a good example of this as are binaries -with the SUID or SGID bit. Privileged escalation is basically a way for -users to execute a file with the permissions of another user or group. -You can prevent a container from using privileged escalation by -implementing a policy-as-code mutating policy that sets -allowPrivilegeEscalation to false or by setting -securityContext.allowPrivilegeEscalation in the podSpec. -Policy-as-code policies can also be used to prevent API server requests -from succeeding if incorrect settings are detected. Pod Security -Standards can also be used to prevent pods from using privilege -escalation.

-
-
-
-

8.3.8. Disable ServiceAccount token mounts

-
-

For pods that do not need to access the Kubernetes API, you can disable -the automatic mounting of a ServiceAccount token on a pod spec, or for -all pods that use a particular ServiceAccount.

-
-
-

!!! Attention

-
-
-

Disabling ServiceAccount mounting does not prevent a pod from having -network access to the Kubernetes API. To prevent a pod from having any -network access to the Kubernetes API, you will need to modify the -EKS -cluster endpoint access and use a -NetworkPolicy to block pod access.

-
-
-
-
apiVersion: v1
-kind: Pod
-metadata:
-  name: pod-no-automount
-spec:
-  automountServiceAccountToken: false
-
-
-
-
-
apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: sa-no-automount
-automountServiceAccountToken: false
-
-
-
-
-

8.3.9. Disable service discovery

-
-

For pods that do not need to lookup or call in-cluster services, you can -reduce the amount of information given to a pod. You can set the Pod’s -DNS policy to not use CoreDNS, and not expose services in the pod’s -namespace as environment variables. See the -Kubernetes -docs on environment variables for more information on service links. -The default value for a pod’s DNS policy is “ClusterFirst” which uses -in-cluster DNS, while the non-default value “Default” uses the -underlying node’s DNS resolution. See the -Kubernetes -docs on Pod DNS policy for more information.

-
-
-

!!! Attention

-
-
-

Disabling service links and changing the pod’s DNS policy does not -prevent a pod from having network access to the in-cluster DNS service. -An attacker can still enumerate services in a cluster by reaching the -in-cluster DNS service. (ex: -dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP) To prevent -in-cluster service discovery, use a -NetworkPolicy to block pod access

-
-
-
-
apiVersion: v1
-kind: Pod
-metadata:
-  name: pod-no-service-info
-spec:
-    dnsPolicy: Default # "Default" is not the true default value
-    enableServiceLinks: false
-
-
-
-
-

8.3.10. Configure your images with read-only root file system

-
-

Configuring your images with a read-only root file system prevents an -attacker from overwriting a binary on the file system that your -application uses. If your application has to write to the file system, -consider writing to a temporary directory or attach and mount a volume. -You can enforce this by setting the pod’s SecurityContext as follows:

-
-
-
-
...
-securityContext:
-  readOnlyRootFilesystem: true
-...
-
-
-
-

Policy-as-code and Pod Security Standards can be used to enforce this -behavior.

-
-
-

!!! Info

-
-
-

As per Windows -containers in Kubernetes securityContext.readOnlyRootFilesystem -cannot be set to true for a container running on Windows as write -access is required for registry and system processes to run inside the -container.

-
-
-
-
-

8.4. Tools and resources

-
- -
-
-
-
-
-

9. Tenant Isolation

-
-
-

When we think of multi-tenancy, we often want to isolate a user or -application from other users or applications running on a shared -infrastructure.

-
-
-

Kubernetes is a single tenant orchestrator, i.e. a single instance of -the control plane is shared among all the tenants within a cluster. -There are, however, various Kubernetes objects that you can use to -create the semblance of multi-tenancy. For example, Namespaces and -Role-based access controls (RBAC) can be implemented to logically -isolate tenants from each other. Similarly, Quotas and Limit Ranges can -be used to control the amount of cluster resources each tenant can -consume. Nevertheless, the cluster is the only construct that provides a -strong security boundary. This is because an attacker that manages to -gain access to a host within the cluster can retrieve all Secrets, -ConfigMaps, and Volumes, mounted on that host. They could also -impersonate the Kubelet which would allow them to manipulate the -attributes of the node and/or move laterally within the cluster.

-
-
-

The following sections will explain how to implement tenant isolation -while mitigating the risks of using a single tenant orchestrator like -Kubernetes.

-
-
-

9.1. Soft multi-tenancy

-
-

With soft multi-tenancy, you use native Kubernetes constructs, -e.g. namespaces, roles and role bindings, and network policies, to -create logical separation between tenants. RBAC, for example, can -prevent tenants from accessing or manipulate each other’s resources. -Quotas and limit ranges control the amount of cluster resources each -tenant can consume while network policies can help prevent applications -deployed into different namespaces from communicating with each other.

-
-
-

None of these controls, however, prevent pods from different tenants -from sharing a node. If stronger isolation is required, you can use a -node selector, anti-affinity rules, and/or taints and tolerations to -force pods from different tenants to be scheduled onto separate nodes; -often referred to as sole tenant nodes. This could get rather -complicated, and cost prohibitive, in an environment with many tenants.

-
-
-

!!! attention Soft multi-tenancy implemented with Namespaces does not -allow you to provide tenants with a filtered list of Namespaces because -Namespaces are a globally scoped Type. If a tenant has the ability to -view a particular Namespace, it can view all Namespaces within the -cluster.

-
-
-

!!! warning With soft-multi-tenancy, tenants retain the ability to query -CoreDNS for all services that run within the cluster by default. An -attacker could exploit this by running dig SRV *.*.svc.cluster.local -from any pod in the cluster. If you need to restrict access to DNS -records of services that run within your clusters, consider using the -Firewall or Policy plugins for CoreDNS. For additional information, see -https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy.

-
-
-

Kiosk is an open source project that -can aid in the implementation of soft multi-tenancy. It is implemented -as a series of CRDs and controllers that provide the following -capabilities:

-
-
-
    -
  • -

    Accounts & Account Users to separate tenants in a shared Kubernetes -cluster

    -
  • -
  • -

    Self-Service Namespace Provisioning for account users

    -
  • -
  • -

    Account Limits to ensure quality of service and fairness when -sharing a cluster

    -
  • -
  • -

    Namespace Templates for secure tenant isolation and self-service -namespace initialization

    -
  • -
-
-
-

Loft is a commercial offering from the maintainers of -Kiosk and DevSpace that adds -the following capabilities:

-
-
-
    -
  • -

    Multi-cluster access for granting access to spaces in different -clusters

    -
  • -
  • -

    Sleep mode scales down deployments in a space during periods of -inactivity

    -
  • -
  • -

    Single sign-on with OIDC authentication providers like GitHub

    -
  • -
-
-
-

There are three primary use cases that can be addressed by soft -multi-tenancy.

-
-
-

9.1.1. Enterprise Setting

-
-

The first is in an Enterprise setting where the “tenants” are -semi-trusted in that they are employees, contractors, or are otherwise -authorized by the organization. Each tenant will typically align to an -administrative division such as a department or team.

-
-
-

In this type of setting, a cluster administrator will usually be -responsible for creating namespaces and managing policies. They may also -implement a delegated administration model where certain individuals are -given oversight of a namespace, allowing them to perform CRUD operations -for non-policy related objects like deployments, services, pods, jobs, -etc.

-
-
-

The isolation provided by a container runtime may be acceptable within -this setting or it may need to be augmented with additional controls for -pod security. It may also be necessary to restrict communication between -services in different namespaces if stricter isolation is required.

-
-
-
-

9.1.2. Kubernetes as a Service

-
-

By contrast, soft multi-tenancy can be used in settings where you want -to offer Kubernetes as a service (KaaS). With KaaS, your application is -hosted in a shared cluster along with a collection of controllers and -CRDs that provide a set of PaaS services. Tenants interact directly with -the Kubernetes API server and are permitted to perform CRUD operations -on non-policy objects. There is also an element of self-service in that -tenants may be allowed to create and manage their own namespaces. In -this type of environment, tenants are assumed to be running untrusted -code.

-
-
-

To isolate tenants in this type of environment, you will likely need to -implement strict network policies as well as pod sandboxing. -Sandboxing is where you run the containers of a pod inside a micro VM -like Firecracker or in a user-space kernel. Today, you can create -sandboxed pods with EKS Fargate.

-
-
-
-

9.1.3. Software as a Service (SaaS)

-
-

The final use case for soft multi-tenancy is in a Software-as-a-Service -(SaaS) setting. In this environment, each tenant is associated with a -particular instance of an application that’s running within the -cluster. Each instance often has its own data and uses separate access -controls that are usually independent of Kubernetes RBAC.

-
-
-

Unlike the other use cases, the tenant in a SaaS setting does not -directly interface with the Kubernetes API. Instead, the SaaS -application is responsible for interfacing with the Kubernetes API to -create the necessary objects to support each tenant.

-
-
-
-
-

9.2. Kubernetes Constructs

-
-

In each of these instances the following constructs are used to isolate -tenants from each other:

-
-
-

9.2.1. Namespaces

-
-

Namespaces are fundamental to implementing soft multi-tenancy. They -allow you to divide the cluster into logical partitions. Quotas, network -policies, service accounts, and other objects needed to implement -multi-tenancy are scoped to a namespace.

-
-
-
-

9.2.2. Network policies

-
-

By default, all pods in a Kubernetes cluster are allowed to communicate -with each other. This behavior can be altered using network policies.

-
-
-

Network policies restrict communication between pods using labels or IP -address ranges. In a multi-tenant environment where strict network -isolation between tenants is required, we recommend starting with a -default rule that denies communication between pods, and another rule -that allows all pods to query the DNS server for name resolution. With -that in place, you can begin adding more permissive rules that allow for -communication within a namespace. This can be further refined as -required.

-
-
-

!!! note Amazon -VPC -CNI now supports Kubernetes Network Policies to create policies that -can isolate sensitive workloads and protect them from unauthorized -access when running Kubernetes on AWS. This means that you can use all -the capabilities of the Network Policy API within your Amazon EKS -cluster. This level of granular control enables you to implement the -principle of least privilege, which ensures that only authorized pods -are allowed to communicate with each other.

-
-
-

!!! attention Network policies are necessary but not sufficient. The -enforcement of network policies requires a policy engine such as Calico -or Cilium.

-
-
-
-

9.2.3. Role-based access control (RBAC)

-
-

Roles and role bindings are the Kubernetes objects used to enforce -role-based access control (RBAC) in Kubernetes. Roles contain lists of -actions that can be performed against objects in your cluster. Role -bindings specify the individuals or groups to whom the roles apply. In -the enterprise and KaaS settings, RBAC can be used to permit -administration of objects by selected groups or individuals.

-
-
-
-

9.2.4. Quotas

-
-

Quotas are used to define limits on workloads hosted in your cluster. -With quotas, you can specify the maximum amount of CPU and memory that a -pod can consume, or you can limit the number of resources that can be -allocated in a cluster or namespace. Limit ranges allow you to declare -minimum, maximum, and default values for each limit.

-
-
-

Overcommitting resources in a shared cluster is often beneficial because -it allows you maximize your resources. However, unbounded access to a -cluster can cause resource starvation, which can lead to performance -degradation and loss of application availability. If a pod’s requests -are set too low and the actual resource utilization exceeds the capacity -of the node, the node will begin to experience CPU or memory pressure. -When this happens, pods may be restarted and/or evicted from the node.

-
-
-

To prevent this from happening, you should plan to impose quotas on -namespaces in a multi-tenant environment to force tenants to specify -requests and limits when scheduling their pods on the cluster. It will -also mitigate a potential denial of service by constraining the amount -of resources a pod can consume.

-
-
-

You can also use quotas to apportion the cluster’s resources to align -with a tenant’s spend. This is particularly useful in the KaaS scenario.

-
-
-
-

9.2.5. Pod priority and preemption

-
-

Pod priority and preemption can be useful when you want to provide more -importance to a Pod relative to other Pods. For example, with pod -priority you can configure pods from customer A to run at a higher -priority than customer B. When there’s insufficient capacity available, -the scheduler will evict the lower-priority pods from customer B to -accommodate the higher-priority pods from customer A. This can be -especially handy in a SaaS environment where customers willing to pay a -premium receive a higher priority.

-
-
-

!!! attention Pods priority can have an undesired effect on other Pods -with lower priority. For example, although the victim pods are -terminated gracefully but the PodDisruptionBudget is not guaranteed, -which could break a application with lower priority that relies on a -quorum of Pods, see -Limitations -of preemption.

-
-
-
-
-

9.3. Mitigating controls

-
-

Your chief concern as an administrator of a multi-tenant environment is -preventing an attacker from gaining access to the underlying host. The -following controls should be considered to mitigate this risk:

-
-
-

9.3.1. Sandboxed execution environments for containers

-
-

Sandboxing is a technique by which each container is run in its own -isolated virtual machine. Technologies that perform pod sandboxing -include Firecracker and Weave’s -Firekube.

-
-
-

For additional information about the effort to make Firecracker a -supported runtime for EKS, see -https://threadreaderapp.com/thread/1238496944684597248.html.

-
-
-
-

9.3.2. Open Policy Agent (OPA) & Gatekeeper

-
-

Gatekeeper is a -Kubernetes admission controller that enforces policies created with -OPA. With OPA you can create a policy -that runs pods from tenants on separate instances or at a higher -priority than other tenants. A collection of common OPA policies can be -found in the GitHub -repository -for this project.

-
-
-

There is also an experimental OPA -plugin for CoreDNS that allows you to use OPA to filter/control the -records returned by CoreDNS.

-
-
-
-

9.3.3. Kyverno

-
-

Kyverno is a Kubernetes native policy engine that -can validate, mutate, and generate configurations with policies as -Kubernetes resources. Kyverno uses Kustomize-style overlays for -validation, supports JSON Patch and strategic merge patch for mutation, -and can clone resources across namespaces based on flexible triggers.

-
-
-

You can use Kyverno to isolate namespaces, enforce pod security and -other best practices, and generate default configurations such as -network policies. Several examples are included in the GitHub -repository -for this project. Many others are included in the -policy library on the Kyverno website.

-
-
-
-

9.3.4. Isolating tenant workloads to specific nodes

-
-

Restricting tenant workloads to run on specific nodes can be used to -increase isolation in the soft multi-tenancy model. With this approach, -tenant-specific workloads are only run on nodes provisioned for the -respective tenants. To achieve this isolation, native Kubernetes -properties (node affinity, and taints and tolerations) are used to -target specific nodes for pod scheduling, and prevent pods, from other -tenants, from being scheduled on the tenant-specific nodes.

-
-
-
Part 1 - Node affinity
-
-

Kubernetes -node -affinity is used to target nodes for scheduling, based on node -labels. -With node affinity rules, the pods are attracted to specific nodes that -match the selector terms. In the below pod specification, the -requiredDuringSchedulingIgnoredDuringExecution node affinity is -applied to the respective pod. The result is that the pod will target -nodes that are labeled with the following key/value: -node-restriction.kubernetes.io/tenant: tenants-x.

-
-
-
-
...
-spec:
-  affinity:
-    nodeAffinity:
-      requiredDuringSchedulingIgnoredDuringExecution:
-        nodeSelectorTerms:
-        - matchExpressions:
-          - key: node-restriction.kubernetes.io/tenant
-            operator: In
-            values:
-            - tenants-x
-...
-
-
-
-

With this node affinity, the label is required during scheduling, but -not during execution; if the underlying nodes’ labels change, the pods -will not be evicted due solely to that label change. However, future -scheduling could be impacted.

-
-
-

!!! Warning The label prefix of node-restriction.kubernetes.io/ has -special meaning in Kubernetes. -NodeRestriction -which is enabled for EKS clusters prevents kubelet from -adding/removing/updating labels with this prefix. Attackers aren’t able -to use the kubelet’s credentials to update the node object or modify -the system setup to pass these labels into kubelet as kubelet -isn’t allowed to modify these labels. If this prefix is used for all pod -to node scheduling, it prevents scenarios where an attacker may want to -attract a different set of workloads to a node by modifying the node -labels.

-
-
-

!!! Info Instead of node affinity, we could have used the -node -selector. However, node affinity is more expressive and allows for more -conditions to be considered during pod scheduling. For additional -information about the differences and more advanced scheduling choices, -please see this CNCF blog post on -Advanced -Kubernetes pod to node scheduling.

-
-
-
-
Part 2 - Taints and tolerations
-
-

Attracting pods to nodes is just the first part of this three-part -approach. For this approach to work, we must repel pods from scheduling -onto nodes for which the pods are not authorized. To repel unwanted or -unauthorized pods, Kubernetes uses node -taints. -Taints are used to place conditions on nodes that prevent pods from -being scheduled. The below taint uses a key-value pair of -tenant: tenants-x.

-
-
-
-
...
-    taints:
-      - key: tenant
-        value: tenants-x
-        effect: NoSchedule
-...
-
-
-
-

Given the above node taint, only pods that tolerate the taint will -be allowed to be scheduled on the node. To allow authorized pods to be -scheduled onto the node, the respective pod specifications must include -a toleration to the taint, as seen below.

-
-
-
-
...
-  tolerations:
-  - effect: NoSchedule
-    key: tenant
-    operator: Equal
-    value: tenants-x
-...
-
-
-
-

Pods with the above toleration will not be stopped from scheduling -on the node, at least not because of that specific taint. Taints are -also used by Kubernetes to temporarily stop pod scheduling during -certain conditions, like node resource pressure. With node affinity, and -taints and tolerations, we can effectively attract the desired pods to -specific nodes and repel unwanted pods.

-
-
-

!!! attention Certain Kubernetes pods are required to run on all nodes. -Examples of these pods are those started by the -Container Network Interface -(CNI) and -kube-proxy -daemonsets. -To that end, the specifications for these pods contain very permissive -tolerations, to tolerate different taints. Care should be taken to not -change these tolerations. Changing these tolerations could result in -incorrect cluster operation. Additionally, policy-management tools, such -as OPA/Gatekeeper and -Kyverno can be used to write validating policies -that prevent unauthorized pods from using these permissive tolerations.

-
-
-
-
Part 3 - Policy-based management for node selection
-
-

There are several tools that can be used to help manage the node -affinity and tolerations of pod specifications, including enforcement of -rules in CICD pipelines. However, enforcement of isolation should also -be done at the Kubernetes cluster level. For this purpose, -policy-management tools can be used to mutate inbound Kubernetes API -server requests, based on request payloads, to apply the respective node -affinity rules and tolerations mentioned above.

-
-
-

For example, pods destined for the tenants-x namespace can be -stamped with the correct node affinity and toleration to permit -scheduling on the tenants-x nodes. Utilizing policy-management tools -configured using the Kubernetes -Mutating -Admission Webhook, policies can be used to mutate the inbound pod -specifications. The mutations add the needed elements to allow desired -scheduling. An example OPA/Gatekeeper policy that adds a node affinity -is seen below.

-
-
-
-
apiVersion: mutations.gatekeeper.sh/v1alpha1
-kind: Assign
-metadata:
-  name: mutator-add-nodeaffinity-pod
-  annotations:
-    aws-eks-best-practices/description: >-
-      Adds Node affinity - https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
-spec:
-  applyTo:
-  - groups: [""]
-    kinds: ["Pod"]
-    versions: ["v1"]
-  match:
-    namespaces: ["tenants-x"]
-  location: "spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms"
-  parameters:
-    assign:
-      value:
-        - matchExpressions:
-          - key: "tenant"
-            operator: In
-            values:
-            - "tenants-x"
-
-
-
-

The above policy is applied to a Kubernetes API server request, to apply -a pod to the tenants-x namespace. The policy adds the -requiredDuringSchedulingIgnoredDuringExecution node affinity rule, -so that pods are attracted to nodes with the tenant: tenants-x -label.

-
-
-

A second policy, seen below, adds the toleration to the same pod -specification, using the same matching criteria of target namespace and -groups, kinds, and versions.

-
-
-
-
apiVersion: mutations.gatekeeper.sh/v1alpha1
-kind: Assign
-metadata:
-  name: mutator-add-toleration-pod
-  annotations:
-    aws-eks-best-practices/description: >-
-      Adds toleration - https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
-spec:
-  applyTo:
-  - groups: [""]
-    kinds: ["Pod"]
-    versions: ["v1"]
-  match:
-    namespaces: ["tenants-x"]
-  location: "spec.tolerations"
-  parameters:
-    assign:
-      value:
-      - key: "tenant"
-        operator: "Equal"
-        value: "tenants-x"
-        effect: "NoSchedule"
-
-
-
-

The above policies are specific to pods; this is due to the paths to the -mutated elements in the policies’ location elements. Additional -policies could be written to handle resources that create pods, like -Deployment and Job resources. The listed policies and other examples can -been seen in the companion -GitHub -project for this guide.

-
-
-

The result of these two mutations is that pods are attracted to the -desired node, while at the same time, not repelled by the specific node -taint. To verify this, we can see the snippets of output from two -kubectl calls to get the nodes labeled with tenant=tenants-x, -and get the pods in the tenants-x namespace.

-
-
-
-
kubectl get nodes -l tenant=tenants-x
-NAME
-ip-10-0-11-255...
-ip-10-0-28-81...
-ip-10-0-43-107...
-
-kubectl -n tenants-x get pods -owide
-NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE
-tenant-test-deploy-58b895ff87-2q7xw   1/1     Running   0          13s   10.0.42.143   ip-10-0-43-107...
-tenant-test-deploy-58b895ff87-9b6hg   1/1     Running   0          13s   10.0.18.145   ip-10-0-28-81...
-tenant-test-deploy-58b895ff87-nxvw5   1/1     Running   0          13s   10.0.30.117   ip-10-0-28-81...
-tenant-test-deploy-58b895ff87-vw796   1/1     Running   0          13s   10.0.3.113    ip-10-0-11-255...
-tenant-test-pod                       1/1     Running   0          13s   10.0.35.83    ip-10-0-43-107...
-
-
-
-

As we can see from the above outputs, all the pods are scheduled on the -nodes labeled with tenant=tenants-x. Simply put, the pods will only -run on the desired nodes, and the other pods (without the required -affinity and tolerations) will not. The tenant workloads are effectively -isolated.

-
-
-

An example mutated pod specification is seen below.

-
-
-
-
apiVersion: v1
-kind: Pod
-metadata:
-  name: tenant-test-pod
-  namespace: tenants-x
-spec:
-  affinity:
-    nodeAffinity:
-      requiredDuringSchedulingIgnoredDuringExecution:
-        nodeSelectorTerms:
-        - matchExpressions:
-          - key: tenant
-            operator: In
-            values:
-            - tenants-x
-...
-  tolerations:
-  - effect: NoSchedule
-    key: tenant
-    operator: Equal
-    value: tenants-x
-...
-
-
-
-

!!! attention Policy-management tools that are integrated to the -Kubernetes API server request flow, using mutating and validating -admission webhooks, are designed to respond to the API server’s request -within a specified timeframe. This is usually 3 seconds or less. If the -webhook call fails to return a response within the configured time, the -mutation and/or validation of the inbound API sever request may or may -not occur. This behavior is based on whether the admission webhook -configurations are set to -Fail -Open or Fail Close.

-
-
-

In the above examples, we used policies written for OPA/Gatekeeper. -However, there are other policy management tools that handle our -node-selection use case as well. For example, this -Kyverno -policy could be used to handle the node affinity mutation.

-
-
-

!!! tip If operating correctly, mutating policies will effect the -desired changes to inbound API server request payloads. However, -validating policies should also be included to verify that the desired -changes occur, before changes are allowed to persist. This is especially -important when using these policies for tenant-to-node isolation. It is -also a good idea to include Audit policies to routinely check your -cluster for unwanted configurations.

-
-
-
-
-

9.3.5. References

-
- -
-
-
-
-

9.4. Hard multi-tenancy

-
-

Hard multi-tenancy can be implemented by provisioning separate clusters -for each tenant. While this provides very strong isolation between -tenants, it has several drawbacks.

-
-
-

First, when you have many tenants, this approach can quickly become -expensive. Not only will you have to pay for the control plane costs for -each cluster, you will not be able to share compute resources between -clusters. This will eventually cause fragmentation where a subset of -your clusters are underutilized while others are overutilized.

-
-
-

Second, you will likely need to buy or build special tooling to manage -all of these clusters. In time, managing hundreds or thousands of -clusters may simply become too unwieldy.

-
-
-

Finally, creating a cluster per tenant will be slow relative to a -creating a namespace. Nevertheless, a hard-tenancy approach may be -necessary in highly-regulated industries or in SaaS environments where -strong isolation is required.

-
-
-
-

9.5. Future directions

-
-

The Kubernetes community has recognized the current shortcomings of soft -multi-tenancy and the challenges with hard multi-tenancy. The -Multi-Tenancy Special -Interest Group (SIG) is attempting to address these shortcomings -through several incubation projects, including Hierarchical Namespace -Controller (HNC) and Virtual Cluster.

-
-
-

The HNC proposal (KEP) describes a way to create parent-child -relationships between namespaces with [policy] object inheritance along -with an ability for tenant administrators to create sub-namespaces.

-
-
-

The Virtual Cluster proposal describes a mechanism for creating separate -instances of the control plane services, including the API server, the -controller manager, and scheduler, for each tenant within the cluster -(also known as “Kubernetes on Kubernetes”).

-
-
-

The -Multi-Tenancy -Benchmarks proposal provides guidelines for sharing clusters using -namespaces for isolation and segmentation, and a command line tool -kubectl-mtb -to validate conformance to the guidelines.

-
-
-
-

9.6. Multi-cluster management tools and resources

-
- -
-
-
-
-
-

10. Auditing and logging

-
-
-

Collecting and analyzing [audit] logs is useful for a variety of -different reasons. Logs can help with root cause analysis and -attribution, i.e. ascribing a change to a particular user. When enough -logs have been collected, they can be used to detect anomalous behaviors -too. On EKS, the audit logs are sent to Amazon Cloudwatch Logs. The -audit policy for EKS is as follows:

-
-
-
-
apiVersion: audit.k8s.io/v1beta1
-kind: Policy
-rules:
-  # Log aws-auth configmap changes
-  - level: RequestResponse
-    namespaces: ["kube-system"]
-    verbs: ["update", "patch", "delete"]
-    resources:
-      - group: "" # core
-        resources: ["configmaps"]
-        resourceNames: ["aws-auth"]
-    omitStages:
-      - "RequestReceived"
-  - level: None
-    users: ["system:kube-proxy"]
-    verbs: ["watch"]
-    resources:
-      - group: "" # core
-        resources: ["endpoints", "services", "services/status"]
-  - level: None
-    users: ["kubelet"] # legacy kubelet identity
-    verbs: ["get"]
-    resources:
-      - group: "" # core
-        resources: ["nodes", "nodes/status"]
-  - level: None
-    userGroups: ["system:nodes"]
-    verbs: ["get"]
-    resources:
-      - group: "" # core
-        resources: ["nodes", "nodes/status"]
-  - level: None
-    users:
-      - system:kube-controller-manager
-      - system:kube-scheduler
-      - system:serviceaccount:kube-system:endpoint-controller
-    verbs: ["get", "update"]
-    namespaces: ["kube-system"]
-    resources:
-      - group: "" # core
-        resources: ["endpoints"]
-  - level: None
-    users: ["system:apiserver"]
-    verbs: ["get"]
-    resources:
-      - group: "" # core
-        resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
-  - level: None
-    users:
-      - system:kube-controller-manager
-    verbs: ["get", "list"]
-    resources:
-      - group: "metrics.k8s.io"
-  - level: None
-    nonResourceURLs:
-      - /healthz*
-      - /version
-      - /swagger*
-  - level: None
-    resources:
-      - group: "" # core
-        resources: ["events"]
-  - level: Request
-    users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
-    verbs: ["update","patch"]
-    resources:
-      - group: "" # core
-        resources: ["nodes/status", "pods/status"]
-    omitStages:
-      - "RequestReceived"
-  - level: Request
-    userGroups: ["system:nodes"]
-    verbs: ["update","patch"]
-    resources:
-      - group: "" # core
-        resources: ["nodes/status", "pods/status"]
-    omitStages:
-      - "RequestReceived"
-  - level: Request
-    users: ["system:serviceaccount:kube-system:namespace-controller"]
-    verbs: ["deletecollection"]
-    omitStages:
-      - "RequestReceived"
-  # Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
-  # so only log at the Metadata level.
-  - level: Metadata
-    resources:
-      - group: "" # core
-        resources: ["secrets", "configmaps"]
-      - group: authentication.k8s.io
-        resources: ["tokenreviews"]
-    omitStages:
-      - "RequestReceived"
-  - level: Request
-    resources:
-      - group: ""
-        resources: ["serviceaccounts/token"]
-  - level: Request
-    verbs: ["get", "list", "watch"]
-    resources:
-      - group: "" # core
-      - group: "admissionregistration.k8s.io"
-      - group: "apiextensions.k8s.io"
-      - group: "apiregistration.k8s.io"
-      - group: "apps"
-      - group: "authentication.k8s.io"
-      - group: "authorization.k8s.io"
-      - group: "autoscaling"
-      - group: "batch"
-      - group: "certificates.k8s.io"
-      - group: "extensions"
-      - group: "metrics.k8s.io"
-      - group: "networking.k8s.io"
-      - group: "policy"
-      - group: "rbac.authorization.k8s.io"
-      - group: "scheduling.k8s.io"
-      - group: "settings.k8s.io"
-      - group: "storage.k8s.io"
-    omitStages:
-      - "RequestReceived"
-  # Default level for known APIs
-  - level: RequestResponse
-    resources:
-      - group: "" # core
-      - group: "admissionregistration.k8s.io"
-      - group: "apiextensions.k8s.io"
-      - group: "apiregistration.k8s.io"
-      - group: "apps"
-      - group: "authentication.k8s.io"
-      - group: "authorization.k8s.io"
-      - group: "autoscaling"
-      - group: "batch"
-      - group: "certificates.k8s.io"
-      - group: "extensions"
-      - group: "metrics.k8s.io"
-      - group: "networking.k8s.io"
-      - group: "policy"
-      - group: "rbac.authorization.k8s.io"
-      - group: "scheduling.k8s.io"
-      - group: "settings.k8s.io"
-      - group: "storage.k8s.io"
-    omitStages:
-      - "RequestReceived"
-  # Default level for all other requests.
-  - level: Metadata
-    omitStages:
-      - "RequestReceived"
-
-
-
-

10.1. Recommendations

-
-

10.1.1. Enable audit logs

-
-

The audit logs are part of the EKS managed Kubernetes control plane logs -that are managed by EKS. Instructions for enabling/disabling the control -plane logs, which includes the logs for the Kubernetes API server, the -controller manager, and the scheduler, along with the audit log, can be -found here, -https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html#enabling-control-plane-log-export.

-
-
-

!!! info When you enable control plane logging, you will incur -costs for storing the logs -in CloudWatch. This raises a broader issue about the ongoing cost of -security. Ultimately you will have to weigh those costs against the cost -of a security breach, e.g. financial loss, damage to your reputation, -etc. You may find that you can adequately secure your environment by -implementing only some of the recommendations in this guide.

-
-
-

!!! warning The maximum size for a CloudWatch Logs entry is -256KB -whereas the maximum Kubernetes API request size is 1.5MiB. Log entries -greater than 256KB will either be truncated or only include the request -metadata.

-
-
-
-

10.1.2. Utilize audit metadata

-
-

Kubernetes audit logs include two annotations that indicate whether or -not a request was authorized authorization.k8s.io/decision and the -reason for the decision authorization.k8s.io/reason. Use these -attributes to ascertain why a particular API call was allowed.

-
-
-
-

10.1.3. Create alarms for suspicious events

-
-

Create an alarm to automatically alert you where there is an increase in -403 Forbidden and 401 Unauthorized responses, and then use attributes -like host, sourceIPs, and k8s_user.username to find out -where those requests are coming from.

-
-
-
-

10.1.4. Analyze logs with Log Insights

-
-

Use CloudWatch Log Insights to monitor changes to RBAC objects, -e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few -sample queries appear below:

-
-
-

Lists updates to the aws-auth ConfigMap:

-
-
-
-
fields @timestamp, @message
-| filter @logStream like "kube-apiserver-audit"
-| filter verb in ["update", "patch"]
-| filter objectRef.resource = "configmaps" and objectRef.name = "aws-auth" and objectRef.namespace = "kube-system"
-| sort @timestamp desc
-
-
-
-

Lists creation of new or changes to validation webhooks:

-
-
-
-
fields @timestamp, @message
-| filter @logStream like "kube-apiserver-audit"
-| filter verb in ["create", "update", "patch"] and responseStatus.code = 201
-| filter objectRef.resource = "validatingwebhookconfigurations"
-| sort @timestamp desc
-
-
-
-

Lists create, update, delete operations to Roles:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter objectRef.resource="roles" and verb in ["create", "update", "patch", "delete"]
-
-
-
-

Lists create, update, delete operations to RoleBindings:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter objectRef.resource="rolebindings" and verb in ["create", "update", "patch", "delete"]
-
-
-
-

Lists create, update, delete operations to ClusterRoles:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter objectRef.resource="clusterroles" and verb in ["create", "update", "patch", "delete"]
-
-
-
-

Lists create, update, delete operations to ClusterRoleBindings:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter objectRef.resource="clusterrolebindings" and verb in ["create", "update", "patch", "delete"]
-
-
-
-

Plots unauthorized read operations against Secrets:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter objectRef.resource="secrets" and verb in ["get", "watch", "list"] and responseStatus.code="401"
-| stats count() by bin(1m)
-
-
-
-

List of failed anonymous requests:

-
-
-
-
fields @timestamp, @message, sourceIPs.0
-| sort @timestamp desc
-| limit 100
-| filter user.username="system:anonymous" and responseStatus.code in ["401", "403"]
-
-
-
-
-

10.1.5. Audit your CloudTrail logs

-
-

AWS APIs called by pods that are utilizing IAM Roles for Service -Accounts (IRSA) are automatically logged to CloudTrail along with the -name of the service account. If the name of a service account that -wasn’t explicitly authorized to call an API appears in the log, it may -be an indication that the IAM role’s trust policy was misconfigured. -Generally speaking, Cloudtrail is a great way to ascribe AWS API calls -to specific IAM principals.

-
-
-
-

10.1.6. Use CloudTrail Insights to unearth suspicious activity

-
-

CloudTrail insights automatically analyzes write management events from -CloudTrail trails and alerts you of unusual activity. This can help you -identify when there’s an increase in call volume on write APIs in your -AWS account, including from pods that use IRSA to assume an IAM role. -See -Announcing -CloudTrail Insights: Identify and Response to Unusual API Activity for -further information.

-
-
-
-

10.1.7. Additional resources

-
-

As the volume of logs increases, parsing and filtering them with Log -Insights or another log analysis tool may become ineffective. As an -alternative, you might want to consider running -Sysdig Falco and -ekscloudwatch. Falco -analyzes audit logs and flags anomalies or abuse over an extended period -of time. The ekscloudwatch project forwards audit log events from -CloudWatch to Falco for analysis. Falco provides a set of -default -audit rules along with the ability to add your own.

-
-
-

Yet another option might be to store the audit logs in S3 and use the -SageMaker -Random -Cut Forest algorithm to anomalous behaviors that warrant further -investigation.

-
-
-
-
-

10.2. Tools and resources

-
-

The following commercial and open source projects can be used to assess -your cluster’s alignment with established best practices:

-
-
- -
-
-
-
-
-

11. Network security

-
-
-

Network security has several facets. The first involves the application -of rules which restrict the flow of network traffic between services. -The second involves the encryption of traffic while it is in transit. -The mechanisms to implement these security measures on EKS are varied -but often include the following items:

-
-
-

11.1. Traffic control

-
-
    -
  • -

    Network Policies

    -
  • -
  • -

    Security Groups

    -
  • -
-
-
-
-

11.2. Network encryption

-
-
    -
  • -

    Service Mesh

    -
  • -
  • -

    Container Network Interfaces (CNIs)

    -
  • -
  • -

    Ingress Controllers and Load Balancers

    -
  • -
  • -

    Nitro Instances

    -
  • -
  • -

    ACM Private CA with cert-manager

    -
  • -
-
-
-
-

11.3. Network policy

-
-

Within a Kubernetes cluster, all Pod to Pod communication is allowed by -default. While this flexibility may help promote experimentation, it is -not considered secure. Kubernetes network policies give you a mechanism -to restrict network traffic between Pods (often referred to as East/West -traffic) as well as between Pods and external services. Kubernetes -network policies operate at layers 3 and 4 of the OSI model. Network -policies use pod, namespace selectors and labels to identify source and -destination pods, but can also include IP addresses, port numbers, -protocols, or a combination of these. Network Policies can be applied to -both Inbound or Outbound connections to the pod, often called Ingress -and Egress rules.

-
-
-

With native network policy support of Amazon VPC CNI Plugin, you can -implement network policies to secure network traffic in kubernetes -clusters. This integrates with the upstream Kubernetes Network Policy -API, ensuring compatibility and adherence to Kubernetes standards. You -can define policies using different -identifiers -supported by the upstream API. By default, all ingress and egress -traffic is allowed to a pod. When a network policy with a policyType -Ingress is specified, only allowed connections into the pod are those -from the pod’s node and those allowed by the ingress rules. Same applies -for egress rules. If multiple rules are defined, then union of all rules -are taken into account when making the decision. Thus, order of -evaluation does not affect the policy result.

-
-
-

!!! attention When you first provision an EKS cluster, VPC CNI Network -Policy functionality is not enabled by default. Ensure you deployed -supported VPC CNI Add-on version and set ENABLE_NETWORK_POLICY flag -to true on the vpc-cni add-on to enable this. Refer -Amazon -EKS User guide for detailed instructions.

-
-
-
-

11.4. Recommendations

-
-

11.4.1. Getting Started with Network Policies - Follow Principle of Least Privilege

-
-
Create a default deny policy
-
-

As with RBAC policies, it is recommended to follow least privileged -access principles with network policies. Start by creating a deny all -policy that restricts all inbound and outbound traffic with in a -namespace.

-
-
-
-
apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
-  name: default-deny
-  namespace: default
-spec:
-  podSelector: {}
-  policyTypes:
-  - Ingress
-  - Egress
-
-
-
-
-default-deny -
-
Figure 3. default-deny
-
-
-

!!! tip The image above was created by the network policy viewer from -Tufin.

-
-
-
-
Create a rule to allow DNS queries
-
-

Once you have the default deny all rule in place, you can begin layering -on additional rules, such as a rule that allows pods to query CoreDNS -for name resolution.

-
-
-
-
apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
-  name: allow-dns-access
-  namespace: default
-spec:
-  podSelector:
-    matchLabels: {}
-  policyTypes:
-  - Egress
-  egress:
-  - to:
-    - namespaceSelector:
-        matchLabels:
-          kubernetes.io/metadata.name: kube-system
-      podSelector:
-        matchLabels:
-          k8s-app: kube-dns
-    ports:
-    - protocol: UDP
-      port: 53
-
-
-
-
-allow-dns-access -
-
Figure 4. allow-dns-access
-
-
-
-
Incrementally add rules to selectively allow the flow of traffic between namespaces/pods
-
-

Understand the application requirements and create fine-grained ingress -and egress rules as needed. Below example shows how to restrict ingress -traffic on port 80 to app-one from client-one. This helps -minimize the attack surface and reduces the risk of unauthorized access.

-
-
-
-
apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
-  name: allow-ingress-app-one
-  namespace: default
-spec:
-  podSelector:
-    matchLabels:
-      k8s-app: app-one
-  policyTypes:
-  - Ingress
-  ingress:
-  - from:
-    - podSelector:
-        matchLabels:
-          k8s-app: client-one
-    ports:
-    - protocol: TCP
-      port: 80
-
-
-
-
-allow-ingress-app-one -
-
Figure 5. allow-ingress-app-one
-
-
-
-
-

11.4.2. Monitoring network policy enforcement

-
-
    -
  • -

    Use Network Policy editor

    -
    -
      -
    • -

      Network policy editor helps with -visualizations, security score, autogenerates from network flow logs

      -
    • -
    • -

      Build network policies in an interactive way

      -
    • -
    -
    -
  • -
  • -

    Audit Logs

    -
    -
      -
    • -

      Regularly review audit logs of your EKS cluster

      -
    • -
    • -

      Audit logs provide wealth of information about what actions have been -performed on your cluster including changes to network policies

      -
    • -
    • -

      Use this information to track changes to your network policies over -time and detect any unauthorized or unexpected changes

      -
    • -
    -
    -
  • -
  • -

    Automated testing

    -
    -
      -
    • -

      Implement automated testing by creating a test environment that -mirrors your production environment and periodically deploy workloads -that attempt to violate your network policies.

      -
    • -
    -
    -
  • -
  • -

    Monitoring metrics

    -
    -
      -
    • -

      Configure your observability agents to scrape the prometheus metrics -from the VPC CNI node agents, that allows to monitor the agent health, -and sdk errors.

      -
    • -
    -
    -
  • -
  • -

    Audit Network Policies regularly

    -
    -
      -
    • -

      Periodically audit your Network Policies to make sure that they meet -your current application requirements. As your application evolves, an -audit gives you the opportunity to remove redundant ingress, egress -rules and make sure that your applications don’t have excessive -permissions.

      -
    • -
    -
    -
  • -
  • -

    Ensure Network Policies exists using Open Policy Agent (OPA)

    -
    -
      -
    • -

      Use OPA Policy like shown below to ensure Network Policy always -exists before onboarding application pods. This policy denies onboarding -k8s pods with a label k8s-app: sample-app if corresponding network -policy does not exist.

      -
    • -
    -
    -
  • -
-
-
-
-
package kubernetes.admission
-import data.kubernetes.networkpolicies
-
-deny[msg] {
-    input.request.kind.kind == "Pod"
-    pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels}
-    contains_label(pod_label_value, "sample-app")
-    np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels}
-    not contains_label(np_label_value, "sample-app")
-    msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name])
-}
-contains_label(arr, val) {
-    arr[_] == val
-}
-
-
-
-
-

11.4.3. Troubleshooting

-
-
Monitor the vpc-network-policy-controller, node-agent logs
-
-

Enable the EKS Control plane controller manager logs to diagnose the -network policy functionality. You can stream the control plane logs to a -CloudWatch log group and use -CloudWatch -Log insights to perform advanced queries. From the logs, you can view -what pod endpoint objects are resolved to a Network Policy, -reconcilation status of the policies, and debug if the policy is working -as expected.

-
-
-

In addition, Amazon VPC CNI allows you to enable the collection and -export of policy enforcement logs to -Amazon Cloudwatch from the EKS -worker nodes. Once enabled, you can leverage -CloudWatch -Container Insights to provide insights on your usage related to Network -Policies.

-
-
-

Amazon VPC CNI also ships an SDK that provides an interface to interact -with eBPF programs on the node. The SDK is installed when the -aws-node is deployed onto the nodes. You can find the SDK binary -installed under /opt/cni/bin directory on the node. At launch, the -SDK provides support for fundamental functionalities such as inspecting -eBPF programs and maps.

-
-
-
-
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
-
-
-
-
-
Log network traffic metadata
-
-

AWS VPC -Flow Logs captures metadata about the traffic flowing through a VPC, -such as source and destination IP address and port along with -accepted/dropped packets. This information could be analyzed to look for -suspicious or unusual activity between resources within the VPC, -including Pods. However, since the IP addresses of pods frequently -change as they are replaced, Flow Logs may not be sufficient on its own. -Calico Enterprise extends the Flow Logs with pod labels and other -metadata, making it easier to decipher the traffic flows between pods.

-
-
-
-
-
-

11.5. Security groups

-
-

EKS uses -AWS -VPC Security Groups (SGs) to control the traffic between the Kubernetes -control plane and the cluster’s worker nodes. Security groups are also -used to control the traffic between worker nodes, and other VPC -resources, and external IP addresses. When you provision an EKS cluster -(with Kubernetes version 1.14-eks.3 or greater), a cluster security -group is automatically created for you. This security group allows -unfettered communication between the EKS control plane and the nodes -from managed node groups. For simplicity, it is recommended that you add -the cluster SG to all node groups, including unmanaged node groups.

-
-
-

Prior to Kubernetes version 1.14 and EKS version eks.3, there were -separate security groups configured for the EKS control plane and node -groups. The minimum and suggested rules for the control plane and node -group security groups can be found at -https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html. -The minimum rules for the control plane security group allows port 443 -inbound from the worker node SG. This rule is what allows the kubelets -to communicate with the Kubernetes API server. It also includes port -10250 for outbound traffic to the worker node SG; 10250 is the port that -the kubelets listen on. Similarly, the minimum node group rules allow -port 10250 inbound from the control plane SG and 443 outbound to the -control plane SG. Finally there is a rule that allows unfettered -communication between nodes within a node group.

-
-
-

If you need to control communication between services that run within -the cluster and service the run outside the cluster such as an RDS -database, consider -security -groups for pods. With security groups for pods, you can assign an -existing security group to a collection of pods.

-
-
-

!!! warning If you reference a security group that does not exist prior -to the creation of the pods, the pods will not get scheduled.

-
-
-

You can control which pods are assigned to a security group by creating -a SecurityGroupPolicy object and specifying a PodSelector or a -ServiceAccountSelector. Setting the selectors to {} will assign -the SGs referenced in the SecurityGroupPolicy to all pods in a -namespace or all Service Accounts in a namespace. Be sure you’ve -familiarized yourself with all the -considerations -before implementing security groups for pods.

-
-
-

!!! important If you use SGs for pods you must create SGs that allow -port 53 outbound to the cluster security group. Similarly, you must -update the cluster security group to accept port 53 inbound traffic from -the pod security group.

-
-
-

!!! important The -limits -for security groups still apply when using security groups for pods so -use them judiciously.

-
-
-

!!! important You must create rules for inbound traffic from the -cluster security group (kubelet) for all of the probes configured for -pod.

-
-
-

!!! important Security groups for pods relies on a feature known as -ENI -trunking which was created to increase the ENI density of an EC2 -instance. When a pod is assigned to an SG, a VPC controller associates a -branch ENI from the node group with the pod. If there aren’t enough -branch ENIs available in a node group at the time the pod is scheduled, -the pod will stay in pending state. The number of branch ENIs an -instance can support varies by instance type/family. See -https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types -for further details.

-
-
-

While security groups for pods offers an AWS-native way to control -network traffic within and outside of your cluster without the overhead -of a policy daemon, other options are available. For example, the Cilium -policy engine allows you to reference a DNS name in a network policy. -Calico Enterprise includes an option for mapping network policies to AWS -security groups. If you’ve implemented a service mesh like Istio, you -can use an egress gateway to restrict network egress to specific, fully -qualified domains or IP addresses. For further information about this -option, read the three part series on -egress -traffic control in Istio.

-
-
-
-

11.6. When to use Network Policy vs Security Group for Pods?

-
-

11.6.1. When to use Kubernetes network policy

-
-
    -
  • -

    Controlling pod-to-pod traffic

    -
    -
      -
    • -

      Suitable for controlling network traffic between pods inside a -cluster (east-west traffic)

      -
    • -
    -
    -
  • -
  • -

    Control traffic at the IP address or port level (OSI layer 3 or 4)

    -
  • -
-
-
-
-

11.6.2. When to use AWS Security groups for pods (SGP)

-
-
    -
  • -

    Leverage existing AWS configurations

    -
    -
      -
    • -

      If you already have complex set of EC2 security groups that manage -access to AWS services and you are migrating applications from EC2 -instances to EKS, SGPs can be a very good choice allowing you to reuse -security group resources and apply them to your pods.

      -
    • -
    -
    -
  • -
  • -

    Control access to AWS services

    -
    -
      -
    • -

      Your applications running within an EKS cluster wants to communicate -with other AWS services (RDS database), use SGPs as an efficient -mechanism to control the traffic from the pods to AWS services.

      -
    • -
    -
    -
  • -
  • -

    Isolation of Pod & Node traffic

    -
    -
      -
    • -

      If you want to completely separate pod traffic from the rest of the -node traffic, use SGP in POD_SECURITY_GROUP_ENFORCING_MODE=strict -mode.

      -
    • -
    -
    -
  • -
-
-
-
-

11.6.3. Best practices using Security groups for pods and Network Policy

-
-
    -
  • -

    Layered security

    -
    -
      -
    • -

      Use a combination of SGP and kubernetes network policy for a layered -security approach

      -
    • -
    • -

      Use SGPs to limit network level access to AWS services that are not -part of a cluster, while kubernetes network policies can restrict -network traffic between pods inside the cluster

      -
    • -
    -
    -
  • -
  • -

    Principle of least privilege

    -
    -
      -
    • -

      Only allow necessary traffic between pods or namespaces

      -
    • -
    -
    -
  • -
  • -

    Segment your applications

    -
    -
      -
    • -

      Wherever possible, segment applications by the network policy to -reduce the blast radius if an application is compromised

      -
    • -
    -
    -
  • -
  • -

    Keep policies simple and clear

    -
    -
      -
    • -

      Kubernetes network policies can be quite granular and complex, its -best to keep them as simple as possible to reduce the risk of -misconfiguration and ease the management overhead

      -
    • -
    -
    -
  • -
  • -

    Reduce the attack surface

    -
    -
      -
    • -

      Minimize the attack surface by limiting the exposure of your -applications

      -
    • -
    -
    -
  • -
-
-
-

!!! attention Security Groups for pods provides two enforcing modes: -strict and standard. You must use standard mode when using -both Network Policy and Security Groups for pods features in an EKS -cluster.

-
-
-

When it comes to network security, a layered approach is often the most -effective solution. Using kubernetes network policy and SGP in -combination can provide a robust defense-in-depth strategy for your -applications running in EKS.

-
-
-
-
-

11.7. Service Mesh Policy Enforcement or Kubernetes network policy

-
-

A service mesh is a dedicated infrastructure layer that you can add -to your applications. It allows you to transparently add capabilities -like observability, traffic management, and security, without adding -them to your own code.

-
-
-

Service mesh enforces policies at Layer 7 (application) of OSI model -whereas kubernetes network policies operate at Layer 3 (network) and -Layer 4 (transport). There are many offerings in this space like AWS -AppMesh, Istio, Linkerd, etc.,

-
-
-

11.7.1. When to use Service mesh for policy enforcement

-
-
    -
  • -

    Have existing investment in a service mesh

    -
  • -
  • -

    Need more advanced capabilities like traffic management, observability -& security

    -
    -
      -
    • -

      Traffic control, load balancing, circuit breaking, rate limiting, -timeouts etc.

      -
    • -
    • -

      Detailed insights into how your services are performing (latency, -error rates, requests per second, request volumes etc.)

      -
    • -
    • -

      You want to implement and leverage service mesh for security features -like mTLS

      -
    • -
    -
    -
  • -
-
-
-
-

11.7.2. Choose Kubernetes network policy for simpler use cases

-
-
    -
  • -

    Limit which pods can communicate with each other

    -
  • -
  • -

    Network policies require fewer resources than a service mesh making -them a good fit for simpler use cases or for smaller clusters where the -overhead of running and managing a service mesh might not be justified

    -
  • -
-
-
-

!!! tip Network policies and Service mesh can also be used together. Use -network policies to provide a baseline level of security and isolation -between your pods and then use a service mesh to add additional -capabilities like traffic management, observability and security.

-
-
-
-
-

11.8. ThirdParty Network Policy Engines

-
-

Consider a Third Party Network Policy Engine when you have advanced -policy requirements like Global Network Policies, support for DNS -Hostname based rules, Layer 7 rules, ServiceAccount based rules, and -explicit deny/log actions, etc., -Calico, is an open source -policy engine from Tigera that works well with EKS. -In addition to implementing the full set of Kubernetes network policy -features, Calico supports extended network polices with a richer set of -features, including support for layer 7 rules, e.g. HTTP, when -integrated with Istio. Calico policies can be scoped to Namespaces, -Pods, service accounts, or globally. When policies are scoped to a -service account, it associates a set of ingress/egress rules with that -service account. With the proper RBAC rules in place, you can prevent -teams from overriding these rules, allowing IT security professionals to -safely delegate administration of namespaces. Isovalent, the maintainers -of Cilium, have also -extended the network policies to include partial support for layer 7 -rules, e.g. HTTP. Cilium also has support for DNS hostnames which can be -useful for restricting traffic between Kubernetes Services/Pods and -resources that run within or outside of your VPC. By contrast, Calico -Enterprise includes a feature that allows you to map a Kubernetes -network policy to an AWS security group, as well as DNS hostnames.

-
-
-

You can find a list of common Kubernetes network policies at -https://github.com/ahmetb/kubernetes-network-policy-recipes. A similar -set of rules for Calico are available at -https://docs.projectcalico.org/security/calico-network-policy.

-
-
-

11.8.1. Migration to Amazon VPC CNI Network Policy Engine

-
-

To maintain consistency and avoid unexpected pod communication behavior, -it is recommended to deploy only one Network Policy Engine in your -cluster. If you want to migrate from 3P to VPC CNI Network Policy -Engine, we recommend converting your existing 3P NetworkPolicy CRDs to -the Kubernetes NetworkPolicy resources before enabling VPC CNI network -policy support. And, test the migrated policies in a separate test -cluster before applying them in you production environment. This allows -you to identify and address any potential issues or inconsistencies in -pod communication behavior.

-
-
-
Migration Tool
-
-

To assist in your migration process, we have developed a tool called -K8s Network -Policy Migrator that converts your existing Calico/Cilium network -policy CRDs to Kubernetes native network policies. After conversion you -can directly test the converted network policies on your new clusters -running VPC CNI network policy controller. The tool is designed to help -you streamline the migration process and ensure a smooth transition.

-
-
-

!!! Important Migration tool will only convert 3P policies that are -compatible with native kubernetes network policy api. If you are using -advanced network policy features offered by 3P plugins, Migration tool -will skip and report them.

-
-
-

Please note that migration tool is currently not supported by AWS VPC -CNI Network policy engineering team, it is made available to customers -on a best-effort basis. We encourage you to utilize this tool to -facilitate your migration process. In the event that you encounter any -issues or bugs with the tool, we kindly ask you create a -GitHub -issue. Your feedback is invaluable to us and will assist in the -continuous improvement of our services.

-
-
-
-
-

11.8.2. Additional Resources

-
- -
-
-
-
-

11.9. Encryption in transit

-
-

Applications that need to conform to PCI, HIPAA, or other regulations -may need to encrypt data while it is in transit. Nowadays TLS is the de -facto choice for encrypting traffic on the wire. TLS, like it’s -predecessor SSL, provides secure communications over a network using -cryptographic protocols. TLS uses symmetric encryption where the keys to -encrypt the data are generated based on a shared secret that is -negotiated at the beginning of the session. The following are a few ways -that you can encrypt data in a Kubernetes environment.

-
-
-

11.9.1. Nitro Instances

-
-

Traffic exchanged between the following Nitro instance types, e.g. C5n, -G4, I3en, M5dn, M5n, P3dn, R5dn, and R5n, is automatically encrypted by -default. When there’s an intermediate hop, like a transit gateway or a -load balancer, the traffic is not encrypted. See -Encryption -in transit for further details on encryption in transit as well as the -complete list of instances types that support network encryption by -default.

-
-
-
-

11.9.2. Container Network Interfaces (CNIs)

-
-

WeaveNet can be configured to -automatically encrypt all traffic using NaCl encryption for sleeve -traffic, and IPsec ESP for fast datapath traffic.

-
-
-
-

11.9.3. Service Mesh

-
-

Encryption in transit can also be implemented with a service mesh like -App Mesh, Linkerd v2, and Istio. AppMesh supports -mTLS -with X.509 certificates or Envoy’s Secret Discovery Service(SDS). -Linkerd and Istio both have support for mTLS.

-
-
-

The aws-app-mesh-examples -GitHub repository provides walkthroughs for configuring mTLS using X.509 -certificates and SPIRE as SDS provider with your Envoy container:

-
- -
-

App Mesh also supports -TLS -encryption with a private certificate issued by -AWS -Certificate Manager (ACM) or a certificate stored on the local file -system of the virtual node.

-
-
-

The aws-app-mesh-examples -GitHub repository provides walkthroughs for configuring TLS using -certificates issued by ACM and certificates that are packaged with your -Envoy container:

-
- -
-
-

11.9.4. Ingress Controllers and Load Balancers

-
-

Ingress controllers are a way for you to intelligently route HTTP/S -traffic that emanates from outside the cluster to services running -inside the cluster. Oftentimes, these Ingresses are fronted by a layer 4 -load balancer, like the Classic Load Balancer or the Network Load -Balancer (NLB). Encrypted traffic can be terminated at different places -within the network, e.g. at the load balancer, at the ingress resource, -or the Pod. How and where you terminate your SSL connection will -ultimately be dictated by your organization’s network security policy. -For instance, if you have a policy that requires end-to-end encryption, -you will have to decrypt the traffic at the Pod. This will place -additional burden on your Pod as it will have to spend cycles -establishing the initial handshake. Overall SSL/TLS processing is very -CPU intensive. Consequently, if you have the flexibility, try performing -the SSL offload at the Ingress or the load balancer.

-
-
-
Use encryption with AWS Elastic load balancers
-
-

The -AWS -Application Load Balancer (ALB) and -Network -Load Balancer (NLB) both have support for transport encryption (SSL and -TLS). The alb.ingress.kubernetes.io/certificate-arn annotation for -the ALB lets you to specify which certificates to add to the ALB. If you -omit the annotation the controller will attempt to add certificates to -listeners that require it by matching the available -AWS -Certificate Manager (ACM) certificates using the host field. Starting -with EKS v1.15 you can use the -service.beta.kubernetes.io/aws-load-balancer-ssl-cert annotation -with the NLB as shown in the example below.

-
-
-
-
apiVersion: v1
-kind: Service
-metadata:
-  name: demo-app
-  namespace: default
-  labels:
-    app: demo-app
-  annotations:
-     service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
-     service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<certificate ARN>"
-     service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
-     service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
-spec:
-  type: LoadBalancer
-  ports:
-  - port: 443
-    targetPort: 80
-    protocol: TCP
-  selector:
-    app: demo-app
----
-kind: Deployment
-apiVersion: apps/v1
-metadata:
-  name: nginx
-  namespace: default
-  labels:
-    app: demo-app
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: demo-app
-  template:
-    metadata:
-      labels:
-        app: demo-app
-    spec:
-      containers:
-        - name: nginx
-          image: nginx
-          ports:
-            - containerPort: 443
-              protocol: TCP
-            - containerPort: 80
-              protocol: TCP
-
-
-
-

Following are additional examples for SSL/TLS termination.

-
- -
-

!!! attention Some Ingresses, like the AWS LB controller, implement the -SSL/TLS using Annotations instead of as part of the Ingress Spec.

-
-
-
-
-

11.9.5. ACM Private CA with cert-manager

-
-

You can enable TLS and mTLS to secure your EKS application workloads at -the ingress, on the pod, and between pods using ACM Private Certificate -Authority (CA) and cert-manager, a popular -Kubernetes add-on to distribute, renew, and revoke certificates. ACM -Private CA is a highly-available, secure, managed CA without the upfront -and maintenance costs of managing your own CA. If you are using the -default Kubernetes certificate authority, there is an opportunity to -improve your security and meet compliance requirements with ACM Private -CA. ACM Private CA secures private keys in FIPS 140-2 Level 3 hardware -security modules (very secure), compared with the default CA storing -keys encoded in memory (less secure). A centralized CA also gives you -more control and improved auditability for private certificates both -inside and outside of a Kubernetes environment.

-
-
-
Short-Lived CA Mode for Mutual TLS Between Workloads
-
-

When using ACM Private CA for mTLS in EKS, it is recommended that you -use short lived certificates with short-lived CA mode. Although it is -possible to issue out short-lived certificates in the general-purpose CA -mode, using short-lived CA mode works out more cost-effective (~75% -cheaper than general mode) for use cases where new certificates need to -be issued frequently. In addition to this, you should try to align the -validity period of the private certificates with the lifetime of the -pods in your EKS cluster. -Learn -more about ACM Private CA and its benefits here.

-
-
-
-
ACM Setup Instructions
-
-

Start by creating a Private CA by following procedures provided in the -ACM -Private CA tech docs. Once you have a Private CA, install cert-manager -using regular installation -instructions. After installing cert-manager, install the Private CA -Kubernetes cert-manager plugin by following the -setup -instructions in GitHub. The plugin lets cert-manager request private -certificates from ACM Private CA.

-
-
-

Now that you have a Private CA and an EKS cluster with cert-manager and -the plugin installed, it’s time to set permissions and create the -issuer. Update IAM permissions of the EKS node role to allow access to -ACM Private CA. Replace the <CA_ARN> with the value from your -Private CA:

-
-
-
-
{
-    "Version": "2012-10-17",
-    "Statement": [
-        {
-            "Sid": "awspcaissuer",
-            "Action": [
-                "acm-pca:DescribeCertificateAuthority",
-                "acm-pca:GetCertificate",
-                "acm-pca:IssueCertificate"
-            ],
-            "Effect": "Allow",
-            "Resource": "<CA_ARN>"
-        }
-    ]
-}
-
-
-
-

Service -Roles for IAM Accounts, or IRSA can also be used. Please see the -Additional Resources section below for complete examples.

-
-
-

Create an Issuer in Amazon EKS by creating a Custom Resource Definition -file named cluster-issuer.yaml with the following text in it, replacing -<CA_ARN> and <Region> information with your Private CA.

-
-
-
-
apiVersion: awspca.cert-manager.io/v1beta1
-kind: AWSPCAClusterIssuer
-metadata:
-          name: demo-test-root-ca
-spec:
-          arn: <CA_ARN>
-          region: <Region>
-
-
-
-

Deploy the Issuer you created.

-
-
-
-
kubectl apply -f cluster-issuer.yaml
-
-
-
-

Your EKS cluster is configured to request certificates from Private CA. -You can now use cert-manager’s Certificate resource to issue -certificates by changing the issuerRef field’s values to the Private -CA Issuer you created above. For more details on how to specify and -request Certificate resources, please check cert-manager’s -Certificate Resources -guide. -See -examples here.

-
-
-
-
-

11.9.6. ACM Private CA with Istio and cert-manager

-
-

If you are running Istio in your EKS cluster, you can disable the Istio -control plane (specifically istiod) from functioning as the root -Certificate Authority (CA), and configure ACM Private CA as the root CA -for mTLS between workloads. If you’re going with this approach, consider -using the short-lived CA mode in ACM Private CA. Refer to the -previous -section and this -blog -post for more details.

-
-
-
How Certificate Signing Works in Istio (Default)
-
-

Workloads in Kubernetes are identified using service accounts. If you -don’t specify a service account, Kubernetes will automatically assign -one to your workload. Also, service accounts automatically mount an -associated token. This token is used by the service account for -workloads to authenticate against the Kubernetes API. The service -account may be sufficient as an identity for Kubernetes but Istio has -its own identity management system and CA. When a workload starts up -with its envoy sidecar proxy, it needs an identity assigned from Istio -in order for it to be deemed as trustworthy and allowed to communicate -with other services in the mesh.

-
-
-

To get this identity from Istio, the istio-agent sends a request -known as a certificate signing request (or CSR) to the Istio control -plane. This CSR contains the service account token so that the -workload’s identity can be verified before being processed. This -verification process is handled by istiod, which acts as both the -Registration Authority (or RA) and the CA. The RA serves as a gatekeeper -that makes sure only verified CSR makes it through to the CA. Once the -CSR is verified, it will be forwarded to the CA which will then issue a -certificate containing a SPIFFE identity with the -service account. This certificate is called a SPIFFE verifiable identity -document (or SVID). The SVID is assigned to the requesting service for -identification purposes and to encrypt the traffic in transit between -the communicating services.

-
-
-
Default flow for Istio Certificate Signing Requests
-

image::./images/default-istio-csr-flow.png[Default flow for Istio -Certificate Signing Requests]

-
-
-
-
How Certificate Signing Works in Istio with ACM Private CA
-
-

You can use a cert-manager add-on called the Istio Certificate Signing -Request agent -(istio-csr) to -integrate Istio with ACM Private CA. This agent allows Istio workloads -and control plane components to be secured with cert manager issuers, in -this case ACM Private CA. The istio-csr agent exposes the same service -that istiod serves in the default config of validating incoming CSRs. -Except, after verification, it will convert the requests into resources -that cert manager supports (i.e. integrations with external CA issuers).

-
-
-

Whenever there’s a CSR from a workload, it will be forwarded to -istio-csr, which will request certificates from ACM Private CA. This -communication between istio-csr and ACM Private CA is enabled by the -AWS Private CA -issuer plugin. Cert manager uses this plugin to request TLS -certificates from ACM Private CA. The issuer plugin will communicate -with the ACM Private CA service to request a signed certificate for the -workload. Once the certificate has been signed, it will be returned to -istio-csr, which will read the signed request, and return it to the -workload that initiated the CSR.

-
-
-
Flow for Istio Certificate Signing Requests with istio-csr
-

image::./images/istio-csr-with-acm-private-ca.png[Flow for Istio -Certificate Signing Requests with istio-csr]

-
-
-
-
Istio with Private CA Setup Instructions
-
-
    -
  1. -

    Start by following the same -setup instructions in this -section to complete the following:

    -
  2. -
  3. -

    Create a Private CA

    -
  4. -
  5. -

    Install cert-manager

    -
  6. -
  7. -

    Install the issuer plugin

    -
  8. -
  9. -

    Set permissions and create an issuer. The issuer represents the CA and -is used to sign istiod and mesh workload certificates. It will -communicate with ACM Private CA.

    -
  10. -
  11. -

    Create an istio-system namespace. This is where the -istiod certificate and other Istio resources will be deployed.

    -
  12. -
  13. -

    Install Istio CSR configured with AWS Private CA Issuer Plugin. You -can preserve the certificate signing requests for workloads to verify -that they get approved and signed -(preserveCertificateRequests=true).

    -
    -
    -
    helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \
    ---set "app.certmanager.issuer.group=awspca.cert-manager.io" \
    ---set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \
    ---set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \
    ---set "app.certmanager.preserveCertificateRequests=true" \
    ---set "app.server.maxCertificateDuration=48h" \
    ---set "app.tls.certificateDuration=24h" \
    ---set "app.tls.istiodCertificateDuration=24h" \
    ---set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \
    ---set "volumeMounts[0].name=root-ca" \
    ---set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \
    ---set "volumes[0].name=root-ca" \
    ---set "volumes[0].secret.secretName=istio-root-ca"
    -
    -
    -
  14. -
  15. -

    Install Istio with custom configurations to replace istiod with -cert-manager istio-csr as the certificate provider for the mesh. -This process can be carried out using the -Istio Operator.

    -
    -
    -
    apiVersion: install.istio.io/v1alpha1
    -kind: IstioOperator
    -metadata:
    -  name: istio
    -  namespace: istio-system
    -spec:
    -  profile: "demo"
    -  hub: gcr.io/istio-release
    -  values:
    -  global:
    -    # Change certificate provider to cert-manager istio agent for istio agent
    -    caAddress: cert-manager-istio-csr.cert-manager.svc:443
    -  components:
    -    pilot:
    -      k8s:
    -        env:
    -          # Disable istiod CA Sever functionality
    -        - name: ENABLE_CA_SERVER
    -          value: "false"
    -        overlays:
    -        - apiVersion: apps/v1
    -          kind: Deployment
    -          name: istiod
    -          patches:
    -
    -            # Mount istiod serving and webhook certificate from Secret mount
    -          - path: spec.template.spec.containers.[name:discovery].args[7]
    -            value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt"
    -          - path: spec.template.spec.containers.[name:discovery].args[8]
    -            value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key"
    -          - path: spec.template.spec.containers.[name:discovery].args[9]
    -            value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem"
    -
    -          - path: spec.template.spec.containers.[name:discovery].volumeMounts[6]
    -            value:
    -              name: cert-manager
    -              mountPath: "/etc/cert-manager/tls"
    -              readOnly: true
    -          - path: spec.template.spec.containers.[name:discovery].volumeMounts[7]
    -            value:
    -              name: ca-root-cert
    -              mountPath: "/etc/cert-manager/ca"
    -              readOnly: true
    -
    -          - path: spec.template.spec.volumes[6]
    -            value:
    -              name: cert-manager
    -              secret:
    -                secretName: istiod-tls
    -          - path: spec.template.spec.volumes[7]
    -            value:
    -              name: ca-root-cert
    -              configMap:
    -                defaultMode: 420
    -                name: istio-ca-root-cert
    -
    -
    -
  16. -
  17. -

    Deploy the above custom resource you created.

    -
    -
    -
    istioctl operator init
    -kubectl apply -f istio-custom-config.yaml
    -
    -
    -
  18. -
  19. -

    Now you can deploy a workload to the mesh in your EKS cluster and -enforce -mTLS.

    -
  20. -
-
-
-
Istio certificate signing requests
-

image::./images/istio-csr-requests.png[Istio certificate signing -requests]

-
-
-
-
-
-

11.10. Tools and resources

- -
-
-
-
-

12. Data encryption and secrets management

-
-
-

12.1. Encryption at rest

-
-

There are three different AWS-native storage options you can use with -Kubernetes: -EBS, -EFS, -and FSx -for Lustre. All three offer encryption at rest using a service managed -key or a customer master key (CMK). For EBS you can use the in-tree -storage driver or the -EBS CSI driver. -Both include parameters for encrypting volumes and supplying a CMK. For -EFS, you can use the -EFS CSI driver, -however, unlike EBS, the EFS CSI driver does not support dynamic -provisioning. If you want to use EFS with EKS, you will need to -provision and configure at-rest encryption for the file system prior to -creating a PV. For further information about EFS file encryption, please -refer to -Encrypting -Data at Rest. Besides offering at-rest encryption, EFS and FSx for -Lustre include an option for encrypting data in transit. FSx for Lustre -does this by default. For EFS, you can add transport encryption by -adding the tls parameter to mountOptions in your PV as in this -example:

-
-
-
-
apiVersion: v1
-kind: PersistentVolume
-metadata:
-  name: efs-pv
-spec:
-  capacity:
-    storage: 5Gi
-  volumeMode: Filesystem
-  accessModes:
-    - ReadWriteOnce
-  persistentVolumeReclaimPolicy: Retain
-  storageClassName: efs-sc
-  mountOptions:
-    - tls
-  csi:
-    driver: efs.csi.aws.com
-    volumeHandle: <file_system_id>
-
-
-
-

The FSx CSI -driver supports dynamic provisioning of Lustre file systems. It -encrypts data with a service managed key by default, although there is -an option to provide your own CMK as in this example:

-
-
-
-
kind: StorageClass
-apiVersion: storage.k8s.io/v1
-metadata:
-  name: fsx-sc
-provisioner: fsx.csi.aws.com
-parameters:
-  subnetId: subnet-056da83524edbe641
-  securityGroupIds: sg-086f61ea73388fb6b
-  deploymentType: PERSISTENT_1
-  kmsKeyId: <kms_arn>
-
-
-
-

!!! attention As of May 28, 2020 all data written to the ephemeral -volume in EKS Fargate pods is encrypted by default using an -industry-standard AES-256 cryptographic algorithm. No modifications to -your application are necessary as encryption and decryption are handled -seamlessly by the service.

-
-
-

12.1.1. Encrypt data at rest

-
-

Encrypting data at rest is considered a best practice. If you’re unsure -whether encryption is necessary, encrypt your data.

-
-
-
-

12.1.2. Rotate your CMKs periodically

-
-

Configure KMS to automatically rotate your CMKs. This will rotate your -keys once a year while saving old keys indefinitely so that your data -can still be decrypted. For additional information see -Rotating -customer master keys

-
-
-
-

12.1.3. Use EFS access points to simplify access to shared datasets

-
-

If you have shared datasets with different POSIX file permissions or -want to restrict access to part of the shared file system by creating -different mount points, consider using EFS access points. To learn more -about working with access points, see -https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today, -if you want to use an access point (AP) you’ll need to reference the AP -in the PV’s volumeHandle parameter.

-
-
-

!!! attention As of March 23, 2021 the EFS CSI driver supports dynamic -provisioning of EFS Access Points. Access points are -application-specific entry points into an EFS file system that make it -easier to share a file system between multiple pods. Each EFS file -system can have up to 120 PVs. See -Introducing -Amazon EFS CSI dynamic provisioning for additional information.

-
-
-
-
-

12.2. Secrets management

-
-

Kubernetes secrets are used to store sensitive information, such as user -certificates, passwords, or API keys. They are persisted in etcd as -base64 encoded strings. On EKS, the EBS volumes for etcd nodes are -encrypted with -EBS -encryption. A pod can retrieve a Kubernetes secrets objects by -referencing the secret in the podSpec. These secrets can either be -mapped to an environment variable or mounted as volume. For additional -information on creating secrets, see -https://kubernetes.io/docs/concepts/configuration/secret/.

-
-
-

!!! caution Secrets in a particular namespace can be referenced by all -pods in the secret’s namespace.

-
-
-

!!! caution The node authorizer allows the Kubelet to read all of the -secrets mounted to the node.

-
-
-

12.2.1. Use AWS KMS for envelope encryption of Kubernetes secrets

-
-

This allows you to encrypt your secrets with a unique data encryption -key (DEK). The DEK is then encrypted using a key encryption key (KEK) -from AWS KMS which can be automatically rotated on a recurring schedule. -With the KMS plugin for Kubernetes, all Kubernetes secrets are stored in -etcd in ciphertext instead of plain text and can only be decrypted by -the Kubernetes API server. For additional details, see -using -EKS encryption provider support for defense in depth

-
-
-
-

12.2.2. Audit the use of Kubernetes Secrets

-
-

On EKS, turn on audit logging and create a CloudWatch metrics filter and -alarm to alert you when a secret is used (optional). The following is an -example of a metrics filter for the Kubernetes audit log, -{($.verb="get") && ($.objectRef.resource="secret")}. You can also -use the following queries with CloudWatch Log Insights:

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| stats count(*) by objectRef.name as secret
-| filter verb="get" and objectRef.resource="secrets"
-
-
-
-

The above query will display the number of times a secret has been -accessed within a specific timeframe.

-
-
-
-
fields @timestamp, @message
-| sort @timestamp desc
-| limit 100
-| filter verb="get" and objectRef.resource="secrets"
-| display objectRef.namespace, objectRef.name, user.username, responseStatus.code
-
-
-
-

This query will display the secret, along with the namespace and -username of the user who attempted to access the secret and the response -code.

-
-
-
-

12.2.3. Rotate your secrets periodically

-
-

Kubernetes doesn’t automatically rotate secrets. If you have to rotate -secrets, consider using an external secret store, e.g. Vault or AWS -Secrets Manager.

-
-
-
-

12.2.4. Use separate namespaces as a way to isolate secrets from different applications

-
-

If you have secrets that cannot be shared between applications in a -namespace, create a separate namespace for those applications.

-
-
-
-

12.2.5. Use volume mounts instead of environment variables

-
-

The values of environment variables can unintentionally appear in logs. -Secrets mounted as volumes are instantiated as tmpfs volumes (a RAM -backed file system) that are automatically removed from the node when -the pod is deleted.

-
-
-
-

12.2.6. Use an external secrets provider

-
-

There are several viable alternatives to using Kubernetes secrets, -including AWS Secrets Manager -and Hashicorp’s -Vault. -These services offer features such as fine grained access controls, -strong encryption, and automatic rotation of secrets that are not -available with Kubernetes Secrets. Bitnami’s -Sealed Secrets is -another approach that uses asymmetric encryption to create “sealed -secrets”. A public key is used to encrypt the secret while the private -key used to decrypt the secret is kept within the cluster, allowing you -to safely store sealed secrets in source control systems like Git. See -Managing -secrets deployment in Kubernetes using Sealed Secrets for further -information.

-
-
-

As the use of external secrets stores has grown, so has need for -integrating them with Kubernetes. The -Secret Store -CSI Driver is a community project that uses the CSI driver model to -fetch secrets from external secret stores. Currently, the Driver has -support for -AWS Secrets -Manager, Azure, Vault, and GCP. The AWS provider supports both AWS -Secrets Manager and AWS Parameter Store. It can also be configured to -rotate secrets when they expire and can synchronize AWS Secrets Manager -secrets to Kubernetes Secrets. Synchronization of secrets can be useful -when you need to reference a secret as an environment variable instead -of reading them from a volume.

-
-
-

!!! note When the the secret store CSI driver has to fetch a secret, it -assumes the IRSA role assigned to the pod that references a secret. The -code for this operation can be found -here.

-
-
-

For additional information about the AWS Secrets & Configuration -Provider (ASCP) refer to the following resources:

-
- -
-

external-secrets -is yet another way to use an external secret store with Kubernetes. Like -the CSI Driver, external-secrets works against a variety of different -backends, including AWS Secrets Manager. The difference is, rather than -retrieving secrets from the external secret store, external-secrets -copies secrets from these backends to Kubernetes as Secrets. This lets -you manage secrets using your preferred secret store and interact with -secrets in a Kubernetes-native way.

-
-
-
- -
-
-
-

13. Runtime security

-
-
-

Runtime security provides active protection for your containers while -they’re running. The idea is to detect and/or prevent malicious activity -from occurring inside the container. This can be achieved with a number -of mechanisms in the Linux kernel or kernel extensions that are -integrated with Kubernetes, such as Linux capabilities, secure computing -(seccomp), AppArmor, or SELinux. There are also options like Amazon -GuardDuty and third party tools that can assist with establishing -baselines and detecting anomalous activity with less manual -configuration of Linux kernel mechanisms.

-
-
-

!!! attention Kubernetes does not currently provide any native -mechanisms for loading seccomp, AppArmor, or SELinux profiles onto -Nodes. They either have to be loaded manually or installed onto Nodes -when they are bootstrapped. This has to be done prior to referencing -them in your Pods because the scheduler is unaware of which nodes have -profiles. See below how tools like Security Profiles Operator can help -automate provisioning of profiles onto nodes.

-
-
-

13.1. Security contexts and built-in Kubernetes controls

-
-

Many Linux runtime security mechanisms are tightly integrated with -Kubernetes and can be configured through Kubernetes -security -contexts. One such option is the privileged flag, which is -false by default and if enabled is essentially equivalent to root on -the host. It is nearly always inappropriate to enable privileged mode in -production workloads, but there are many more controls that can provide -more granular privileges to containers as appropriate.

-
-
-

13.1.1. Linux capabilities

-
-

Linux capabilities allow you to grant certain capabilities to a Pod or -container without providing all the abilities of the root user. Examples -include CAP_NET_ADMIN, which allows configuring network interfaces -or firewalls, or CAP_SYS_TIME, which allows manipulation of the -system clock.

-
-
-
-

13.1.2. Seccomp

-
-

With secure computing (seccomp) you can prevent a containerized -application from making certain syscalls to the underlying host -operating system’s kernel. While the Linux operating system has a few -hundred system calls, the lion’s share of them are not necessary for -running containers. By restricting what syscalls can be made by a -container, you can effectively decrease your application’s attack -surface.

-
-
-

Seccomp works by intercepting syscalls and only allowing those that have -been allowlisted to pass through. Docker has a -default -seccomp profile which is suitable for a majority of general purpose -workloads, and other container runtimes like containerd provide -comparable defaults. You can configure your container or Pod to use the -container runtime’s default seccomp profile by adding the following to -the securityContext section of the Pod spec:

-
-
-
-
securityContext:
-  seccompProfile:
-    type: RuntimeDefault
-
-
-
-

As of 1.22 (in alpha, stable as of 1.27), the above RuntimeDefault -can be used for all Pods on a Node using a -single -kubelet flag, --seccomp-default. Then the profile specified in -securityContext is only needed for other profiles.

-
-
-

It’s also possible to create your own profiles for things that require -additional privileges. This can be very tedious to do manually, but -there are tools like -Inspektor Gadget -(also recommended in the network security section for -generating network policies) and -Security Profiles -Operator that support using tools like eBPF or logs to record baseline -privilege requirements as seccomp profiles. Security Profiles Operator -further allows automating the deployment of recorded profiles to nodes -for use by Pods and containers.

-
-
-
-

13.1.3. AppArmor and SELinux

-
-

AppArmor and SELinux are known as -mandatory access -control or MAC systems. They are similar in concept to seccomp but with -different APIs and abilities, allowing access control for e.g. specific -filesystem paths or network ports. Support for these tools depends on -the Linux distribution, with Debian/Ubuntu supporting AppArmor and -RHEL/CentOS/Bottlerocket/Amazon Linux 2023 supporting SELinux. Also see -the infrastructure security section for -further discussion of SELinux.

-
-
-

Both AppArmor and SELinux are integrated with Kubernetes, but as of -Kubernetes 1.28 AppArmor profiles must be specified via -annotations -while SELinux labels can be set through the -SELinuxOptions -field on the security context directly.

-
-
-

As with seccomp profiles, the Security Profiles Operator mentioned above -can assist with deploying profiles onto nodes in the cluster. (In the -future, the project also aims to generate profiles for AppArmor and -SELinux as it does for seccomp.)

-
-
-
-
-

13.2. Recommendations

-
-

13.2.1. Use Amazon GuardDuty for runtime monitoring and detecting threats to your EKS environments

-
-

If you do not currently have a solution for continuously monitoring EKS -runtimes and analyzing EKS audit logs, and scanning for malware and -other suspicious activity, Amazon strongly recommends the use of -Amazon GuardDuty for customers who -want a simple, fast, secure, scalable, and cost-effective one-click way -to protect their AWS environments. Amazon GuardDuty is a security -monitoring service that analyzes and processes foundational data -sources, such as AWS CloudTrail management events, AWS CloudTrail event -logs, VPC flow logs (from Amazon EC2 instances), Kubernetes audit logs, -and DNS logs. It also includes EKS runtime monitoring. It uses -continuously updated threat intelligence feeds, such as lists of -malicious IP addresses and domains, and machine learning to identify -unexpected, potentially unauthorized, and malicious activity within your -AWS environment. This can include issues like escalation of privileges, -use of exposed credentials, or communication with malicious IP -addresses, domains, presence of malware on your Amazon EC2 instances and -EKS container workloads, or discovery of suspicious API activity. -GuardDuty informs you of the status of your AWS environment by producing -security findings that you can view in the GuardDuty console or through -Amazon EventBridge. GuardDuty also provides support for you to export -your findings to an Amazon Simple Storage Service (S3) bucket, and -integrate with other services such as AWS Security Hub and Detective.

-
-
-

Watch this AWS Online Tech Talk -“Enhanced threat detection -for Amazon EKS with Amazon GuardDuty - AWS Online Tech Talks” to see -how to enable these additional EKS security features step-by-step in -minutes.

-
-
-
-

13.2.2. Optionally: Use a 3rd party solution for runtime monitoring

-
-

Creating and managing seccomp and Apparmor profiles can be difficult if -you’re not familiar with Linux security. If you don’t have the time to -become proficient, consider using a 3rd party commercial solution. A lot -of them have moved beyond static profiles like Apparmor and seccomp and -have begun using machine learning to block or alert on suspicious -activity. A handful of these solutions can be found below in the -tools section. Additional options can be -found on the AWS -Marketplace for Containers.

-
-
-
-

13.2.3. Consider add/dropping Linux capabilities before writing seccomp policies

-
-

Capabilities involve various checks in kernel functions reachable by -syscalls. If the check fails, the syscall typically returns an error. -The check can be done either right at the beginning of a specific -syscall, or deeper in the kernel in areas that might be reachable -through multiple different syscalls (such as writing to a specific -privileged file). Seccomp, on the other hand, is a syscall filter which -is applied to all syscalls before they are run. A process can set up a -filter which allows them to revoke their right to run certain syscalls, -or specific arguments for certain syscalls.

-
-
-

Before using seccomp, consider whether adding/removing Linux -capabilities gives you the control you need. See -Setting -capabilities for- containers for further information.

-
-
-
-

13.2.4. See whether you can accomplish your aims by using Pod Security Policies (PSPs)

-
-

Pod Security Policies offer a lot of different ways to improve your -security posture without introducing undue complexity. Explore the -options available in PSPs before venturing into building seccomp and -Apparmor profiles.

-
-
-

!!! warning As of Kubernetes 1.25, PSPs have been removed and replaced -with the -Pod -Security Admission controller. Third-party alternatives which exist -include OPA/Gatekeeper and Kyverno. A collection of Gatekeeper -constraints and constraint templates for implementing policies commonly -found in PSPs can be pulled from the -Gatekeeper -library repository on GitHub. And many replacements for PSPs can be -found in the Kyverno policy library -including the full collection of -Pod -Security Standards.

-
-
-
-
-

13.3. Tools and Resources

-
- -
-
-

[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] -= Protecting the infrastructure (hosts) -:info_doctype: section -:info_title: Protecting the infrastructure (hosts) -:info_abstract: Protecting the infrastructure (hosts) -:info_titleabbrev: Protecting the infrastructure (hosts) -:imagesdir: images/

-
-
-

Inasmuch as it’s important to secure your container images, it’s equally -important to safeguard the infrastructure that runs them. This section -explores different ways to mitigate risks from attacks launched directly -against the host. These guidelines should be used in conjunction with -those outlined in the Runtime Security section.

-
-
-
-

13.4. Recommendations

-
-

13.4.1. Use an OS optimized for running containers

-
-

Consider using Flatcar Linux, Project Atomic, RancherOS, and -Bottlerocket, a -special purpose OS from AWS designed for running Linux containers. It -includes a reduced attack surface, a disk image that is verified on -boot, and enforced permission boundaries using SELinux.

-
-
-

Alternately, use the -EKS -optimized AMI for your Kubernetes worker nodes. The EKS optimized AMI -is released regularly and contains a minimal set of OS packages and -binaries necessary to run your containerized workloads.

-
-
-

Please refer Amazon -EKS AMI RHEL Build Specification for a sample configuration script -which can be used for building a custom Amazon EKS AMI running on Red -Hat Enterprise Linux using Hashicorp Packer. This script can be further -leveraged to build STIG compliant EKS custom AMIs.

-
-
-
-

13.4.2. Keep your worker node OS updated

-
-

Regardless of whether you use a container-optimized host OS like -Bottlerocket or a larger, but still minimalist, Amazon Machine Image -like the EKS optimized AMIs, it is best practice to keep these host OS -images up to date with the latest security patches.

-
-
-

For the EKS optimized AMIs, regularly check the -CHANGELOG -and/or release notes -channel and automate the rollout of updated worker node images into -your cluster.

-
-
-
-

13.4.3. Treat your infrastructure as immutable and automate the replacement of your worker nodes

-
-

Rather than performing in-place upgrades, replace your workers when a -new patch or update becomes available. This can be approached a couple -of ways. You can either add instances to an existing autoscaling group -using the latest AMI as you sequentially cordon and drain nodes until -all of the nodes in the group have been replaced with the latest AMI. -Alternatively, you can add instances to a new node group while you -sequentially cordon and drain nodes from the old node group until all of -the nodes have been replaced. EKS -managed -node groups uses the first approach and will display a message in the -console to upgrade your workers when a new AMI becomes available. -eksctl also has a mechanism for creating node groups with the latest -AMI and for gracefully cordoning and draining pods from nodes groups -before the instances are terminated. If you decide to use a different -method for replacing your worker nodes, it is strongly recommended that -you automate the process to minimize human oversight as you will likely -need to replace workers regularly as new updates/patches are released -and when the control plane is upgraded.

-
-
-

With EKS Fargate, AWS will automatically update the underlying -infrastructure as updates become available. Oftentimes this can be done -seamlessly, but there may be times when an update will cause your pod to -be rescheduled. Hence, we recommend that you create deployments with -multiple replicas when running your application as a Fargate pod.

-
-
-
-

13.4.4. Periodically run kube-bench to verify compliance with CIS benchmarks for Kubernetes

-
-

kube-bench is an open source project from Aqua that evaluates your -cluster against the CIS benchmarks for Kubernetes. The benchmark -describes the best practices for securing unmanaged Kubernetes clusters. -The CIS Kubernetes Benchmark encompasses the control plane and the data -plane. Since Amazon EKS provides a fully managed control plane, not all -of the recommendations from the CIS Kubernetes Benchmark are applicable. -To ensure this scope reflects how Amazon EKS is implemented, AWS created -the CIS Amazon EKS Benchmark. The EKS benchmark inherits from CIS -Kubernetes Benchmark with additional inputs from the community with -specific configuration considerations for EKS clusters.

-
-
-

When running kube-bench -against an EKS cluster, follow -these -instructions from Aqua Security. For further information see -Introducing -The CIS Amazon EKS Benchmark.

-
-
-
-

13.4.5. Minimize access to worker nodes

-
-

Instead of enabling SSH access, use -SSM -Session Manager when you need to remote into a host. Unlike SSH keys -which can be lost, copied, or shared, Session Manager allows you to -control access to EC2 instances using IAM. Moreover, it provides an -audit trail and log of the commands that were run on the instance.

-
-
-

As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 -Launch Templates. This allows you to embed the SSM agent into the AMI or -install it as the worker node is being bootstrapped. If you rather not -modify the Optimized AMI or the ASG’s launch template, you can install -the SSM agent with a DaemonSet as in -this -example.

-
-
-
Minimal IAM policy for SSM based SSH Access
-
-

The AmazonSSMManagedInstanceCore AWS managed policy contains a -number of permissions that are not required for SSM Session Manager / -SSM RunCommand if you’re just looking to avoid SSH access. Of concern -specifically is the * permissions for ssm:GetParameter(s) which -would allow for the role to access all parameters in Parameter Store -(including SecureStrings with the AWS managed KMS key configured).

-
-
-

The following IAM policy contains the minimal set of permissions to -enable node access via SSM Systems Manager.

-
-
-
-
{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Sid": "EnableAccessViaSSMSessionManager",
-      "Effect": "Allow",
-      "Action": [
-        "ssmmessages:OpenDataChannel",
-        "ssmmessages:OpenControlChannel",
-        "ssmmessages:CreateDataChannel",
-        "ssmmessages:CreateControlChannel",
-        "ssm:UpdateInstanceInformation"
-      ],
-      "Resource": "*"
-    },
-    {
-      "Sid": "EnableSSMRunCommand",
-      "Effect": "Allow",
-      "Action": [
-        "ssm:UpdateInstanceInformation",
-        "ec2messages:SendReply",
-        "ec2messages:GetMessages",
-        "ec2messages:GetEndpoint",
-        "ec2messages:FailMessage",
-        "ec2messages:DeleteMessage",
-        "ec2messages:AcknowledgeMessage"
-      ],
-      "Resource": "*"
-    }
-  ]
-}
-
-
-
-

With this policy in place and the -Session -Manager plugin installed, you can then run

-
-
-
-
aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE]
-
-
-
-

to access the node.

-
-
-

!!! note You may also want to consider adding permissions to -enable -Session Manager logging.

-
-
-
-
-

13.4.6. Deploy workers onto private subnets

-
-

By deploying workers onto private subnets, you minimize their exposure -to the Internet where attacks often originate. Beginning April 22, 2020, -the assignment of public IP addresses to nodes in a managed node groups -will be controlled by the subnet they are deployed onto. Prior to this, -nodes in a Managed Node Group were automatically assigned a public IP. -If you choose to deploy your worker nodes on to public subnets, -implement restrictive AWS security group rules to limit their exposure.

-
-
-
-

13.4.7. Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices

-
-

You can use -Amazon -Inspector to check for unintended network access to your nodes and for -vulnerabilities on the underlying Amazon EC2 instances.

-
-
-

Amazon Inspector can provide common vulnerabilities and exposures (CVE) -data for your Amazon EC2 instances only if the Amazon EC2 Systems -Manager (SSM) agent is installed and enabled. This agent is preinstalled -on several -Amazon -Machine Images (AMIs) including -EKS -optimized Amazon Linux AMIs. Regardless of SSM agent status, all of -your Amazon EC2 instances are scanned for network reachability issues. -For more information about configuring scans for Amazon EC2, see -Scanning -Amazon EC2 instances.

-
-
-

!!! attention Inspector cannot be run on the infrastructure used to run -Fargate pods.

-
-
-
-
-

13.5. Alternatives

-
-

13.5.1. Run SELinux

-
-

!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, -Bottlerocket, and Amazon Linux 2023

-
-
-

SELinux provides an additional layer of security to keep containers -isolated from each other and from the host. SELinux allows -administrators to enforce mandatory access controls (MAC) for every -user, application, process, and file. Think of it as a backstop that -restricts the operations that can be performed against to specific -resources based on a set of labels. On EKS, SELinux can be used to -prevent containers from accessing each other’s resources.

-
-
-

Container SELinux policies are defined in the -container-selinux -package. Docker CE requires this package (along with its dependencies) -so that the processes and files created by Docker (or other container -runtimes) run with limited system access. Containers leverage the -container_t label which is an alias to svirt_lxc_net_t. These -policies effectively prevent containers from accessing certain features -of the host.

-
-
-

When you configure SELinux for Docker, Docker automatically labels -workloads container_t as a type and gives each container a unique -MCS level. This will isolate containers from one another. If you need -looser restrictions, you can create your own profile in SElinux which -grants a container permissions to specific areas of the file system. -This is similar to PSPs in that you can create different profiles for -different containers/pods. For example, you can have a profile for -general workloads with a set of restrictive controls and another for -things that require privileged access.

-
-
-

SELinux for Containers has a set of options that can be configured to -modify the default restrictions. The following SELinux Booleans can be -enabled or disabled based on your needs:

-
- ----- - - - - - - - - - - - - - - - - - - - - - - - - -
BooleanDefaultDescription

container_connect_any

off

Allow containers to access -privileged ports on the host. For example, if you have a container that -needs to map ports to 443 or 80 on the host.

container_manage_cgroup

off

Allow containers to manage cgroup -configuration. For example, a container running systemd will need this -to be enabled.

container_use_cephfs

off

Allow containers to use a ceph file -system.

-
-

By default, containers are allowed to read/execute under /usr and -read most content from /etc. The files under /var/lib/docker and -/var/lib/containers have the label container_var_lib_t. To view -a full list of default, labels see the -container.fc -file.

-
-
-
-
docker container run -it \
-  -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \
-  centos:7 cat /host/repositories.json
-# cat: /host/repositories.json: Permission denied
-
-docker container run -it \
-  -v /etc/passwd:/host/etc/passwd \
-  centos:7 cat /host/etc/passwd
-# cat: /host/etc/passwd: Permission denied
-
-
-
-

Files labeled with container_file_t are the only files that are -writable by containers. If you want a volume mount to be writeable, you -will needed to specify :z or :Z at the end.

-
-
-
    -
  • -

    :z will re-label the files so that the container can read/write

    -
  • -
  • -

    :Z will re-label the files so that only the container can -read/write

    -
  • -
-
-
-
-
ls -Z /var/lib/misc
-# -rw-r--r--. root root system_u:object_r:var_lib_t:s0   postfix.aliasesdb-stamp
-
-docker container run -it \
-  -v /var/lib/misc:/host/var/lib/misc:z \
-  centos:7 echo "Relabeled!"
-
-ls -Z /var/lib/misc
-#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp
-
-
-
-
-
docker container run -it \
-  -v /var/log:/host/var/log:Z \
-  fluentbit:latest
-
-
-
-

In Kubernetes, relabeling is slightly different. Rather than having -Docker automatically relabel the files, you can specify a custom MCS -label to run the pod. Volumes that support relabeling will automatically -be relabeled so that they are accessible. Pods with a matching MCS label -will be able to access the volume. If you need strict isolation, set a -different MCS label for each pod.

-
-
-
-
securityContext:
-  seLinuxOptions:
-    # Provide a unique MCS label per container
-    # You can specify user, role, and type also
-    # enforcement based on type and level (svert)
-    level: s0:c144:c154
-
-
-
-

In this example s0:c144:c154 corresponds to an MCS label assigned to -a file that the container is allowed to access.

-
-
-

On EKS you could create policies that allow for privileged containers to -run, like FluentD and create an SELinux policy to allow it to read from -/var/log on the host without needing to relabel the host directory. Pods -with the same label will be able to access the same host volumes.

-
-
-

We have implemented -sample AMIs for -Amazon EKS that have SELinux configured on CentOS 7 and RHEL 7. These -AMIs were developed to demonstrate sample implementations that meet -requirements of highly regulated customers, such as STIG, CJIS, and C2S.

-
-
-

!!! caution SELinux will ignore containers where the type is unconfined.

-
-
-
-
-

13.6. Tools and resources

-
- -
-
-
-
-
-

14. Compliance

-
-
-

Compliance is a shared responsibility between AWS and the consumers of -its services. Generally speaking, AWS is responsible for “security of -the cloud” whereas its users are responsible for “security in the -cloud.” The line that delineates what AWS and its users are responsible -for will vary depending on the service. For example, with Fargate, AWS -is responsible for managing the physical security of its data centers, -the hardware, the virtual infrastructure (Amazon EC2), and the container -runtime (Docker). Users of Fargate are responsible for securing the -container image and their application. Knowing who is responsible for -what is an important consideration when running workloads that must -adhere to compliance standards.

-
-
-

The following table shows the compliance programs with which the -different container services conform.

-
- ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Compliance ProgramAmazon ECS OrchestratorAmazon EKS OrchestratorECS FargateAmazon ECR

PCI DSS Level 1

1

1

1

1

HIPAA Eligible

1

1

1

1

SOC I

1

1

1

1

SOC II

1

1

1

1

SOC III

1

1

1

1

ISO 27001:2013

1

1

1

1

ISO 9001:2015

1

1

1

1

ISO 27017:2015

1

1

1

1

ISO 27018:2019

1

1

1

1

IRAP

1

1

1

1

FedRAMP Moderate (East/West)

1

1

0

1

FedRAMP High (GovCloud)

1

1

0

1

DOD CC SRG

1

DISA Review (IL5)

0

1

HIPAA BAA

1

1

1

1

MTCS

1

1

0

1

C5

1

1

0

1

K-ISMS

1

1

0

1

ENS High

1

1

0

1

OSPAR

1

1

0

1

HITRUST CSF

1

1

1

1

-
-

Compliance status changes over time. For the latest status, always refer -to https://aws.amazon.com/compliance/services-in-scope/.

-
-
-

For further information about cloud accreditation models and best -practices, see the AWS whitepaper, -Accreditation -Models for Secure Cloud Adoption

-
-
-

14.1. Shifting Left

-
-

The concept of shifting left involves catching policy violations and -errors earlier in the software development lifecycle. From a security -perspective, this can be very beneficial. A developer, for example, can -fix issues with their configuration before their application is deployed -to the cluster. Catching mistakes like this earlier will help prevent -configurations that violate your policies from being deployed.

-
-
-

14.1.1. Policy as Code

-
-

Policy can be thought of as a set of rules for governing behaviors, -i.e. behaviors that are allowed or those that are prohibited. For -example, you may have a policy that says that all Dockerfiles should -include a USER directive that causes the container to run as a non-root -user. As a document, a policy like this can be hard to discover and -enforce. It may also become outdated as your requirements change. With -Policy as Code (PaC) solutions, you can automate security, compliance, -and privacy controls that detect, prevent, reduce, and counteract known -and persistent threats. Furthermore, they give you mechanism to codify -your policies and manage them as you do other code artifacts. The -benefit of this approach is that you can reuse your DevOps and GitOps -strategies to manage and consistently apply policies across fleets of -Kubernetes clusters. Please refer to -Pod -Security for information about PaC options and the future of PSPs.

-
-
-
-

14.1.2. Use policy-as-code tools in pipelines to detect violations before deployment

-
-
    -
  • -

    OPA is an open source policy engine -that’s part of the CNCF. It’s used for making policy decisions and can -be run a variety of different ways, e.g. as a language library or a -service. OPA policies are written in a Domain Specific Language (DSL) -called Rego. While it is often run as part of a Kubernetes Dynamic -Admission Controller as the -Gatekeeper project, OPA -can also be incorporated into your CI/CD pipeline. This allows -developers to get feedback about their configuration earlier in the -release cycle which can subsequently help them resolve issues before -they get to production. A collection of common OPA policies can be found -in the GitHub -repository -for this project.

    -
  • -
  • -

    Conftest is built on -top of OPA and it provides a developer focused experience for testing -Kubernetes configuration.

    -
  • -
  • -

    Kyverno is a policy engine designed for -Kubernetes. With Kyverno, policies are managed as Kubernetes resources -and no new language is required to write policies. This allows using -familiar tools such as kubectl, git, and kustomize to manage policies. -Kyverno policies can validate, mutate, and generate Kubernetes resources -plus ensure OCI image supply chain security. The -Kyverno CLI can be used to test -policies and validate resources as part of a CI/CD pipeline. All the -Kyverno community policies can be found on the -Kyverno website, and for examples using -the Kyverno CLI to write tests in pipelines, see the -policies repository.

    -
  • -
-
-
-
-
-

14.2. Tools and resources

-
- -
-
-
-
-
-

15. Incident response and forensics

-
-
-

Your ability to react quickly to an incident can help minimize damage -caused from a breach. Having a reliable alerting system that can warn -you of suspicious behavior is the first step in a good incident response -plan. When an incident does arise, you have to quickly decide whether to -destroy and replace the effected container, or isolate and inspect the -container. If you choose to isolate the container as part of a forensic -investigation and root cause analysis, then the following set of -activities should be followed:

-
-
-

15.1. Sample incident response plan

-
-

15.1.1. Identify the offending Pod and worker node

-
-

Your first course of action should be to isolate the damage. Start by -identifying where the breach occurred and isolate that Pod and its node -from the rest of the infrastructure.

-
-
-
-

15.1.2. Identify the offending Pods and worker nodes using workload name

-
-

If you know the name and namespace of the offending pod, you can -identify the the worker node running the pod as follows:

-
-
-
-
kubectl get pods <name> --namespace <namespace> -o=jsonpath='{.spec.nodeName}{"\n"}'
-
-
-
-

If a Workload -Resource such as a Deployment has been compromised, it is likely that -all the pods that are part of the workload resource are compromised. Use -the following command to list all the pods of the Workload Resource and -the nodes they are running on:

-
-
-
-
selector=$(kubectl get deployments <name> \
- --namespace <namespace> -o json | jq -j \
-'.spec.selector.matchLabels | to_entries | .[] | "\(.key)=\(.value)"')
-
-kubectl get pods --namespace <namespace> --selector=$selector \
--o json | jq -r '.items[] | "\(.metadata.name) \(.spec.nodeName)"'
-
-
-
-

The above command is for deployments. You can run the same command for -other workload resources such as replicasets,, statefulsets, etc.

-
-
-
-

15.1.3. Identify the offending Pods and worker nodes using service account name

-
-

In some cases, you may identify that a service account is compromised. -It is likely that pods using the identified service account are -compromised. You can identify all the pods using the service account and -nodes they are running on with the following command:

-
-
-
-
kubectl get pods -o json --namespace <namespace> | \
-    jq -r '.items[] |
-    select(.spec.serviceAccount == "<service account name>") |
-    "\(.metadata.name) \(.spec.nodeName)"'
-
-
-
-
-

15.1.4. Identify Pods with vulnerable or compromised images and worker nodes

-
-

In some cases, you may discover that a container image being used in -pods on your cluster is malicious or compromised. A container image is -malicious or compromised, if it was found to contain malware, is a known -bad image or has a CVE that has been exploited. You should consider all -the pods using the container image compromised. You can identify the -pods using the image and nodes they are running on with the following -command:

-
-
-
-
IMAGE=<Name of the malicious/compromised image>
-
-kubectl get pods -o json --all-namespaces | \
-    jq -r --arg image "$IMAGE" '.items[] |
-    select(.spec.containers[] | .image == $image) |
-    "\(.metadata.name) \(.metadata.namespace) \(.spec.nodeName)"'
-
-
-
-
-

15.1.5. Isolate the Pod by creating a Network Policy that denies all ingress and egress traffic to the pod

-
-

A deny all traffic rule may help stop an attack that is already underway -by severing all connections to the pod. The following Network Policy -will apply to a pod with the label app=web.

-
-
-
-
apiVersion: networking.k8s.io/v1
-kind: NetworkPolicy
-metadata:
-  name: default-deny
-spec:
-  podSelector:
-    matchLabels:
-      app: web
-  policyTypes:
-  - Ingress
-  - Egress
-
-
-
-

!!! attention A Network Policy may prove ineffective if an attacker has -gained access to underlying host. If you suspect that has happened, you -can use -AWS -Security Groups to isolate a compromised host from other hosts. When -changing a host’s security group, be aware that it will impact all -containers running on that host.

-
-
-
-

15.1.6. Revoke temporary security credentials assigned to the pod or worker node if necessary

-
-

If the worker node has been assigned an IAM role that allows Pods to -gain access to other AWS resources, remove those roles from the instance -to prevent further damage from the attack. Similarly, if the Pod has -been assigned an IAM role, evaluate whether you can safely remove the -IAM policies from the role without impacting other workloads.

-
-
-
-

15.1.7. Cordon the worker node

-
-

By cordoning the impacted worker node, you’re informing the scheduler to -avoid scheduling pods onto the affected node. This will allow you to -remove the node for forensic study without disrupting other workloads.

-
-
-

!!! info This guidance is not applicable to Fargate where each Fargate -pod run in its own sandboxed environment. Instead of cordoning, -sequester the affected Fargate pods by applying a network policy that -denies all ingress and egress traffic.

-
-
-
-

15.1.8. Enable termination protection on impacted worker node

-
-

An attacker may attempt to erase their misdeeds by terminating an -affected node. Enabling -termination -protection can prevent this from happening. -Instance -scale-in protection will protect the node from a scale-in event.

-
-
-

!!! warning You cannot enable termination protection on a Spot instance.

-
-
-
-

15.1.9. Label the offending Pod/Node with a label indicating that it is part of an active investigation

-
-

This will serve as a warning to cluster administrators not to tamper -with the affected Pods/Nodes until the investigation is complete.

-
-
-
-

15.1.10. Capture volatile artifacts on the worker node

-
-
    -
  • -

    Capture the operating system memory. This will capture the Docker -daemon (or other container runtime) and its subprocesses per container. -This can be accomplished using tools like -LiME and -Volatility, or through -higher-level tools such as -Automated -Forensics Orchestrator for Amazon EC2 that build on top of them.

    -
  • -
  • -

    Perform a netstat tree dump of the processes running and the open -ports. This will capture the docker daemon and its subprocess per -container.

    -
  • -
  • -

    Run commands to save container-level state before evidence is -altered. You can use capabilities of the container runtime to capture -information about currently running containers. For example, with -Docker, you could do the following:

    -
    -
      -
    • -

      docker top CONTAINER for processes running.

      -
    • -
    • -

      docker logs CONTAINER for daemon level held logs.

      -
    • -
    • -

      docker inspect CONTAINER for various information about the -container.

      -
      -

      The same could be achieved with containerd using the -nerdctl CLI, in place of -docker (e.g. nerdctl inspect). Some additional commands are -available depending on the container runtime. For example, Docker has -docker diff to see changes to the container filesystem or -docker checkpoint to save all container state including volatile -memory (RAM). See -this -Kubernetes blog post for discussion of similar capabilities with -containerd or CRI-O runtimes.

      -
      -
    • -
    -
    -
  • -
  • -

    Pause the container for forensic capture.

    -
  • -
  • -

    Snapshot the instance’s EBS volumes.

    -
  • -
-
-
-
-

15.1.11. Redeploy compromised Pod or Workload Resource

-
-

Once you have gathered data for forensic analysis, you can redeploy the -compromised pod or workload resource.

-
-
-

First roll out the fix for the vulnerability that was compromised and -start new replacement pods. Then delete the vulnerable pods.

-
-
-

If the vulnerable pods are managed by a higher-level Kubernetes workload -resource (for example, a Deployment or DaemonSet), deleting them will -schedule new ones. So vulnerable pods will be launched again. In that -case you should deploy a new replacement workload resource after fixing -the vulnerability. Then you should delete the vulnerable workload.

-
-
-
-
-

15.2. Recommendations

-
-

15.2.1. Review the AWS Security Incident Response Whitepaper

-
-

While this section gives a brief overview along with a few -recommendations for handling suspected security breaches, the topic is -exhaustively covered in the white paper, -AWS -Security Incident Response.

-
-
-
-

15.2.2. Practice security game days

-
-

Divide your security practitioners into 2 teams: red and blue. The red -team will be focused on probing different systems for vulnerabilities -while the blue team will be responsible for defending against them. If -you don’t have enough security practitioners to create separate teams, -consider hiring an outside entity that has knowledge of Kubernetes -exploits.

-
-
-

Kubesploit is a penetration -testing framework from CyberArk that you can use to conduct game days. -Unlike other tools which scan your cluster for vulnerabilities, -kubesploit simulates a real-world attack. This gives your blue team an -opportunity to practice its response to an attack and gauge its -effectiveness.

-
-
-
-

15.2.3. Run penetration tests against your cluster

-
-

Periodically attacking your own cluster can help you discover -vulnerabilities and misconfigurations. Before getting started, follow -the penetration -test guidelines before conducting a test against your cluster.

-
-
-
-
-

15.3. Tools and resources

-
- -
-
-
-
-
-

16. Image security

-
-
-

You should consider the container image as your first line of defense -against an attack. An insecure, poorly constructed image can allow an -attacker to escape the bounds of the container and gain access to the -host. Once on the host, an attacker can gain access to sensitive -information or move laterally within the cluster or with your AWS -account. The following best practices will help mitigate risk of this -happening.

-
-
-

16.1. Recommendations

-
-

16.1.1. Create minimal images

-
-

Start by removing all extraneous binaries from the container image. If -you’re using an unfamiliar image from Dockerhub, inspect the image using -an application like Dive which can -show you the contents of each of the container’s layers. Remove all -binaries with the SETUID and SETGID bits as they can be used to escalate -privilege and consider removing all shells and utilities like nc and -curl that can be used for nefarious purposes. You can find the files -with SETUID and SETGID bits with the following command:

-
-
-
-
find / -perm /6000 -type f -exec ls -ld {} \;
-
-
-
-

To remove the special permissions from these files, add the following -directive to your container image:

-
-
-
-
RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true
-
-
-
-

Colloquially, this is known as de-fanging your image.

-
-
-
-

16.1.2. Use multi-stage builds

-
-

Using multi-stage builds is a way to create minimal images. Oftentimes, -multi-stage builds are used to automate parts of the Continuous -Integration cycle. For example, multi-stage builds can be used to lint -your source code or perform static code analysis. This affords -developers an opportunity to get near immediate feedback instead of -waiting for a pipeline to execute. Multi-stage builds are attractive -from a security standpoint because they allow you to minimize the size -of the final image pushed to your container registry. Container images -devoid of build tools and other extraneous binaries improves your -security posture by reducing the attack surface of the image. For -additional information about multi-stage builds, see -Docker’s -multi-stage builds documentation.

-
-
-
-

16.1.3. Create Software Bill of Materials (SBOMs) for your container image

-
-

A “software bill of materials” (SBOM) is a nested inventory of the -software artifacts that make up your container image. SBOM is a key -building block in software security and software supply chain risk -management. Generating, storing SBOMS in a -central repository and scanning SBOMs for vulnerabilities helps address -the following concerns:

-
-
-
    -
  • -

    Visibility: understand what components make up your container image. -Storing in a central repository allows SBOMs to be audited and scanned -anytime, even post deployment to detect and respond to new -vulnerabilities such as zero day vulnerabilities.

    -
  • -
  • -

    Provenance Verification: assurance that existing assumptions of -where and how an artifact originates from are true and that the artifact -or its accompanying metadata have not been tampered with during the -build or delivery processes.

    -
  • -
  • -

    Trustworthiness: assurance that a given artifact and its contents -can be trusted to do what it is purported to do, i.e. is suitable for a -purpose. This involves judgement on whether the code is safe to execute -and making informed decisions about the risks associated with executing -the code. Trustworthiness is assured by creating an attested pipeline -execution report along with attested SBOM and attested CVE scan report -to assure the consumers of the image that this image is in-fact created -through secure means (pipeline) with secure components.

    -
  • -
  • -

    Dependency Trust Verification: recursive checking of an artifact’s -dependency tree for trustworthiness and provenance of the artifacts it -uses. Drift in SBOMs can help detect malicious activity including -unauthorized, untrusted dependencies, infiltration attempts.

    -
  • -
-
-
-

The following tools can be used to generate SBOM:

-
-
-
    -
  • -

    Amazon Inspector can be used to -create -and export SBOMs.

    -
  • -
  • -

    Syft from Anchore can also be used -for SBOM generation. For quicker vulnerability scans, the SBOM generated -for a container image can be used as an input to scan. The SBOM and scan -report are then -attested -and attached to the image before pushing the image to a central OCI -repository such as Amazon ECR for review and audit purposes.

    -
  • -
-
-
-

Learn more about securing your software supply chain by reviewing -CNCF Software -Supply Chain Best Practices guide.

-
-
-
-

16.1.4. Scan images for vulnerabilities regularly

-
-

Like their virtual machine counterparts, container images can contain -binaries and application libraries with vulnerabilities or develop -vulnerabilities over time. The best way to safeguard against exploits is -by regularly scanning your images with an image scanner. Images that are -stored in Amazon ECR can be scanned on push or on-demand (once during a -24 hour period). ECR currently supports -two -types of scanning - Basic and Enhanced. Basic scanning leverages -Clair an open source image scanning -solution for no cost. -Enhanced -scanning uses Amazon Inspector to provide automatic continuous scans -for additional cost. After an -image is scanned, the results are logged to the event stream for ECR in -EventBridge. You can also see the results of a scan from within the ECR -console. Images with a HIGH or CRITICAL vulnerability should be deleted -or rebuilt. If an image that has been deployed develops a vulnerability, -it should be replaced as soon as possible.

-
-
-

Knowing where images with vulnerabilities have been deployed is -essential to keeping your environment secure. While you could -conceivably build an image tracking solution yourself, there are already -several commercial offerings that provide this and other advanced -capabilities out of the box, including:

-
-
- -
-
-

A Kubernetes validation webhook could also be used to validate that -images are free of critical vulnerabilities. Validation webhooks are -invoked prior to the Kubernetes API. They are typically used to reject -requests that don’t comply with the validation criteria defined in the -webhook. -This -is an example of a serverless webhook that calls the ECR -describeImageScanFindings API to determine whether a pod is pulling an -image with critical vulnerabilities. If vulnerabilities are found, the -pod is rejected and a message with list of CVEs is returned as an Event.

-
-
-
-

16.1.5. Use attestations to validate artifact integrity

-
-

An attestation is a cryptographically signed “statement” that claims -something - a “predicate” e.g. a pipeline run or the SBOM or the -vulnerability scan report is true about another thing - a “subject” -i.e. the container image.

-
-
-

Attestations help users to validate that an artifact comes from a -trusted source in the software supply chain. As an example, we may use a -container image without knowing all the software components or -dependencies that are included in that image. However, if we trust -whatever the producer of the container image says about what software is -present, we can use the producer’s attestation to rely on that artifact. -This means that we can proceed to use the artifact safely in our -workflow in place of having done the analysis ourself.

-
-
-
    -
  • -

    Attestations can be created using -AWS -Signer or -Sigstore -cosign.

    -
  • -
  • -

    Kubernetes admission controllers such as Kyverno -can be used to -verify -attestations.

    -
  • -
  • -

    Refer to this -workshop -to learn more about software supply chain management best practices on -AWS using open source tools with topics including creating and attaching -attestations to a container image.

    -
  • -
-
-
-
-

16.1.6. Create IAM policies for ECR repositories

-
-

Nowadays, it is not uncommon for an organization to have multiple -development teams operating independently within a shared AWS account. -If these teams don’t need to share assets, you may want to create a set -of IAM policies that restrict access to the repositories each team can -interact with. A good way to implement this is by using ECR -namespaces. -Namespaces are a way to group similar repositories together. For -example, all of the registries for team A can be prefaced with the -team-a/ while those for team B can use the team-b/ prefix. The policy to -restrict access might look like the following:

-
-
-
-
{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Sid": "AllowPushPull",
-      "Effect": "Allow",
-      "Action": [
-        "ecr:GetDownloadUrlForLayer",
-        "ecr:BatchGetImage",
-        "ecr:BatchCheckLayerAvailability",
-        "ecr:PutImage",
-        "ecr:InitiateLayerUpload",
-        "ecr:UploadLayerPart",
-        "ecr:CompleteLayerUpload"
-      ],
-      "Resource": [
-        "arn:aws:ecr:<region>:<account_id>:repository/team-a/*"
-      ]
-    }
-  ]
-}
-
-
-
-
-

16.1.7. Consider using ECR private endpoints

-
-

The ECR API has a public endpoint. Consequently, ECR registries can be -accessed from the Internet so long as the request has been authenticated -and authorized by IAM. For those who need to operate in a sandboxed -environment where the cluster VPC lacks an Internet Gateway (IGW), you -can configure a private endpoint for ECR. Creating a private endpoint -enables you to privately access the ECR API through a private IP address -instead of routing traffic across the Internet. For additional -information on this topic, see -Amazon -ECR interface VPC endpoints.

-
-
-
-

16.1.8. Implement endpoint policies for ECR

-
-

The default endpoint policy for allows access to all ECR repositories -within a region. This might allow an attacker/insider to exfiltrate data -by packaging it as a container image and pushing it to a registry in -another AWS account. Mitigating this risk involves creating an endpoint -policy that limits API access to ECR repositories. For example, the -following policy allows all AWS principles in your account to perform -all actions against your and only your ECR repositories:

-
-
-
-
{
-  "Statement": [
-    {
-      "Sid": "LimitECRAccess",
-      "Principal": "*",
-      "Action": "*",
-      "Effect": "Allow",
-      "Resource": "arn:aws:ecr:<region>:<account_id>:repository/*"
-    }
-  ]
-}
-
-
-
-

You can enhance this further by setting a condition that uses the new -PrincipalOrgID attribute which will prevent pushing/pulling of -images by an IAM principle that is not part of your AWS Organization. -See, -aws:PrincipalOrgID -for additional details. We recommended applying the same policy to both -the com.amazonaws.<region>.ecr.dkr and the -com.amazonaws.<region>.ecr.api endpoints. Since EKS pulls images for -kube-proxy, coredns, and aws-node from ECR, you will need to add the -account ID of the registry, -e.g. 602401143452.dkr.ecr.us-west-2.amazonaws.com/* to the list of -resources in the endpoint policy or alter the policy to allow pulls from -“*” and restrict pushes to your account ID. The table below reveals the -mapping between the AWS accounts where EKS images are vended from and -cluster region.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account NumberRegion

602401143452

All commercial regions except for those listed below

800184023465

ap-east-1 - Asia Pacific (Hong Kong)

558608220178

me-south-1 - Middle East (Bahrain)

918309763551

cn-north-1 - China (Beijing)

961992271922

cn-northwest-1 - China (Ningxia)

-
-

For further information about using endpoint policies, see -Using -VPC endpoint policies to control Amazon ECR access.

-
-
-
-

16.1.9. Implement lifecycle policies for ECR

-
-

The -NIST -Application Container Security Guide warns about the risk of “stale -images in registries”, noting that over time old images with -vulnerable, out-of-date software packages should be removed to prevent -accidental deployment and exposure. Each ECR repository can have a -lifecycle policy that sets rules for when images expire. The -AWS -official documentation describes how to set up test rules, evaluate -them and then apply them. There are several -lifecycle -policy examples in the official docs that show different ways of -filtering the images in a repository:

-
-
-
    -
  • -

    Filtering by image age or count

    -
  • -
  • -

    Filtering by tagged or untagged images

    -
  • -
  • -

    Filtering by image tags, either in multiple rules or a single rule

    -
  • -
-
-
-

???+ warning If the image for long running application is purged from -ECR, it can cause an image pull errors when the application is -redeployed or scaled horizontally. When using image lifecycle policies, -be sure you have good CI/CD practices in place to keep deployments and -the images that they reference up to date and always create [image] -expiry rules that account for how often you do releases/deployments.

-
-
-
-

16.1.10. Create a set of curated images

-
-

Rather than allowing developers to create their own images, consider -creating a set of vetted images for the different application stacks in -your organization. By doing so, developers can forego learning how to -compose Dockerfiles and concentrate on writing code. As changes are -merged into Master, a CI/CD pipeline can automatically compile the -asset, store it in an artifact repository and copy the artifact into the -appropriate image before pushing it to a Docker registry like ECR. At -the very least you should create a set of base images from which -developers to create their own Dockerfiles. Ideally, you want to avoid -pulling images from Dockerhub because 1/ you don’t always know what is -in the image and 2/ about -a -fifth of the top 1000 images have vulnerabilities. A list of those -images and their vulnerabilities can be found -here.

-
-
-
-

16.1.11. Add the USER directive to your Dockerfiles to run as a non-root user

-
-

As was mentioned in the pod security section, you should avoid running -container as root. While you can configure this as part of the podSpec, -it is a good habit to use the USER directive to your Dockerfiles. -The USER directive sets the UID to use when running RUN, -ENTRYPOINT, or CMD instruction that appears after the USER -directive.

-
-
-
-

16.1.12. Lint your Dockerfiles

-
-

Linting can be used to verify that your Dockerfiles are adhering to a -set of predefined guidelines, e.g. the inclusion of the USER -directive or the requirement that all images be tagged. -dockerfile_lint is an -open source project from RedHat that verifies common best practices and -includes a rule engine that you can use to build your own rules for -linting Dockerfiles. It can be incorporated into a CI pipeline, in that -builds with Dockerfiles that violate a rule will automatically fail.

-
-
-
-

16.1.13. Build images from Scratch

-
-

Reducing the attack surface of your container images should be primary -aim when building images. The ideal way to do this is by creating -minimal images that are devoid of binaries that can be used to exploit -vulnerabilities. Fortunately, Docker has a mechanism to create images -from -scratch. -With languages like Go, you can create a static linked binary and -reference it in your Dockerfile as in this example:

-
-
-
-
############################
-# STEP 1 build executable binary
-############################
-FROM golang:alpine AS builder# Install git.
-# Git is required for fetching the dependencies.
-RUN apk update && apk add --no-cache gitWORKDIR $GOPATH/src/mypackage/myapp/COPY . . # Fetch dependencies.
-# Using go get.
-RUN go get -d -v# Build the binary.
-RUN go build -o /go/bin/hello
-
-############################
-# STEP 2 build a small image
-############################
-FROM scratch# Copy our static executable.
-COPY --from=builder /go/bin/hello /go/bin/hello# Run the hello binary.
-ENTRYPOINT ["/go/bin/hello"]
-
-
-
-

This creates a container image that consists of your application and -nothing else, making it extremely secure.

-
-
-
-

16.1.14. Use immutable tags with ECR

-
-

Immutable -tags force you to update the image tag on each push to the image -repository. This can thwart an attacker from overwriting an image with a -malicious version without changing the image’s tags. Additionally, it -gives you a way to easily and uniquely identify an image.

-
-
-
-

16.1.15. Sign your images, SBOMs, pipeline runs and vulnerability reports

-
-

When Docker was first introduced, there was no cryptographic model for -verifying container images. With v2, Docker added digests to the image -manifest. This allowed an image’s configuration to be hashed and for the -hash to be used to generate an ID for the image. When image signing is -enabled, the Docker engine verifies the manifest’s signature, ensuring -that the content was produced from a trusted source and no tampering has -occurred. After each layer is downloaded, the engine verifies the digest -of the layer, ensuring that the content matches the content specified in -the manifest. Image signing effectively allows you to create a secure -supply chain, through the verification of digital signatures associated -with the image.

-
-
-

We can use -AWS -Signer or Sigstore Cosign, to sign -container images, create attestations for SBOMs, vulnerability scan -reports and pipeline run reports. These attestations assure the -trustworthiness and integrity of the image, that it is in fact created -by the trusted pipeline without any interference or tampering, and that -it contains only the software components that are documented (in the -SBOM) that is verified and trusted by the image publisher. These -attestations can be attached to the container image and pushed to the -repository.

-
-
-

In the next section we will see how to use the attested artifacts for -audits and admissions controller verification.

-
-
-
-

16.1.16. Image integrity verification using Kubernetes admission controller

-
-

We can verify image signatures, attested artifacts in an automated way -before deploying the image to target Kubernetes cluster using -dynamic -admission controller and admit deployments only when the security -metadata of the artifacts comply with the admission controller policies.

-
-
-

For example we can write a policy that cryptographically verifies the -signature of an image, an attested SBOM, attested pipeline run report, -or attested CVE scan report. We can write conditions in the policy to -check data in the report, e.g. a CVE scan should not have any critical -CVEs. Deployment is allowed only for images that satisfy these -conditions and all other deployments will be rejected by the admissions -controller.

-
-
-

Examples of admission controller include:

-
-
- -
-
-
-

16.1.17. Update the packages in your container images

-
-

You should include RUN apt-get update && apt-get upgrade in your -Dockerfiles to upgrade the packages in your images. Although upgrading -requires you to run as root, this occurs during image build phase. The -application doesn’t need to run as root. You can install the updates and -then switch to a different user with the USER directive. If your base -image runs as a non-root user, switch to root and back; don’t solely -rely on the maintainers of the base image to install the latest security -updates.

-
-
-

Run apt-get clean to delete the installer files from -/var/cache/apt/archives/. You can also run -rm -rf /var/lib/apt/lists/* after installing packages. This removes -the index files or the lists of packages that are available to install. -Be aware that these commands may be different for each package manager. -For example:

-
-
-
-
RUN apt-get update && apt-get install -y \
-    curl \
-    git \
-    libsqlite3-dev \
-    && apt-get clean && rm -rf /var/lib/apt/lists/*
-
-
-
-
-
-

16.2. Tools and resources

-
-
    -
  • -

    Amazon -EKS Security Immersion Workshop - Image Security

    -
  • -
  • -

    docker-slim Build secure -minimal images

    -
  • -
  • -

    dockle Verifies that your -Dockerfile aligns with best practices for creating secure images

    -
  • -
  • -

    dockerfile-lint Rule -based linter for Dockerfiles

    -
  • -
  • -

    hadolint A smart dockerfile -linter

    -
  • -
  • -

    Gatekeeper and OPA A -policy based admission controller

    -
  • -
  • -

    Kyverno A Kubernetes-native policy engine

    -
  • -
  • -

    in-toto Allows the user to verify if a step in -the supply chain was intended to be performed, and if the step was -performed by the right actor

    -
  • -
  • -

    Notary A project for -signing container images

    -
  • -
  • -

    Notary v2

    -
  • -
  • -

    Grafeas An open artifact metadata API to audit -and govern your software supply chain

    -
  • -
  • -

    NeuVector by SUSE open source, -zero-trust container security platform, provides container, image and -registry scanning for vulnerabilities, secrets and compliance.

    -
  • -
-
-
-
-
-
-

17. Multi Account Strategy

-
-
-

AWS recommends using a -multi -account strategy and AWS organizations to help isolate and manage your -business applications and data. There are -many -benefits to using a multi account strategy:

-
-
-
    -
  • -

    Increased AWS API service quotas. Quotas are applied to AWS accounts, -and using multiple accounts for your workloads increases the overall -quota available to your workloads.

    -
  • -
  • -

    Simpler Identity and Access Management (IAM) policies. Granting -workloads and the operators that support them access to only their own -AWS accounts means less time crafting fine-grained IAM policies to -achieve the principle of least privilege.

    -
  • -
  • -

    Improved Isolation of AWS resources. By design, all resources -provisioned within an account are logically isolated from resources -provisioned in other accounts. This isolation boundary provides you with -a way to limit the risks of an application-related issue, -misconfiguration, or malicious actions. If an issue occurs within one -account, impacts to workloads contained in other accounts can be either -reduced or eliminated.

    -
  • -
  • -

    More benefits, as described in the -AWS -Multi Account Strategy Whitepaper

    -
  • -
-
-
-

The following sections will explain how to implement a multi account -strategy for your EKS workloads using either a centralized, or -de-centralized EKS cluster approach.

-
-
-

17.1. Planning for a Multi Workload Account Strategy for Multi Tenant Clusters

-
-

In a multi account AWS strategy, resources that belong to a given -workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables -are all created in an AWS account that contains all the resources for -that workload. These are referred to as a workload account, and the EKS -cluster is deployed into an account referred to as the cluster account. -Cluster accounts will be explored in the next section. Deploying -resources into a dedicated workload account is similar to deploying -kubernetes resources into a dedicated namespace.

-
-
-

Workload accounts can then be further broken down by software -development lifecycle or other requirements if appropriate. For example -a given workload can have a production account, a development account, -or accounts for hosting instances of that workload in a specific region. -More -information is available in this AWS whitepaper.

-
-
-

You can adopt the following approaches when implementing EKS Multi -account strategy:

-
-
-
-

17.2. Centralized EKS Cluster

-
-

In this approach, your EKS Cluster will be deployed in a single AWS -account called the Cluster Account. Using -IAM -roles for Service Accounts (IRSA) or -EKS -Pod Identities to deliver temporary AWS credentials and -AWS Resource Access Manager (RAM) to -simplify network access, you can adopt a multi account strategy for your -multi tenant EKS cluster. The cluster account will contain the VPC, -subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and -any additional networking configurations needed to run your EKS cluster.

-
-
-

In a multi workload account strategy for multi tenant cluster, AWS -accounts typically align with -kubernetes -namespaces as a mechanism for isolating groups of resources. -Best practices for tenant isolation -within an EKS cluster should still be followed when implementing a multi -account strategy for multi tenant EKS clusters.

-
-
-

It is possible to have multiple Cluster Accounts in your AWS -organization, and it is a best practice to have multiple -Cluster Accounts that align with your software development lifecycle -needs. For workloads operating at a very large scale, you may require -multiple Cluster Accounts to ensure that there are enough kubernetes -and AWS service quotas available to all your workloads.

-
- --- - - - - - - - - - - -
multi-account-eks

In the above diagram, AWS RAM is used to share subnets from a cluster -account into a workload account. Then workloads running in EKS pods use -IRSA or EKS Pod Identities and role chaining to assume a role in their -workload account and access their AWS resources.

-
-

17.2.1. Implementing a Multi Workload Account Strategy for Multi Tenant Cluster

-
-
Sharing Subnets With AWS Resource Access Manager
-
-

AWS Resource Access Manager (RAM) allows -you to share resources across AWS accounts.

-
-
-

If -RAM -is enabled for your AWS Organization, you can share the VPC Subnets -from the Cluster account to your workload accounts. This will allow AWS -resources owned by your workload accounts, such as -Amazon ElastiCache Clusters or -Amazon Relational Database Service (RDS) -Databases to be deployed into the same VPC as your EKS cluster, and be -consumable by the workloads running on your EKS cluster.

-
-
-

To share a resource via RAM, open up RAM in the AWS console of the -cluster account and select “Resource Shares” and “Create Resource -Share”. Name your Resource Share and Select the subnets you want to -share. Select Next again and enter the 12 digit account IDs for the -workload accounts you wish to share the subnets with, select next again, -and click Create resource share to finish. After this step, the workload -account can deploy resources into those subnets.

-
-
-

RAM shares can also be created programmatically, or with infrastructure -as code.

-
-
-
-
Choosing Between EKS Pod Identities and IRSA
-
-

At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of -delivering temporary AWS credentials to your pods on EKS. Both IRSA and -EKS Pod Identities are valid methods for delivering temporary AWS -credentials to your EKS pods and will continue to be supported. You -should consider which method of delivering best meets your needs.

-
-
-

When working with a EKS cluster and multiple AWS accounts, IRSA can -directly assume roles in AWS accounts other than the account the EKS -cluster is hosted in directly, while EKS Pod identities require you to -configure role chaining. Refer -EKS -documentation for an in-depth comparison.

-
-
-
Accessing AWS API Resources with IAM Roles For Service Accounts
-
-

IAM -Roles for Service Accounts (IRSA) allows you to deliver temporary AWS -credentials to your workloads running on EKS. IRSA can be used to get -temporary credentials for IAM roles in the workload accounts from the -cluster account. This allows your workloads running on your EKS clusters -in the cluster account to consume AWS API resources, such as S3 buckets -hosted in the workload account seemlessly, and use IAM authentication -for resources like Amazon RDS Databases or Amazon EFS FileSystems.

-
-
-

AWS API resources and other Resources that use IAM authentication in a -workload account can only be accessed by credentials for IAM roles in -that same workload account, except where cross account access is capable -and has been explicity enabled.

-
-
-Enabling IRSA for cross account access -
-

To enable IRSA for workloads in your Cluster Account to access resources -in your Workload accounts, you first must create an IAM OIDC identity -provider in your workload account. This can be done with the same -procedure for setting up -IRSA, -except the Identity Provider will be created in the workload account.

-
-
-

Then when configuring IRSA for your workloads on EKS, you can -follow -the same steps as the documentation, but use the -12 -digit account id of the workload account as mentioned in the section -“Example Create an identity provider from another account’s cluster”.

-
-
-

After this is configured, your application running in EKS will be able -to directly use its service account to assume a role in the workload -account, and use resources within it.

-
-
-
-
-
Accessing AWS API Resources with EKS Pod Identities
-
-

EKS -Pod Identities is a new way of delivering AWS credentials to your -workloads running on EKS. EKS pod identities simplifies the -configuration of AWS resources as you no longer need to manage OIDC -configurations to deliver AWS credentials to your pods on EKS.

-
-
-Enabling EKS Pod Identities for cross account access -
-

Unlike IRSA, EKS Pod Identities can only be used to directly grant -access to a role in the same account as the EKS cluster. To access a -role in another AWS account, pods that use EKS Pod Identities must -perform -Role -Chaining.

-
-
-

Role chaining can be configured in an applications profile with their -aws configuration file using the -Process -Credentials Provider available in various AWS SDKs. -credential_process can be used as a credential source when -configuring a profile, such as:

-
-
-
-
# Content of the AWS Config file
-[profile account_b_role]
-source_profile = account_a_role
-role_arn = arn:aws:iam::444455556666:role/account-b-role
-
-[profile account_a_role]
-credential_process = /eks-credential-processrole.sh
-
-
-
-

The source of the script called by credential_process:

-
-
-
-
#!/bin/bash
-# Content of the eks-credential-processrole.sh
-# This will retreive the credential from the pod identities agent,
-# and return it to the AWS SDK when referenced in a profile
-curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}'
-
-
-
-

You can create an aws config file as shown above with both Account A and -B roles and specify the AWS_CONFIG_FILE and AWS_PROFILE env vars in your -pod spec. EKS Pod identity webhook does not override if the env vars -already exists in the pod spec.

-
-
-
-
# Snippet of the PodSpec
-containers:
-  - name: container-name
-    image: container-image:version
-    env:
-    - name: AWS_CONFIG_FILE
-      value: path-to-customer-provided-aws-config-file
-    - name: AWS_PROFILE
-      value: account_b_role
-
-
-
-

When configuring role trust policies for role chaining with EKS pod -identities, you can reference -EKS -specific attributes as session tags and use attribute based access -control(ABAC) to limit access to your IAM roles to only specific EKS Pod -identity sessions, such as the Kubernetes Service Account a pod belongs -to.

-
-
-

Please note that some of these attributes may not be universally unique, -for example two EKS clusters may have identical namespaces, and one -cluster may have identically named service accounts across namespaces. -So when granting access via EKS Pod Identities and ABAC, it is a best -practice to always consider the cluster arn and namespace when granting -access to a service account.

-
-
-
-ABAC and EKS Pod Identities for cross account access -
-

When using EKS Pod Identities to assume roles (role chaining) in other -accounts as part of a multi account strategy, you have the option to -assign a unique IAM role for each service account that needs to access -another account, or use a common IAM role across multiple service -accounts and use ABAC to control what accounts it can access.

-
-
-

To use ABAC to control what service accounts can assume a role into -another account with role chaining, you create a role trust policy -statement that only allows a role to be assumed by a role session when -the expected values are present. The following role trust policy will -only let a role from the EKS cluster account (account ID 111122223333) -assume a role if the kubernetes-service-account, eks-cluster-arn -and kubernetes-namespace tags all have the expected value.

-
-
-
-
{
-    "Version": "2012-10-17",
-    "Statement": [
-        {
-            "Effect": "Allow",
-            "Principal": {
-                "AWS": "arn:aws:iam::111122223333:root"
-            },
-            "Action": "sts:AssumeRole",
-            "Condition": {
-                "StringEquals": {
-                    "aws:PrincipalTag/kubernetes-service-account": "PayrollApplication",
-                    "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-east-1:111122223333:cluster/ProductionCluster",
-                    "aws:PrincipalTag/kubernetes-namespace": "PayrollNamespace"
-                }
-            }
-        }
-    ]
-}
-
-
-
-

When using this strategy it is a best practice to ensure that the common -IAM role only has sts:AssumeRole permissions and no other AWS -access.

-
-
-

It is important when using ABAC that you control who has the ability to -tag IAM roles and users to only those who have a strict need to do so. -Someone with the ability to tag an IAM role or user would be able to set -tags on roles/users identical to what would be set by EKS Pod Identities -and may be able to escalate their privileges. You can restrict who has -the access to set tags the kubernetes- and eks- tags on IAM role -and users using IAM policy, or Service Control Policy (SCP).

-
-
-
-
-
-
-
-

17.3. De-centralized EKS Clusters

-
-

In this approach, EKS clusters are deployed to respective workload AWS -Accounts and live along side with other AWS resources like Amazon S3 -buckets, VPCs, Amazon DynamoDB tables, etc., Each workload account is -independent, self-sufficient, and operated by respective Business -Unit/Application teams. This model allows the creation of reusuable -blueprints for various cluster capabilities (AI/ML cluster, Batch -processing, General purpose, etc.,) and vend the clusters based on the -application team requirements. Both application and platform teams -operate out of their respective -GitOps repositories to -manage the deployments to the workload clusters.

-
- --- - - - - - - - - - - -
De-centralized EKS Cluster Architecture

In the above diagram, Amazon EKS clusters and other AWS resources are -deployed to respective workload accounts. Then workloads running in EKS -pods use IRSA or EKS Pod Identities to access their AWS resources.

-
-

GitOps is a way of managing application and infrastructure deployment so -that the whole system is described declaratively in a Git repository. -It’s an operational model that offers you the ability to manage the -state of multiple Kubernetes clusters using the best practices of -version control, immutable artifacts, and automation. In this multi -cluster model, each workload cluster is bootstrapped with multiple Git -repos, allowing each team (application, platform, security, etc.,) to -deploy their respective changes on the cluster.

-
-
-

You would utilize -IAM -roles for Service Accounts (IRSA) or -EKS -Pod Identities in each account to allow your EKS workloads to get -temporary aws credentials to securely access other AWS resources. IAM -roles are created in respective workload AWS Accounts and map them to -k8s service accounts to provide temporary IAM access. So, no -cross-account access is required in this approach. Follow the -IAM -roles for Service Accounts documentation on how to setup in each -workload for IRSA, and -EKS -Pod Identities documentation on how to setup EKS pod identities in each -account.

-
-
-

17.3.1. Centralized Networking

-
-

You can also utilize AWS RAM to share the VPC Subnets to workload -accounts and launch Amazon EKS clusters and other AWS resources in them. -This enables centralized network managment/administration, simplified -network connectivity, and de-centralized EKS clusters. Refer this -AWS -blog for a detailed walkthrough and considerations of this approach.

-
- --- - - - - - - - - - - -
De-centralized EKS Cluster Architecture using VPC Shared Subnets

In the above diagram, AWS RAM is used to share subnets from a central -networking account into a workload account. Then EKS cluster and other -AWS resources are launched in those subnets in respective workload -accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS -resources.

-
-
-
-

17.4. Centralized vs De-centralized EKS clusters

-
-

The decision to run with a Centralized or De-centralized will depend on -your requirements. This table demonstrates the key differences with each -strategy.

-
- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#Centralized EKS clusterDe-centralized EKS clusters

Cluster Management:

Managing a single EKS cluster is easier than -administrating multiple clusters

An Efficient cluster management -automation is necessary to reduce the operational overhead of managing -multiple EKS clusters

Cost Efficiency:

Allows reuse of EKS cluster and network resources, -which promotes cost efficiency

Requires networking and cluster setups -per workload, which requires additional resources

Resilience:

Multiple workloads on the centralized cluster may be -impacted if a cluster becomes impaired

If a cluster becomes impaired, -the damage is limited to only the workloads that run on that cluster. -All other workloads are unaffected

Isolation & Security:

Isolation/Soft Multi-tenancy is achieved using -k8s native constructs like Namespaces. Workloads may share the -underlying resources like CPU, memory, etc. AWS resources are isolated -into their own workload accounts which by default are not accessible -from other AWS accounts.

Stronger isolation on compute resources as the -workloads run in individual clusters and nodes that don’t share any -resources. AWS resources are isolated into their own workload accounts -which by default are not accessible from other AWS accounts.

Performance & Scalabity:

As workloads grow to very large scales you -may encounter kubernetes and AWS service quotas in the cluster account. -You can deploy addtional cluster accounts to scale even further

As more -clusters and VPCs are present, each workload has more available k8s and -AWS service quota

Networking:

Single VPC is used per cluster, allowing for simpler -connectivity for applications on that cluster

Routing must be -established between the de-centralized EKS cluster VPCs

Kubernetes Access Management:

Need to maintain many different roles -and users in the cluster to provide access to all workload teams and -ensure kubernetes resources are properly segregated

Simplified access -management as each cluster is dedicated to a workload/team

AWS Access Management:

AWS resources are deployed into to their own -account which can only be accessed by default with IAM roles in the -workload account. IAM roles in the workload accounts are assumed cross -account either with IRSA or EKS Pod Identities.

AWS resources are -deployed into to their own account which can only be accessed by default -with IAM roles in the workload account. IAM roles in the workload -accounts are delivered directly to pods with IRSA or EKS Pod Identities

-
-
-
-
- - - \ No newline at end of file diff --git a/latest/bpg/security/multiaccount.adoc b/latest/bpg/security/multiaccount.adoc index 17b1064d0..ec6b845a6 100644 --- a/latest/bpg/security/multiaccount.adoc +++ b/latest/bpg/security/multiaccount.adoc @@ -58,34 +58,34 @@ information] is available in this AWS whitepaper. You can adopt the following approaches when implementing EKS Multi account strategy: -== Centralized EKS Cluster - -In this approach, your EKS Cluster will be deployed in a single AWS -account called the `+Cluster Account+`. Using -https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM -roles for Service Accounts (IRSA)] or -https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS -Pod Identities] to deliver temporary AWS credentials and -https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to -simplify network access, you can adopt a multi account strategy for your -multi tenant EKS cluster. The cluster account will contain the VPC, -subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and -any additional networking configurations needed to run your EKS cluster. - -In a multi workload account strategy for multi tenant cluster, AWS -accounts typically align with -https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes -namespaces] as a mechanism for isolating groups of resources. -link:/security/docs/multitenancy/[Best practices for tenant isolation] -within an EKS cluster should still be followed when implementing a multi -account strategy for multi tenant EKS clusters. - -It is possible to have multiple `+Cluster Accounts+` in your AWS -organization, and it is a best practice to have multiple -`+Cluster Accounts+` that align with your software development lifecycle -needs. For workloads operating at a very large scale, you may require -multiple `+Cluster Accounts+` to ensure that there are enough kubernetes -and AWS service quotas available to all your workloads. +// == Centralized EKS Cluster + +// In this approach, your EKS Cluster will be deployed in a single AWS +// account called the `+Cluster Account+`. Using +// https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +// roles for Service Accounts (IRSA)] or +// https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +// Pod Identities] to deliver temporary AWS credentials and +// https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to +// simplify network access, you can adopt a multi account strategy for your +// multi tenant EKS cluster. The cluster account will contain the VPC, +// subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and +// any additional networking configurations needed to run your EKS cluster. + +// In a multi workload account strategy for multi tenant cluster, AWS +// accounts typically align with +// https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes +// namespaces] as a mechanism for isolating groups of resources. +// link:/security/docs/multitenancy/[Best practices for tenant isolation] +// within an EKS cluster should still be followed when implementing a multi +// account strategy for multi tenant EKS clusters. + +// It is possible to have multiple `+Cluster Accounts+` in your AWS +// organization, and it is a best practice to have multiple +// `+Cluster Accounts+` that align with your software development lifecycle +// needs. For workloads operating at a very large scale, you may require +// multiple `+Cluster Accounts+` to ensure that there are enough kubernetes +// and AWS service quotas available to all your workloads. [width="100%",cols="^100%",options="header",] |=== diff --git a/latest/bpg/security/multiaccount.adoc.backup b/latest/bpg/security/multiaccount.adoc.backup new file mode 100644 index 000000000..17b1064d0 --- /dev/null +++ b/latest/bpg/security/multiaccount.adoc.backup @@ -0,0 +1,430 @@ +//!!NODE_ROOT
+[."topic"] +[[multi-account-strategy,multi-account-strategy.title]] += Multi Account Strategy +:info_doctype: section +:info_title: Multi Account Strategy +:info_abstract: Multi Account Strategy +:info_titleabbrev: Multi Account Strategy +:imagesdir: images/ + +AWS recommends using a +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-your-aws-environment.html[multi +account strategy] and AWS organizations to help isolate and manage your +business applications and data. There are +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html[many +benefits] to using a multi account strategy: + +* Increased AWS API service quotas. Quotas are applied to AWS accounts, +and using multiple accounts for your workloads increases the overall +quota available to your workloads. +* Simpler Identity and Access Management (IAM) policies. Granting +workloads and the operators that support them access to only their own +AWS accounts means less time crafting fine-grained IAM policies to +achieve the principle of least privilege. +* Improved Isolation of AWS resources. By design, all resources +provisioned within an account are logically isolated from resources +provisioned in other accounts. This isolation boundary provides you with +a way to limit the risks of an application-related issue, +misconfiguration, or malicious actions. If an issue occurs within one +account, impacts to workloads contained in other accounts can be either +reduced or eliminated. +* More benefits, as described in the +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html#group-workloads-based-on-business-purpose-and-ownership[AWS +Multi Account Strategy Whitepaper] + +The following sections will explain how to implement a multi account +strategy for your EKS workloads using either a centralized, or +de-centralized EKS cluster approach. + +== Planning for a Multi Workload Account Strategy for Multi Tenant Clusters + +In a multi account AWS strategy, resources that belong to a given +workload such as S3 buckets, ElastiCache clusters and DynamoDB Tables +are all created in an AWS account that contains all the resources for +that workload. These are referred to as a workload account, and the EKS +cluster is deployed into an account referred to as the cluster account. +Cluster accounts will be explored in the next section. Deploying +resources into a dedicated workload account is similar to deploying +kubernetes resources into a dedicated namespace. + +Workload accounts can then be further broken down by software +development lifecycle or other requirements if appropriate. For example +a given workload can have a production account, a development account, +or accounts for hosting instances of that workload in a specific region. +https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/organizing-workload-oriented-ous.html[More +information] is available in this AWS whitepaper. + +You can adopt the following approaches when implementing EKS Multi +account strategy: + +== Centralized EKS Cluster + +In this approach, your EKS Cluster will be deployed in a single AWS +account called the `+Cluster Account+`. Using +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts (IRSA)] or +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] to deliver temporary AWS credentials and +https://aws.amazon.com/ram/[AWS Resource Access Manager (RAM)] to +simplify network access, you can adopt a multi account strategy for your +multi tenant EKS cluster. The cluster account will contain the VPC, +subnets, EKS cluster, EC2/Fargate compute resources (worker nodes), and +any additional networking configurations needed to run your EKS cluster. + +In a multi workload account strategy for multi tenant cluster, AWS +accounts typically align with +https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/[kubernetes +namespaces] as a mechanism for isolating groups of resources. +link:/security/docs/multitenancy/[Best practices for tenant isolation] +within an EKS cluster should still be followed when implementing a multi +account strategy for multi tenant EKS clusters. + +It is possible to have multiple `+Cluster Accounts+` in your AWS +organization, and it is a best practice to have multiple +`+Cluster Accounts+` that align with your software development lifecycle +needs. For workloads operating at a very large scale, you may require +multiple `+Cluster Accounts+` to ensure that there are enough kubernetes +and AWS service quotas available to all your workloads. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks.jpg[multi-account-eks] +|In the above diagram, AWS RAM is used to share subnets from a cluster +account into a workload account. Then workloads running in EKS pods use +IRSA or EKS Pod Identities and role chaining to assume a role in their +workload account and access their AWS resources. +|=== + +=== Implementing a Multi Workload Account Strategy for Multi Tenant Cluster + +==== Sharing Subnets With AWS Resource Access Manager + +https://aws.amazon.com/ram/[AWS Resource Access Manager] (RAM) allows +you to share resources across AWS accounts. + +If +https://docs.aws.amazon.com/ram/latest/userguide/getting-started-sharing.html#getting-started-sharing-orgs[RAM +is enabled for your AWS Organization], you can share the VPC Subnets +from the Cluster account to your workload accounts. This will allow AWS +resources owned by your workload accounts, such as +https://aws.amazon.com/elasticache/[Amazon ElastiCache] Clusters or +https://aws.amazon.com/rds/[Amazon Relational Database Service (RDS)] +Databases to be deployed into the same VPC as your EKS cluster, and be +consumable by the workloads running on your EKS cluster. + +To share a resource via RAM, open up RAM in the AWS console of the +cluster account and select "`Resource Shares`" and "`Create Resource +Share`". Name your Resource Share and Select the subnets you want to +share. Select Next again and enter the 12 digit account IDs for the +workload accounts you wish to share the subnets with, select next again, +and click Create resource share to finish. After this step, the workload +account can deploy resources into those subnets. + +RAM shares can also be created programmatically, or with infrastructure +as code. + +==== Choosing Between EKS Pod Identities and IRSA + +At re:Invent 2023, AWS launched EKS Pod Identities as a simpler way of +delivering temporary AWS credentials to your pods on EKS. Both IRSA and +EKS Pod Identities are valid methods for delivering temporary AWS +credentials to your EKS pods and will continue to be supported. You +should consider which method of delivering best meets your needs. + +When working with a EKS cluster and multiple AWS accounts, IRSA can +directly assume roles in AWS accounts other than the account the EKS +cluster is hosted in directly, while EKS Pod identities require you to +configure role chaining. Refer +https://docs.aws.amazon.com/eks/latest/userguide/service-accounts.html#service-accounts-iam[EKS +documentation] for an in-depth comparison. + +===== Accessing AWS API Resources with IAM Roles For Service Accounts + +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +Roles for Service Accounts (IRSA)] allows you to deliver temporary AWS +credentials to your workloads running on EKS. IRSA can be used to get +temporary credentials for IAM roles in the workload accounts from the +cluster account. This allows your workloads running on your EKS clusters +in the cluster account to consume AWS API resources, such as S3 buckets +hosted in the workload account seemlessly, and use IAM authentication +for resources like Amazon RDS Databases or Amazon EFS FileSystems. + +AWS API resources and other Resources that use IAM authentication in a +workload account can only be accessed by credentials for IAM roles in +that same workload account, except where cross account access is capable +and has been explicity enabled. + +====== Enabling IRSA for cross account access + +To enable IRSA for workloads in your Cluster Account to access resources +in your Workload accounts, you first must create an IAM OIDC identity +provider in your workload account. This can be done with the same +procedure for setting up +https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html[IRSA], +except the Identity Provider will be created in the workload account. + +Then when configuring IRSA for your workloads on EKS, you can +https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html[follow +the same steps as the documentation], but use the +https://docs.aws.amazon.com/eks/latest/userguide/cross-account-access.html[12 +digit account id of the workload account] as mentioned in the section +"`Example Create an identity provider from another account’s cluster`". + +After this is configured, your application running in EKS will be able +to directly use its service account to assume a role in the workload +account, and use resources within it. + +===== Accessing AWS API Resources with EKS Pod Identities + +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] is a new way of delivering AWS credentials to your +workloads running on EKS. EKS pod identities simplifies the +configuration of AWS resources as you no longer need to manage OIDC +configurations to deliver AWS credentials to your pods on EKS. + +====== Enabling EKS Pod Identities for cross account access + +Unlike IRSA, EKS Pod Identities can only be used to directly grant +access to a role in the same account as the EKS cluster. To access a +role in another AWS account, pods that use EKS Pod Identities must +perform +https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining[Role +Chaining]. + +Role chaining can be configured in an applications profile with their +aws configuration file using the +https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process +Credentials Provider] available in various AWS SDKs. +`+credential_process+` can be used as a credential source when +configuring a profile, such as: + +[source,bash] +---- +# Content of the AWS Config file +[profile account_b_role] +source_profile = account_a_role +role_arn = arn:aws:iam::444455556666:role/account-b-role + +[profile account_a_role] +credential_process = /eks-credential-processrole.sh +---- + +The source of the script called by credential_process: + +[source,bash] +---- +#!/bin/bash +# Content of the eks-credential-processrole.sh +# This will retreive the credential from the pod identities agent, +# and return it to the AWS SDK when referenced in a profile +curl -H "Authorization: $(cat $AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE)" $AWS_CONTAINER_CREDENTIALS_FULL_URI | jq -c '{AccessKeyId: .AccessKeyId, SecretAccessKey: .SecretAccessKey, SessionToken: .Token, Expiration: .Expiration, Version: 1}' +---- + +You can create an aws config file as shown above with both Account A and +B roles and specify the AWS_CONFIG_FILE and AWS_PROFILE env vars in your +pod spec. EKS Pod identity webhook does not override if the env vars +already exists in the pod spec. + +[source,yaml] +---- +# Snippet of the PodSpec +containers: + - name: container-name + image: container-image:version + env: + - name: AWS_CONFIG_FILE + value: path-to-customer-provided-aws-config-file + - name: AWS_PROFILE + value: account_b_role +---- + +When configuring role trust policies for role chaining with EKS pod +identities, you can reference +https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html[EKS +specific attributes] as session tags and use attribute based access +control(ABAC) to limit access to your IAM roles to only specific EKS Pod +identity sessions, such as the Kubernetes Service Account a pod belongs +to. + +Please note that some of these attributes may not be universally unique, +for example two EKS clusters may have identical namespaces, and one +cluster may have identically named service accounts across namespaces. +So when granting access via EKS Pod Identities and ABAC, it is a best +practice to always consider the cluster arn and namespace when granting +access to a service account. + +====== ABAC and EKS Pod Identities for cross account access + +When using EKS Pod Identities to assume roles (role chaining) in other +accounts as part of a multi account strategy, you have the option to +assign a unique IAM role for each service account that needs to access +another account, or use a common IAM role across multiple service +accounts and use ABAC to control what accounts it can access. + +To use ABAC to control what service accounts can assume a role into +another account with role chaining, you create a role trust policy +statement that only allows a role to be assumed by a role session when +the expected values are present. The following role trust policy will +only let a role from the EKS cluster account (account ID 111122223333) +assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+` +and `+kubernetes-namespace+` tags all have the expected value. + +[source,json] +---- +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::111122223333:root" + }, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "aws:PrincipalTag/kubernetes-service-account": "PayrollApplication", + "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-east-1:111122223333:cluster/ProductionCluster", + "aws:PrincipalTag/kubernetes-namespace": "PayrollNamespace" + } + } + } + ] +} +---- + +When using this strategy it is a best practice to ensure that the common +IAM role only has `+sts:AssumeRole+` permissions and no other AWS +access. + +It is important when using ABAC that you control who has the ability to +tag IAM roles and users to only those who have a strict need to do so. +Someone with the ability to tag an IAM role or user would be able to set +tags on roles/users identical to what would be set by EKS Pod Identities +and may be able to escalate their privileges. You can restrict who has +the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role +and users using IAM policy, or Service Control Policy (SCP). + +== De-centralized EKS Clusters + +In this approach, EKS clusters are deployed to respective workload AWS +Accounts and live along side with other AWS resources like Amazon S3 +buckets, VPCs, Amazon DynamoDB tables, etc., Each workload account is +independent, self-sufficient, and operated by respective Business +Unit/Application teams. This model allows the creation of reusuable +blueprints for various cluster capabilities (AI/ML cluster, Batch +processing, General purpose, etc.,) and vend the clusters based on the +application team requirements. Both application and platform teams +operate out of their respective +https://www.weave.works/technologies/gitops/[GitOps] repositories to +manage the deployments to the workload clusters. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks-decentralized.png[De-centralized EKS +Cluster Architecture] +|In the above diagram, Amazon EKS clusters and other AWS resources are +deployed to respective workload accounts. Then workloads running in EKS +pods use IRSA or EKS Pod Identities to access their AWS resources. +|=== + +GitOps is a way of managing application and infrastructure deployment so +that the whole system is described declaratively in a Git repository. +It’s an operational model that offers you the ability to manage the +state of multiple Kubernetes clusters using the best practices of +version control, immutable artifacts, and automation. In this multi +cluster model, each workload cluster is bootstrapped with multiple Git +repos, allowing each team (application, platform, security, etc.,) to +deploy their respective changes on the cluster. + +You would utilize +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts (IRSA)] or +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] in each account to allow your EKS workloads to get +temporary aws credentials to securely access other AWS resources. IAM +roles are created in respective workload AWS Accounts and map them to +k8s service accounts to provide temporary IAM access. So, no +cross-account access is required in this approach. Follow the +https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM +roles for Service Accounts] documentation on how to setup in each +workload for IRSA, and +https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS +Pod Identities] documentation on how to setup EKS pod identities in each +account. + +=== Centralized Networking + +You can also utilize AWS RAM to share the VPC Subnets to workload +accounts and launch Amazon EKS clusters and other AWS resources in them. +This enables centralized network managment/administration, simplified +network connectivity, and de-centralized EKS clusters. Refer this +https://aws.amazon.com/blogs/containers/use-shared-vpcs-in-amazon-eks/[AWS +blog] for a detailed walkthrough and considerations of this approach. + +[width="100%",cols="^100%",options="header",] +|=== +|image:./images/multi-account-eks-shared-subnets.png[De-centralized EKS +Cluster Architecture using VPC Shared Subnets] +|In the above diagram, AWS RAM is used to share subnets from a central +networking account into a workload account. Then EKS cluster and other +AWS resources are launched in those subnets in respective workload +accounts. EKS pods use IRSA or EKS Pod Identities to access their AWS +resources. +|=== + +== Centralized vs De-centralized EKS clusters + +The decision to run with a Centralized or De-centralized will depend on +your requirements. This table demonstrates the key differences with each +strategy. + +[width="100%",cols="<34%,<33%,<33%",options="header",] +|=== +|# |Centralized EKS cluster |De-centralized EKS clusters +|Cluster Management: |Managing a single EKS cluster is easier than +administrating multiple clusters |An Efficient cluster management +automation is necessary to reduce the operational overhead of managing +multiple EKS clusters + +|Cost Efficiency: |Allows reuse of EKS cluster and network resources, +which promotes cost efficiency |Requires networking and cluster setups +per workload, which requires additional resources + +|Resilience: |Multiple workloads on the centralized cluster may be +impacted if a cluster becomes impaired |If a cluster becomes impaired, +the damage is limited to only the workloads that run on that cluster. +All other workloads are unaffected + +|Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using +k8s native constructs like `+Namespaces+`. Workloads may share the +underlying resources like CPU, memory, etc. AWS resources are isolated +into their own workload accounts which by default are not accessible +from other AWS accounts. |Stronger isolation on compute resources as the +workloads run in individual clusters and nodes that don’t share any +resources. AWS resources are isolated into their own workload accounts +which by default are not accessible from other AWS accounts. + +|Performance & Scalabity: |As workloads grow to very large scales you +may encounter kubernetes and AWS service quotas in the cluster account. +You can deploy addtional cluster accounts to scale even further |As more +clusters and VPCs are present, each workload has more available k8s and +AWS service quota + +|Networking: |Single VPC is used per cluster, allowing for simpler +connectivity for applications on that cluster |Routing must be +established between the de-centralized EKS cluster VPCs + +|Kubernetes Access Management: |Need to maintain many different roles +and users in the cluster to provide access to all workload teams and +ensure kubernetes resources are properly segregated |Simplified access +management as each cluster is dedicated to a workload/team + +|AWS Access Management: |AWS resources are deployed into to their own +account which can only be accessed by default with IAM roles in the +workload account. IAM roles in the workload accounts are assumed cross +account either with IRSA or EKS Pod Identities. |AWS resources are +deployed into to their own account which can only be accessed by default +with IAM roles in the workload account. IAM roles in the workload +accounts are delivered directly to pods with IRSA or EKS Pod Identities +|=== diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index 93c1964f1..79213f6f5 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -9,7 +9,7 @@ from typing import List, Tuple # File to test -TEST_FILE = 'multiaccount.adoc' +TEST_FILE = 'hosts.adoc' @dataclass class Section: From cf586391fb2d47ac1a7fb6c50a3552366e7cf982 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 2 Jul 2024 19:51:18 -0500 Subject: [PATCH 26/56] fixup --- build-info.xml | 2 +- latest/bpg/security/index.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build-info.xml b/build-info.xml index a33fed418..5cc1d1222 100755 --- a/build-info.xml +++ b/build-info.xml @@ -31,7 +31,7 @@ - + diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index 26f7e6c30..dfd8f6db5 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -155,7 +155,7 @@ include::data.adoc[leveloffset=+1] include::runtime.adoc[leveloffset=+1] -include::hosts.adoc[leveloffset=+1] +// include::hosts.adoc[leveloffset=+1] include::compliance.adoc[leveloffset=+1] From 47110247899835237dde64f1c13341f1ba63f274 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Thu, 11 Jul 2024 08:58:29 -0700 Subject: [PATCH 27/56] fixup --- latest/bpg/security/data.adoc | 8 +-- latest/bpg/security/detective.adoc | 8 +-- latest/bpg/security/fix-literals.py | 6 +-- latest/bpg/security/hosts.adoc | 32 +++++------ latest/bpg/security/hosts.adoc.backup | 32 +++++------ latest/bpg/security/image.adoc | 26 ++++----- latest/bpg/security/incidents.adoc | 14 ++--- latest/bpg/security/multiaccount.adoc | 20 +++---- latest/bpg/security/multiaccount.adoc.backup | 20 +++---- latest/bpg/security/multitenancy.adoc | 34 ++++++------ latest/bpg/security/network.adoc | 56 ++++++++++---------- latest/bpg/security/runtime.adoc | 16 +++--- latest/bpg/security/test.py | 2 +- 13 files changed, 137 insertions(+), 137 deletions(-) diff --git a/latest/bpg/security/data.adoc b/latest/bpg/security/data.adoc index 530b16d1a..1fffae4a7 100644 --- a/latest/bpg/security/data.adoc +++ b/latest/bpg/security/data.adoc @@ -31,7 +31,7 @@ https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html[Encrypting Data at Rest]. Besides offering at-rest encryption, EFS and FSx for Lustre include an option for encrypting data in transit. FSx for Lustre does this by default. For EFS, you can add transport encryption by -adding the `+tls+` parameter to `+mountOptions+` in your PV as in this +adding the `tls` parameter to `mountOptions` in your PV as in this example: [source,yaml] @@ -101,7 +101,7 @@ different mount points, consider using EFS access points. To learn more about working with access points, see https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html. Today, if you want to use an access point (AP) you’ll need to reference the AP -in the PV’s `+volumeHandle+` parameter. +in the PV’s `volumeHandle` parameter. !!! attention As of March 23, 2021 the EFS CSI driver supports dynamic provisioning of EFS Access Points. Access points are @@ -119,7 +119,7 @@ base64 encoded strings. On EKS, the EBS volumes for etcd nodes are encrypted with https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html[EBS encryption]. A pod can retrieve a Kubernetes secrets objects by -referencing the secret in the `+podSpec+`. These secrets can either be +referencing the secret in the `podSpec`. These secrets can either be mapped to an environment variable or mounted as volume. For additional information on creating secrets, see https://kubernetes.io/docs/concepts/configuration/secret/. @@ -146,7 +146,7 @@ EKS encryption provider support for defense in depth] On EKS, turn on audit logging and create a CloudWatch metrics filter and alarm to alert you when a secret is used (optional). The following is an example of a metrics filter for the Kubernetes audit log, -`+{($.verb="get") && ($.objectRef.resource="secret")}+`. You can also +`{($.verb="get") && ($.objectRef.resource="secret")}`. You can also use the following queries with CloudWatch Log Insights: [source,bash] diff --git a/latest/bpg/security/detective.adoc b/latest/bpg/security/detective.adoc index 2a222d53d..c4be183bc 100644 --- a/latest/bpg/security/detective.adoc +++ b/latest/bpg/security/detective.adoc @@ -194,15 +194,15 @@ metadata. === Utilize audit metadata Kubernetes audit logs include two annotations that indicate whether or -not a request was authorized `+authorization.k8s.io/decision+` and the -reason for the decision `+authorization.k8s.io/reason+`. Use these +not a request was authorized `authorization.k8s.io/decision` and the +reason for the decision `authorization.k8s.io/reason`. Use these attributes to ascertain why a particular API call was allowed. === Create alarms for suspicious events Create an alarm to automatically alert you where there is an increase in 403 Forbidden and 401 Unauthorized responses, and then use attributes -like `+host+`, `+sourceIPs+`, and `+k8s_user.username+` to find out +like `host`, `sourceIPs`, and `k8s_user.username` to find out where those requests are coming from. === Analyze logs with Log Insights @@ -211,7 +211,7 @@ Use CloudWatch Log Insights to monitor changes to RBAC objects, e.g. Roles, RoleBindings, ClusterRoles, and ClusterRoleBindings. A few sample queries appear below: -Lists updates to the `+aws-auth+` ConfigMap: +Lists updates to the `aws-auth` ConfigMap: [source,bash] ---- diff --git a/latest/bpg/security/fix-literals.py b/latest/bpg/security/fix-literals.py index 7674a45be..77f2d4c00 100644 --- a/latest/bpg/security/fix-literals.py +++ b/latest/bpg/security/fix-literals.py @@ -12,15 +12,15 @@ def fix_code_literals(filename): with open(filename, 'r') as file: content = file.read() - # Use regex to replace `+code literal+` with `code literal` - pattern = r'`\+(.*?)\+`' + # Use regex to replace `code literal` with `code literal` + pattern = r'`\+(.*?)\`' replaced_content, count = re.subn(pattern, r'`\1`', content) # Write the modified content back to the file with open(filename, 'w') as file: file.write(replaced_content) - print(f"Replaced {count} instances of `+code literal+` syntax.") + print(f"Replaced {count} instances of `code literal` syntax.") print(f"Modified file saved as: {filename}") print(f"Original file backed up as: {filename}.backup") diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index e47ef28b1..248970c4f 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -62,7 +62,7 @@ the nodes have been replaced. EKS https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed node groups] uses the first approach and will display a message in the console to upgrade your workers when a new AMI becomes available. -`+eksctl+` also has a mechanism for creating node groups with the latest +`eksctl` also has a mechanism for creating node groups with the latest AMI and for gracefully cordoning and draining pods from nodes groups before the instances are terminated. If you decide to use a different method for replacing your worker nodes, it is strongly recommended that @@ -115,10 +115,10 @@ example]. ==== Minimal IAM policy for SSM based SSH Access -The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a +The `AmazonSSMManagedInstanceCore` AWS managed policy contains a number of permissions that are not required for SSM Session Manager / SSM RunCommand if you’re just looking to avoid SSH access. Of concern -specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which +specifically is the `*` permissions for `ssm:GetParameter(s)` which would allow for the role to access all parameters in Parameter Store (including SecureStrings with the AWS managed KMS key configured). @@ -229,12 +229,12 @@ Fargate pods. // package. Docker CE requires this package (along with its dependencies) // so that the processes and files created by Docker (or other container // runtimes) run with limited system access. Containers leverage the -// `+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +// `container_t` label which is an alias to `svirt_lxc_net_t`. These // policies effectively prevent containers from accessing certain features // of the host. // When you configure SELinux for Docker, Docker automatically labels -// workloads `+container_t+` as a type and gives each container a unique +// workloads `container_t` as a type and gives each container a unique // MCS level. This will isolate containers from one another. If you need // looser restrictions, you can create your own profile in SElinux which // grants a container permissions to specific areas of the file system. @@ -250,21 +250,21 @@ Fargate pods. // [width="100%",cols="30%,^40%,30%",options="header",] // |=== // |Boolean |Default |Description -// |`+container_connect_any+` |`+off+` |Allow containers to access +// |`container_connect_any` |`off` |Allow containers to access // privileged ports on the host. For example, if you have a container that // needs to map ports to 443 or 80 on the host. -// |`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +// |`container_manage_cgroup` |`off` |Allow containers to manage cgroup // configuration. For example, a container running systemd will need this // to be enabled. -// |`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file +// |`container_use_cephfs` |`off` |Allow containers to use a ceph file // system. // |=== -// By default, containers are allowed to read/execute under `+/usr+` and -// read most content from `+/etc+`. The files under `+/var/lib/docker+` and -// `+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +// By default, containers are allowed to read/execute under `/usr` and +// read most content from `/etc`. The files under `/var/lib/docker` and +// `/var/lib/containers` have the label `container_var_lib_t`. To view // a full list of default, labels see the // https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] // file. @@ -282,12 +282,12 @@ Fargate pods. // # cat: /host/etc/passwd: Permission denied // ---- -// Files labeled with `+container_file_t+` are the only files that are +// Files labeled with `container_file_t` are the only files that are // writable by containers. If you want a volume mount to be writeable, you -// will needed to specify `+:z+` or `+:Z+` at the end. +// will needed to specify `:z` or `:Z` at the end. -// * `+:z+` will re-label the files so that the container can read/write -// * `+:Z+` will re-label the files so that *only* the container can +// * `:z` will re-label the files so that the container can read/write +// * `:Z` will re-label the files so that *only* the container can // read/write // [source,bash] @@ -327,7 +327,7 @@ Fargate pods. // level: s0:c144:c154 // ---- -// In this example `+s0:c144:c154+` corresponds to an MCS label assigned to +// In this example `s0:c144:c154` corresponds to an MCS label assigned to // a file that the container is allowed to access. // On EKS you could create policies that allow for privileged containers to diff --git a/latest/bpg/security/hosts.adoc.backup b/latest/bpg/security/hosts.adoc.backup index e47ef28b1..248970c4f 100644 --- a/latest/bpg/security/hosts.adoc.backup +++ b/latest/bpg/security/hosts.adoc.backup @@ -62,7 +62,7 @@ the nodes have been replaced. EKS https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed node groups] uses the first approach and will display a message in the console to upgrade your workers when a new AMI becomes available. -`+eksctl+` also has a mechanism for creating node groups with the latest +`eksctl` also has a mechanism for creating node groups with the latest AMI and for gracefully cordoning and draining pods from nodes groups before the instances are terminated. If you decide to use a different method for replacing your worker nodes, it is strongly recommended that @@ -115,10 +115,10 @@ example]. ==== Minimal IAM policy for SSM based SSH Access -The `+AmazonSSMManagedInstanceCore+` AWS managed policy contains a +The `AmazonSSMManagedInstanceCore` AWS managed policy contains a number of permissions that are not required for SSM Session Manager / SSM RunCommand if you’re just looking to avoid SSH access. Of concern -specifically is the `+*+` permissions for `+ssm:GetParameter(s)+` which +specifically is the `*` permissions for `ssm:GetParameter(s)` which would allow for the role to access all parameters in Parameter Store (including SecureStrings with the AWS managed KMS key configured). @@ -229,12 +229,12 @@ Fargate pods. // package. Docker CE requires this package (along with its dependencies) // so that the processes and files created by Docker (or other container // runtimes) run with limited system access. Containers leverage the -// `+container_t+` label which is an alias to `+svirt_lxc_net_t+`. These +// `container_t` label which is an alias to `svirt_lxc_net_t`. These // policies effectively prevent containers from accessing certain features // of the host. // When you configure SELinux for Docker, Docker automatically labels -// workloads `+container_t+` as a type and gives each container a unique +// workloads `container_t` as a type and gives each container a unique // MCS level. This will isolate containers from one another. If you need // looser restrictions, you can create your own profile in SElinux which // grants a container permissions to specific areas of the file system. @@ -250,21 +250,21 @@ Fargate pods. // [width="100%",cols="30%,^40%,30%",options="header",] // |=== // |Boolean |Default |Description -// |`+container_connect_any+` |`+off+` |Allow containers to access +// |`container_connect_any` |`off` |Allow containers to access // privileged ports on the host. For example, if you have a container that // needs to map ports to 443 or 80 on the host. -// |`+container_manage_cgroup+` |`+off+` |Allow containers to manage cgroup +// |`container_manage_cgroup` |`off` |Allow containers to manage cgroup // configuration. For example, a container running systemd will need this // to be enabled. -// |`+container_use_cephfs+` |`+off+` |Allow containers to use a ceph file +// |`container_use_cephfs` |`off` |Allow containers to use a ceph file // system. // |=== -// By default, containers are allowed to read/execute under `+/usr+` and -// read most content from `+/etc+`. The files under `+/var/lib/docker+` and -// `+/var/lib/containers+` have the label `+container_var_lib_t+`. To view +// By default, containers are allowed to read/execute under `/usr` and +// read most content from `/etc`. The files under `/var/lib/docker` and +// `/var/lib/containers` have the label `container_var_lib_t`. To view // a full list of default, labels see the // https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] // file. @@ -282,12 +282,12 @@ Fargate pods. // # cat: /host/etc/passwd: Permission denied // ---- -// Files labeled with `+container_file_t+` are the only files that are +// Files labeled with `container_file_t` are the only files that are // writable by containers. If you want a volume mount to be writeable, you -// will needed to specify `+:z+` or `+:Z+` at the end. +// will needed to specify `:z` or `:Z` at the end. -// * `+:z+` will re-label the files so that the container can read/write -// * `+:Z+` will re-label the files so that *only* the container can +// * `:z` will re-label the files so that the container can read/write +// * `:Z` will re-label the files so that *only* the container can // read/write // [source,bash] @@ -327,7 +327,7 @@ Fargate pods. // level: s0:c144:c154 // ---- -// In this example `+s0:c144:c154+` corresponds to an MCS label assigned to +// In this example `s0:c144:c154` corresponds to an MCS label assigned to // a file that the container is allowed to access. // On EKS you could create policies that allow for privileged containers to diff --git a/latest/bpg/security/image.adoc b/latest/bpg/security/image.adoc index db0caed13..b91217954 100644 --- a/latest/bpg/security/image.adoc +++ b/latest/bpg/security/image.adoc @@ -261,16 +261,16 @@ all actions against your and only your ECR repositories: ---- You can enhance this further by setting a condition that uses the new -`+PrincipalOrgID+` attribute which will prevent pushing/pulling of +`PrincipalOrgID` attribute which will prevent pushing/pulling of images by an IAM principle that is not part of your AWS Organization. See, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid[aws:PrincipalOrgID] for additional details. We recommended applying the same policy to both -the `+com.amazonaws..ecr.dkr+` and the -`+com.amazonaws..ecr.api+` endpoints. Since EKS pulls images for +the `com.amazonaws..ecr.dkr` and the +`com.amazonaws..ecr.api` endpoints. Since EKS pulls images for kube-proxy, coredns, and aws-node from ECR, you will need to add the account ID of the registry, -e.g. `+602401143452.dkr.ecr.us-west-2.amazonaws.com/*+` to the list of +e.g. `602401143452.dkr.ecr.us-west-2.amazonaws.com/*` to the list of resources in the endpoint policy or alter the policy to allow pulls from “*” and restrict pushes to your account ID. The table below reveals the mapping between the AWS accounts where EKS images are vended from and @@ -340,15 +340,15 @@ https://vulnerablecontainers.org/[here]. As was mentioned in the pod security section, you should avoid running container as root. While you can configure this as part of the podSpec, -it is a good habit to use the `+USER+` directive to your Dockerfiles. -The `+USER+` directive sets the UID to use when running `+RUN+`, -`+ENTRYPOINT+`, or `+CMD+` instruction that appears after the USER +it is a good habit to use the `USER` directive to your Dockerfiles. +The `USER` directive sets the UID to use when running `RUN`, +`ENTRYPOINT`, or `CMD` instruction that appears after the USER directive. === Lint your Dockerfiles Linting can be used to verify that your Dockerfiles are adhering to a -set of predefined guidelines, e.g. the inclusion of the `+USER+` +set of predefined guidelines, e.g. the inclusion of the `USER` directive or the requirement that all images be tagged. https://github.com/projectatomic/dockerfile_lint[dockerfile_lint] is an open source project from RedHat that verifies common best practices and @@ -363,7 +363,7 @@ aim when building images. The ideal way to do this is by creating minimal images that are devoid of binaries that can be used to exploit vulnerabilities. Fortunately, Docker has a mechanism to create images from -https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch[`+scratch+`]. +https://docs.docker.com/develop/develop-images/baseimages/#create-a-simple-parent-image-using-scratch[`scratch`]. With languages like Go, you can create a static linked binary and reference it in your Dockerfile as in this example: @@ -455,7 +455,7 @@ Examples of admission controller include: === Update the packages in your container images -You should include RUN `+apt-get update && apt-get upgrade+` in your +You should include RUN `apt-get update && apt-get upgrade` in your Dockerfiles to upgrade the packages in your images. Although upgrading requires you to run as root, this occurs during image build phase. The application doesn’t need to run as root. You can install the updates and @@ -464,9 +464,9 @@ image runs as a non-root user, switch to root and back; don’t solely rely on the maintainers of the base image to install the latest security updates. -Run `+apt-get clean+` to delete the installer files from -`+/var/cache/apt/archives/+`. You can also run -`+rm -rf /var/lib/apt/lists/*+` after installing packages. This removes +Run `apt-get clean` to delete the installer files from +`/var/cache/apt/archives/`. You can also run +`rm -rf /var/lib/apt/lists/*` after installing packages. This removes the index files or the lists of packages that are available to install. Be aware that these commands may be different for each package manager. For example: diff --git a/latest/bpg/security/incidents.adoc b/latest/bpg/security/incidents.adoc index 247504ef4..312cbeb80 100644 --- a/latest/bpg/security/incidents.adoc +++ b/latest/bpg/security/incidents.adoc @@ -93,7 +93,7 @@ kubectl get pods -o json --all-namespaces | \ A deny all traffic rule may help stop an attack that is already underway by severing all connections to the pod. The following Network Policy -will apply to a pod with the label `+app=web+`. +will apply to a pod with the label `app=web`. [source,yaml] ---- @@ -170,17 +170,17 @@ container. altered*. You can use capabilities of the container runtime to capture information about currently running containers. For example, with Docker, you could do the following: -** `+docker top CONTAINER+` for processes running. -** `+docker logs CONTAINER+` for daemon level held logs. -** `+docker inspect CONTAINER+` for various information about the +** `docker top CONTAINER` for processes running. +** `docker logs CONTAINER` for daemon level held logs. +** `docker inspect CONTAINER` for various information about the container. + The same could be achieved with containerd using the https://github.com/containerd/nerdctl[nerdctl] CLI, in place of -`+docker+` (e.g. `+nerdctl inspect+`). Some additional commands are +`docker` (e.g. `nerdctl inspect`). Some additional commands are available depending on the container runtime. For example, Docker has -`+docker diff+` to see changes to the container filesystem or -`+docker checkpoint+` to save all container state including volatile +`docker diff` to see changes to the container filesystem or +`docker checkpoint` to save all container state including volatile memory (RAM). See https://kubernetes.io/blog/2022/12/05/forensic-container-checkpointing-alpha/[this Kubernetes blog post] for discussion of similar capabilities with diff --git a/latest/bpg/security/multiaccount.adoc b/latest/bpg/security/multiaccount.adoc index ec6b845a6..1bfa4e140 100644 --- a/latest/bpg/security/multiaccount.adoc +++ b/latest/bpg/security/multiaccount.adoc @@ -61,7 +61,7 @@ account strategy: // == Centralized EKS Cluster // In this approach, your EKS Cluster will be deployed in a single AWS -// account called the `+Cluster Account+`. Using +// account called the `Cluster Account`. Using // https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM // roles for Service Accounts (IRSA)] or // https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS @@ -80,11 +80,11 @@ account strategy: // within an EKS cluster should still be followed when implementing a multi // account strategy for multi tenant EKS clusters. -// It is possible to have multiple `+Cluster Accounts+` in your AWS +// It is possible to have multiple `Cluster Accounts` in your AWS // organization, and it is a best practice to have multiple -// `+Cluster Accounts+` that align with your software development lifecycle +// `Cluster Accounts` that align with your software development lifecycle // needs. For workloads operating at a very large scale, you may require -// multiple `+Cluster Accounts+` to ensure that there are enough kubernetes +// multiple `Cluster Accounts` to ensure that there are enough kubernetes // and AWS service quotas available to all your workloads. [width="100%",cols="^100%",options="header",] @@ -196,7 +196,7 @@ Role chaining can be configured in an applications profile with their aws configuration file using the https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process Credentials Provider] available in various AWS SDKs. -`+credential_process+` can be used as a credential source when +`credential_process` can be used as a credential source when configuring a profile, such as: [source,bash] @@ -267,8 +267,8 @@ another account with role chaining, you create a role trust policy statement that only allows a role to be assumed by a role session when the expected values are present. The following role trust policy will only let a role from the EKS cluster account (account ID 111122223333) -assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+` -and `+kubernetes-namespace+` tags all have the expected value. +assume a role if the `kubernetes-service-account`, `eks-cluster-arn` +and `kubernetes-namespace` tags all have the expected value. [source,json] ---- @@ -294,7 +294,7 @@ and `+kubernetes-namespace+` tags all have the expected value. ---- When using this strategy it is a best practice to ensure that the common -IAM role only has `+sts:AssumeRole+` permissions and no other AWS +IAM role only has `sts:AssumeRole` permissions and no other AWS access. It is important when using ABAC that you control who has the ability to @@ -302,7 +302,7 @@ tag IAM roles and users to only those who have a strict need to do so. Someone with the ability to tag an IAM role or user would be able to set tags on roles/users identical to what would be set by EKS Pod Identities and may be able to escalate their privileges. You can restrict who has -the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role +the access to set tags the `kubernetes-` and `eks-` tags on IAM role and users using IAM policy, or Service Control Policy (SCP). == De-centralized EKS Clusters @@ -397,7 +397,7 @@ the damage is limited to only the workloads that run on that cluster. All other workloads are unaffected |Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using -k8s native constructs like `+Namespaces+`. Workloads may share the +k8s native constructs like `Namespaces`. Workloads may share the underlying resources like CPU, memory, etc. AWS resources are isolated into their own workload accounts which by default are not accessible from other AWS accounts. |Stronger isolation on compute resources as the diff --git a/latest/bpg/security/multiaccount.adoc.backup b/latest/bpg/security/multiaccount.adoc.backup index 17b1064d0..c35c89629 100644 --- a/latest/bpg/security/multiaccount.adoc.backup +++ b/latest/bpg/security/multiaccount.adoc.backup @@ -61,7 +61,7 @@ account strategy: == Centralized EKS Cluster In this approach, your EKS Cluster will be deployed in a single AWS -account called the `+Cluster Account+`. Using +account called the `Cluster Account`. Using https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html[IAM roles for Service Accounts (IRSA)] or https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html[EKS @@ -80,11 +80,11 @@ link:/security/docs/multitenancy/[Best practices for tenant isolation] within an EKS cluster should still be followed when implementing a multi account strategy for multi tenant EKS clusters. -It is possible to have multiple `+Cluster Accounts+` in your AWS +It is possible to have multiple `Cluster Accounts` in your AWS organization, and it is a best practice to have multiple -`+Cluster Accounts+` that align with your software development lifecycle +`Cluster Accounts` that align with your software development lifecycle needs. For workloads operating at a very large scale, you may require -multiple `+Cluster Accounts+` to ensure that there are enough kubernetes +multiple `Cluster Accounts` to ensure that there are enough kubernetes and AWS service quotas available to all your workloads. [width="100%",cols="^100%",options="header",] @@ -196,7 +196,7 @@ Role chaining can be configured in an applications profile with their aws configuration file using the https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html[Process Credentials Provider] available in various AWS SDKs. -`+credential_process+` can be used as a credential source when +`credential_process` can be used as a credential source when configuring a profile, such as: [source,bash] @@ -267,8 +267,8 @@ another account with role chaining, you create a role trust policy statement that only allows a role to be assumed by a role session when the expected values are present. The following role trust policy will only let a role from the EKS cluster account (account ID 111122223333) -assume a role if the `+kubernetes-service-account+`, `+eks-cluster-arn+` -and `+kubernetes-namespace+` tags all have the expected value. +assume a role if the `kubernetes-service-account`, `eks-cluster-arn` +and `kubernetes-namespace` tags all have the expected value. [source,json] ---- @@ -294,7 +294,7 @@ and `+kubernetes-namespace+` tags all have the expected value. ---- When using this strategy it is a best practice to ensure that the common -IAM role only has `+sts:AssumeRole+` permissions and no other AWS +IAM role only has `sts:AssumeRole` permissions and no other AWS access. It is important when using ABAC that you control who has the ability to @@ -302,7 +302,7 @@ tag IAM roles and users to only those who have a strict need to do so. Someone with the ability to tag an IAM role or user would be able to set tags on roles/users identical to what would be set by EKS Pod Identities and may be able to escalate their privileges. You can restrict who has -the access to set tags the `+kubernetes-+` and `+eks-+` tags on IAM role +the access to set tags the `kubernetes-` and `eks-` tags on IAM role and users using IAM policy, or Service Control Policy (SCP). == De-centralized EKS Clusters @@ -397,7 +397,7 @@ the damage is limited to only the workloads that run on that cluster. All other workloads are unaffected |Isolation & Security: |Isolation/Soft Multi-tenancy is achieved using -k8s native constructs like `+Namespaces+`. Workloads may share the +k8s native constructs like `Namespaces`. Workloads may share the underlying resources like CPU, memory, etc. AWS resources are isolated into their own workload accounts which by default are not accessible from other AWS accounts. |Stronger isolation on compute resources as the diff --git a/latest/bpg/security/multitenancy.adoc b/latest/bpg/security/multitenancy.adoc index a586aeebb..6e8f77c7f 100644 --- a/latest/bpg/security/multitenancy.adoc +++ b/latest/bpg/security/multitenancy.adoc @@ -55,7 +55,7 @@ cluster. !!! warning With soft-multi-tenancy, tenants retain the ability to query CoreDNS for all services that run within the cluster by default. An -attacker could exploit this by running dig SRV `+*.*.svc.cluster.local+` +attacker could exploit this by running dig SRV `*.*.svc.cluster.local` from any pod in the cluster. If you need to restrict access to DNS records of services that run within your clusters, consider using the Firewall or Policy plugins for CoreDNS. For additional information, see @@ -295,10 +295,10 @@ affinity] is used to target nodes for scheduling, based on node https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/[labels]. With node affinity rules, the pods are attracted to specific nodes that match the selector terms. In the below pod specification, the -`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity is +`requiredDuringSchedulingIgnoredDuringExecution` node affinity is applied to the respective pod. The result is that the pod will target nodes that are labeled with the following key/value: -`+node-restriction.kubernetes.io/tenant: tenants-x+`. +`node-restriction.kubernetes.io/tenant: tenants-x`. [source,yaml] ---- @@ -321,13 +321,13 @@ not during execution; if the underlying nodes’ labels change, the pods will not be evicted due solely to that label change. However, future scheduling could be impacted. -!!! Warning The label prefix of `+node-restriction.kubernetes.io/+` has +!!! Warning The label prefix of `node-restriction.kubernetes.io/` has special meaning in Kubernetes. https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction[NodeRestriction] -which is enabled for EKS clusters prevents `+kubelet+` from +which is enabled for EKS clusters prevents `kubelet` from adding/removing/updating labels with this prefix. Attackers aren’t able -to use the `+kubelet+`’s credentials to update the node object or modify -the system setup to pass these labels into `+kubelet+` as `+kubelet+` +to use the `kubelet`’s credentials to update the node object or modify +the system setup to pass these labels into `kubelet` as `kubelet` isn’t allowed to modify these labels. If this prefix is used for all pod to node scheduling, it prevents scenarios where an attacker may want to attract a different set of workloads to a node by modifying the node @@ -351,7 +351,7 @@ unauthorized pods, Kubernetes uses node https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/[taints]. Taints are used to place conditions on nodes that prevent pods from being scheduled. The below taint uses a key-value pair of -`+tenant: tenants-x+`. +`tenant: tenants-x`. [source,yaml] ---- @@ -363,10 +363,10 @@ being scheduled. The below taint uses a key-value pair of ... ---- -Given the above node `+taint+`, only pods that _tolerate_ the taint will +Given the above node `taint`, only pods that _tolerate_ the taint will be allowed to be scheduled on the node. To allow authorized pods to be scheduled onto the node, the respective pod specifications must include -a `+toleration+` to the taint, as seen below. +a `toleration` to the taint, as seen below. [source,yaml] ---- @@ -379,7 +379,7 @@ a `+toleration+` to the taint, as seen below. ... ---- -Pods with the above `+toleration+` will not be stopped from scheduling +Pods with the above `toleration` will not be stopped from scheduling on the node, at least not because of that specific taint. Taints are also used by Kubernetes to temporarily stop pod scheduling during certain conditions, like node resource pressure. With node affinity, and @@ -449,8 +449,8 @@ spec: The above policy is applied to a Kubernetes API server request, to apply a pod to the _tenants-x_ namespace. The policy adds the -`+requiredDuringSchedulingIgnoredDuringExecution+` node affinity rule, -so that pods are attracted to nodes with the `+tenant: tenants-x+` +`requiredDuringSchedulingIgnoredDuringExecution` node affinity rule, +so that pods are attracted to nodes with the `tenant: tenants-x` label. A second policy, seen below, adds the toleration to the same pod @@ -484,7 +484,7 @@ spec: ---- The above policies are specific to pods; this is due to the paths to the -mutated elements in the policies’ `+location+` elements. Additional +mutated elements in the policies’ `location` elements. Additional policies could be written to handle resources that create pods, like Deployment and Job resources. The listed policies and other examples can been seen in the companion @@ -494,8 +494,8 @@ project] for this guide. The result of these two mutations is that pods are attracted to the desired node, while at the same time, not repelled by the specific node taint. To verify this, we can see the snippets of output from two -`+kubectl+` calls to get the nodes labeled with `+tenant=tenants-x+`, -and get the pods in the `+tenants-x+` namespace. +`kubectl` calls to get the nodes labeled with `tenant=tenants-x`, +and get the pods in the `tenants-x` namespace. [source,bash] ---- @@ -515,7 +515,7 @@ tenant-test-pod 1/1 Running 0 13s 10.0.35 ---- As we can see from the above outputs, all the pods are scheduled on the -nodes labeled with `+tenant=tenants-x+`. Simply put, the pods will only +nodes labeled with `tenant=tenants-x`. Simply put, the pods will only run on the desired nodes, and the other pods (without the required affinity and tolerations) will not. The tenant workloads are effectively isolated. diff --git a/latest/bpg/security/network.adoc b/latest/bpg/security/network.adoc index c51b35687..b8e267d69 100644 --- a/latest/bpg/security/network.adoc +++ b/latest/bpg/security/network.adoc @@ -58,8 +58,8 @@ evaluation does not affect the policy result. !!! attention When you first provision an EKS cluster, VPC CNI Network Policy functionality is not enabled by default. Ensure you deployed -supported VPC CNI Add-on version and set `+ENABLE_NETWORK_POLICY+` flag -to `+true+` on the vpc-cni add-on to enable this. Refer +supported VPC CNI Add-on version and set `ENABLE_NETWORK_POLICY` flag +to `true` on the vpc-cni add-on to enable this. Refer https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html[Amazon EKS User guide] for detailed instructions. @@ -132,7 +132,7 @@ image::./images/allow-dns-access.jpg[allow-dns-access] Understand the application requirements and create fine-grained ingress and egress rules as needed. Below example shows how to restrict ingress -traffic on port 80 to `+app-one+` from `+client-one+`. This helps +traffic on port 80 to `app-one` from `client-one`. This helps minimize the attack surface and reduces the risk of unauthorized access. [source,yaml] @@ -190,7 +190,7 @@ permissions. * *Ensure Network Policies exists using Open Policy Agent (OPA)* ** Use OPA Policy like shown below to ensure Network Policy always exists before onboarding application pods. This policy denies onboarding -k8s pods with a label `+k8s-app: sample-app+` if corresponding network +k8s pods with a label `k8s-app: sample-app` if corresponding network policy does not exist. ``` @@ -234,8 +234,8 @@ Policies. Amazon VPC CNI also ships an SDK that provides an interface to interact with eBPF programs on the node. The SDK is installed when the -`+aws-node+` is deployed onto the nodes. You can find the SDK binary -installed under `+/opt/cni/bin+` directory on the node. At launch, the +`aws-node` is deployed onto the nodes. You can find the SDK binary +installed under `/opt/cni/bin` directory on the node. At launch, the SDK provides support for fundamental functionalities such as inspecting eBPF programs and maps. @@ -295,9 +295,9 @@ groups for pods]. With security groups for pods, you can assign an to the creation of the pods, the pods will not get scheduled. You can control which pods are assigned to a security group by creating -a `+SecurityGroupPolicy+` object and specifying a `+PodSelector+` or a -`+ServiceAccountSelector+`. Setting the selectors to `+{}+` will assign -the SGs referenced in the `+SecurityGroupPolicy+` to all pods in a +a `SecurityGroupPolicy` object and specifying a `PodSelector` or a +`ServiceAccountSelector`. Setting the selectors to `{}` will assign +the SGs referenced in the `SecurityGroupPolicy` to all pods in a namespace or all Service Accounts in a namespace. Be sure you’ve familiarized yourself with all the https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations[considerations] @@ -362,10 +362,10 @@ with other AWS services (RDS database), use SGPs as an efficient mechanism to control the traffic from the pods to AWS services. * *Isolation of Pod & Node traffic* ** If you want to completely separate pod traffic from the rest of the -node traffic, use SGP in `+POD_SECURITY_GROUP_ENFORCING_MODE=strict+` +node traffic, use SGP in `POD_SECURITY_GROUP_ENFORCING_MODE=strict` mode. -=== Best practices using `+Security groups for pods+` and `+Network Policy+` +=== Best practices using `Security groups for pods` and `Network Policy` * *Layered security* ** Use a combination of SGP and kubernetes network policy for a layered @@ -387,7 +387,7 @@ misconfiguration and ease the management overhead applications !!! attention Security Groups for pods provides two enforcing modes: -`+strict+` and `+standard+`. You must use `+standard+` mode when using +`strict` and `standard`. You must use `standard` mode when using both Network Policy and Security Groups for pods features in an EKS cluster. @@ -398,7 +398,7 @@ applications running in EKS. == Service Mesh Policy Enforcement or Kubernetes network policy -A `+service mesh+` is a dedicated infrastructure layer that you can add +A `service mesh` is a dedicated infrastructure layer that you can add to your applications. It allows you to transparently add capabilities like observability, traffic management, and security, without adding them to your own code. @@ -597,14 +597,14 @@ https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction Application Load Balancer] (ALB) and https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html[Network Load Balancer] (NLB) both have support for transport encryption (SSL and -TLS). The `+alb.ingress.kubernetes.io/certificate-arn+` annotation for +TLS). The `alb.ingress.kubernetes.io/certificate-arn` annotation for the ALB lets you to specify which certificates to add to the ALB. If you omit the annotation the controller will attempt to add certificates to listeners that require it by matching the available https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html[AWS Certificate Manager (ACM)] certificates using the host field. Starting with EKS v1.15 you can use the -`+service.beta.kubernetes.io/aws-load-balancer-ssl-cert+` annotation +`service.beta.kubernetes.io/aws-load-balancer-ssl-cert` annotation with the NLB as shown in the example below. [source,yaml] @@ -713,7 +713,7 @@ certificates from ACM Private CA. Now that you have a Private CA and an EKS cluster with cert-manager and the plugin installed, it’s time to set permissions and create the issuer. Update IAM permissions of the EKS node role to allow access to -ACM Private CA. Replace the `++` with the value from your +ACM Private CA. Replace the `` with the value from your Private CA: [source,json] @@ -741,7 +741,7 @@ Additional Resources section below for complete examples. Create an Issuer in Amazon EKS by creating a Custom Resource Definition file named cluster-issuer.yaml with the following text in it, replacing -`++` and `++` information with your Private CA. +`` and `` information with your Private CA. [source,yaml] ---- @@ -762,8 +762,8 @@ kubectl apply -f cluster-issuer.yaml ---- Your EKS cluster is configured to request certificates from Private CA. -You can now use cert-manager’s `+Certificate+` resource to issue -certificates by changing the `+issuerRef+` field’s values to the Private +You can now use cert-manager’s `Certificate` resource to issue +certificates by changing the `issuerRef` field’s values to the Private CA Issuer you created above. For more details on how to specify and request Certificate resources, please check cert-manager’s https://cert-manager.io/docs/usage/certificate/[Certificate Resources @@ -774,7 +774,7 @@ examples here]. === ACM Private CA with Istio and cert-manager If you are running Istio in your EKS cluster, you can disable the Istio -control plane (specifically `+istiod+`) from functioning as the root +control plane (specifically `istiod`) from functioning as the root Certificate Authority (CA), and configure ACM Private CA as the root CA for mTLS between workloads. If you’re going with this approach, consider using the _short-lived CA mode_ in ACM Private CA. Refer to the @@ -796,11 +796,11 @@ with its envoy sidecar proxy, it needs an identity assigned from Istio in order for it to be deemed as trustworthy and allowed to communicate with other services in the mesh. -To get this identity from Istio, the `+istio-agent+` sends a request +To get this identity from Istio, the `istio-agent` sends a request known as a certificate signing request (or CSR) to the Istio control plane. This CSR contains the service account token so that the workload’s identity can be verified before being processed. This -verification process is handled by `+istiod+`, which acts as both the +verification process is handled by `istiod`, which acts as both the Registration Authority (or RA) and the CA. The RA serves as a gatekeeper that makes sure only verified CSR makes it through to the CA. Once the CSR is verified, it will be forwarded to the CA which will then issue a @@ -851,14 +851,14 @@ section] to complete the following: . Install cert-manager . Install the issuer plugin . Set permissions and create an issuer. The issuer represents the CA and -is used to sign `+istiod+` and mesh workload certificates. It will +is used to sign `istiod` and mesh workload certificates. It will communicate with ACM Private CA. -. Create an `+istio-system+` namespace. This is where the -`+istiod certificate+` and other Istio resources will be deployed. +. Create an `istio-system` namespace. This is where the +`istiod certificate` and other Istio resources will be deployed. . Install Istio CSR configured with AWS Private CA Issuer Plugin. You can preserve the certificate signing requests for workloads to verify that they get approved and signed -(`+preserveCertificateRequests=true+`). +(`preserveCertificateRequests=true`). + [source,bash] ---- @@ -876,8 +876,8 @@ helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio- --set "volumes[0].name=root-ca" \ --set "volumes[0].secret.secretName=istio-root-ca" ---- -. Install Istio with custom configurations to replace `+istiod+` with -`+cert-manager istio-csr+` as the certificate provider for the mesh. +. Install Istio with custom configurations to replace `istiod` with +`cert-manager istio-csr` as the certificate provider for the mesh. This process can be carried out using the https://tetrate.io/blog/what-is-istio-operator/[Istio Operator]. + diff --git a/latest/bpg/security/runtime.adoc b/latest/bpg/security/runtime.adoc index a1c7c4163..bcd1a909d 100644 --- a/latest/bpg/security/runtime.adoc +++ b/latest/bpg/security/runtime.adoc @@ -31,8 +31,8 @@ automate provisioning of profiles onto nodes. Many Linux runtime security mechanisms are tightly integrated with Kubernetes and can be configured through Kubernetes https://kubernetes.io/docs/tasks/configure-pod-container/security-context/[security -contexts]. One such option is the `+privileged+` flag, which is -`+false+` by default and if enabled is essentially equivalent to root on +contexts]. One such option is the `privileged` flag, which is +`false` by default and if enabled is essentially equivalent to root on the host. It is nearly always inappropriate to enable privileged mode in production workloads, but there are many more controls that can provide more granular privileges to containers as appropriate. @@ -41,8 +41,8 @@ more granular privileges to containers as appropriate. Linux capabilities allow you to grant certain capabilities to a Pod or container without providing all the abilities of the root user. Examples -include `+CAP_NET_ADMIN+`, which allows configuring network interfaces -or firewalls, or `+CAP_SYS_TIME+`, which allows manipulation of the +include `CAP_NET_ADMIN`, which allows configuring network interfaces +or firewalls, or `CAP_SYS_TIME`, which allows manipulation of the system clock. === Seccomp @@ -62,7 +62,7 @@ seccomp profile which is suitable for a majority of general purpose workloads, and other container runtimes like containerd provide comparable defaults. You can configure your container or Pod to use the container runtime’s default seccomp profile by adding the following to -the `+securityContext+` section of the Pod spec: +the `securityContext` section of the Pod spec: [source,yaml] ---- @@ -71,11 +71,11 @@ securityContext: type: RuntimeDefault ---- -As of 1.22 (in alpha, stable as of 1.27), the above `+RuntimeDefault+` +As of 1.22 (in alpha, stable as of 1.27), the above `RuntimeDefault` can be used for all Pods on a Node using a https://kubernetes.io/docs/tutorials/security/seccomp/#enable-the-use-of-runtimedefault-as-the-default-seccomp-profile-for-all-workloads[single -kubelet flag], `+--seccomp-default+`. Then the profile specified in -`+securityContext+` is only needed for other profiles. +kubelet flag], `--seccomp-default`. Then the profile specified in +`securityContext` is only needed for other profiles. It’s also possible to create your own profiles for things that require additional privileges. This can be very tedious to do manually, but diff --git a/latest/bpg/security/test.py b/latest/bpg/security/test.py index 79213f6f5..5e37e8bd7 100644 --- a/latest/bpg/security/test.py +++ b/latest/bpg/security/test.py @@ -128,7 +128,7 @@ def suggest_fixes(section: Section) -> List[str]: if re.search(r'[^=]=+[^=]', section.content): suggestions.append("Check for misplaced section headers or formatting issues with '=' characters") - if re.search(r'[^`]`[^`]+`[^`]', section.content): + if re.search(r'[^`]`[^`]`[^`]', section.content): suggestions.append("Ensure all inline code blocks use matching backticks") if re.search(r'\{[^}]+\}', section.content): From 1496ae6f4a2fa97c5c715ace6d1912a1568d7c69 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Tue, 27 Aug 2024 21:35:29 -0500 Subject: [PATCH 28/56] fixup --- latest/bpg/scalability/cluster-services.adoc | 96 + latest/bpg/scalability/control-plane.adoc | 301 ++ latest/bpg/scalability/data-plane.adoc | 215 ++ latest/bpg/scalability/images/APF.jpg | Bin 0 -> 262223 bytes .../bpg/scalability/images/PLEG-duration.png | Bin 0 -> 39119 bytes .../images/api-request-duration.png | Bin 0 -> 35993 bytes .../bpg/scalability/images/bad-sweetspot.png | Bin 0 -> 32641 bytes latest/bpg/scalability/images/bottlenecks.png | Bin 0 -> 30923 bytes latest/bpg/scalability/images/churn-rate.png | Bin 0 -> 34724 bytes latest/bpg/scalability/images/cores-1.png | Bin 0 -> 13448 bytes latest/bpg/scalability/images/cores-2.png | Bin 0 -> 15976 bytes latest/bpg/scalability/images/cores-3.png | Bin 0 -> 17067 bytes latest/bpg/scalability/images/cpu-1.png | Bin 0 -> 63481 bytes latest/bpg/scalability/images/cpu-2.png | Bin 0 -> 65609 bytes latest/bpg/scalability/images/cpu-limits.png | Bin 0 -> 21976 bytes latest/bpg/scalability/images/cwl-query.png | Bin 0 -> 121646 bytes latest/bpg/scalability/images/defrag.png | Bin 0 -> 242544 bytes latest/bpg/scalability/images/etcd-duress.png | Bin 0 -> 160258 bytes latest/bpg/scalability/images/flow-addons.png | Bin 0 -> 16585 bytes latest/bpg/scalability/images/flow.png | Bin 0 -> 13164 bytes .../scalability/images/hpa-utilization.png | Bin 0 -> 22953 bytes .../scalability/images/inflight-requests.png | Bin 0 -> 282344 bytes .../bpg/scalability/images/k8s-components.png | Bin 0 -> 16585 bytes latest/bpg/scalability/images/keeping-up.png | Bin 0 -> 14536 bytes .../scalability/images/node-saturation.png | Bin 0 -> 16438 bytes latest/bpg/scalability/images/node-size.png | Bin 0 -> 43566 bytes .../bpg/scalability/images/query-results.png | Bin 0 -> 63203 bytes latest/bpg/scalability/images/queues.png | Bin 0 -> 45213 bytes latest/bpg/scalability/images/requests-1.png | Bin 0 -> 17109 bytes latest/bpg/scalability/images/requests-2.png | Bin 0 -> 18037 bytes .../scalability/images/requests-in-use.png | Bin 0 -> 94619 bytes .../bpg/scalability/images/scaling-ratio.png | Bin 0 -> 45982 bytes .../scalability/images/shared-concurrency.png | Bin 0 -> 61794 bytes .../scalability/images/slowest-requests.png | Bin 0 -> 100313 bytes .../bpg/scalability/images/smooth-scaling.png | Bin 0 -> 25399 bytes .../bpg/scalability/images/spiky-scaling.png | Bin 0 -> 31759 bytes latest/bpg/scalability/images/stalled-io.png | Bin 0 -> 189674 bytes latest/bpg/scalability/images/sweet-spot.png | Bin 0 -> 16981 bytes latest/bpg/scalability/images/thread-pool.png | Bin 0 -> 35529 bytes .../images/util-vs-saturation-1.png | Bin 0 -> 25565 bytes .../images/util-vs-saturation-2.png | Bin 0 -> 34826 bytes latest/bpg/scalability/index.adoc | 51 + latest/bpg/scalability/index.html | 3073 +++++++++++++++++ latest/bpg/scalability/kcp_monitoring.adoc | 251 ++ latest/bpg/scalability/kubernetes_slos.adoc | 157 + latest/bpg/scalability/node_efficiency.adoc | 266 ++ latest/bpg/scalability/quotas.adoc | 247 ++ latest/bpg/scalability/scaling_theory.adoc | 102 + latest/bpg/scalability/workloads.adoc | 99 + latest/bpg/security/hosts.adoc | 268 +- latest/bpg/security/index.adoc | 2 +- 51 files changed, 4993 insertions(+), 135 deletions(-) create mode 100644 latest/bpg/scalability/cluster-services.adoc create mode 100644 latest/bpg/scalability/control-plane.adoc create mode 100644 latest/bpg/scalability/data-plane.adoc create mode 100644 latest/bpg/scalability/images/APF.jpg create mode 100644 latest/bpg/scalability/images/PLEG-duration.png create mode 100644 latest/bpg/scalability/images/api-request-duration.png create mode 100644 latest/bpg/scalability/images/bad-sweetspot.png create mode 100644 latest/bpg/scalability/images/bottlenecks.png create mode 100644 latest/bpg/scalability/images/churn-rate.png create mode 100644 latest/bpg/scalability/images/cores-1.png create mode 100644 latest/bpg/scalability/images/cores-2.png create mode 100644 latest/bpg/scalability/images/cores-3.png create mode 100644 latest/bpg/scalability/images/cpu-1.png create mode 100644 latest/bpg/scalability/images/cpu-2.png create mode 100644 latest/bpg/scalability/images/cpu-limits.png create mode 100644 latest/bpg/scalability/images/cwl-query.png create mode 100644 latest/bpg/scalability/images/defrag.png create mode 100644 latest/bpg/scalability/images/etcd-duress.png create mode 100644 latest/bpg/scalability/images/flow-addons.png create mode 100644 latest/bpg/scalability/images/flow.png create mode 100644 latest/bpg/scalability/images/hpa-utilization.png create mode 100644 latest/bpg/scalability/images/inflight-requests.png create mode 100644 latest/bpg/scalability/images/k8s-components.png create mode 100644 latest/bpg/scalability/images/keeping-up.png create mode 100644 latest/bpg/scalability/images/node-saturation.png create mode 100644 latest/bpg/scalability/images/node-size.png create mode 100644 latest/bpg/scalability/images/query-results.png create mode 100644 latest/bpg/scalability/images/queues.png create mode 100644 latest/bpg/scalability/images/requests-1.png create mode 100644 latest/bpg/scalability/images/requests-2.png create mode 100644 latest/bpg/scalability/images/requests-in-use.png create mode 100644 latest/bpg/scalability/images/scaling-ratio.png create mode 100644 latest/bpg/scalability/images/shared-concurrency.png create mode 100644 latest/bpg/scalability/images/slowest-requests.png create mode 100644 latest/bpg/scalability/images/smooth-scaling.png create mode 100644 latest/bpg/scalability/images/spiky-scaling.png create mode 100644 latest/bpg/scalability/images/stalled-io.png create mode 100644 latest/bpg/scalability/images/sweet-spot.png create mode 100644 latest/bpg/scalability/images/thread-pool.png create mode 100644 latest/bpg/scalability/images/util-vs-saturation-1.png create mode 100644 latest/bpg/scalability/images/util-vs-saturation-2.png create mode 100644 latest/bpg/scalability/index.adoc create mode 100644 latest/bpg/scalability/index.html create mode 100644 latest/bpg/scalability/kcp_monitoring.adoc create mode 100644 latest/bpg/scalability/kubernetes_slos.adoc create mode 100644 latest/bpg/scalability/node_efficiency.adoc create mode 100644 latest/bpg/scalability/quotas.adoc create mode 100644 latest/bpg/scalability/scaling_theory.adoc create mode 100644 latest/bpg/scalability/workloads.adoc diff --git a/latest/bpg/scalability/cluster-services.adoc b/latest/bpg/scalability/cluster-services.adoc new file mode 100644 index 000000000..d6ed1a2ed --- /dev/null +++ b/latest/bpg/scalability/cluster-services.adoc @@ -0,0 +1,96 @@ += Cluster Services + +Cluster services run inside an EKS cluster, but they are not user workloads. If you have a Linux server you often need to run services like NTP, syslog, and a container runtime to support your workloads. Cluster services are similar, supporting services that help you automate and operate your cluster. In Kubernetes these are usually run in the kube-system namespace and some are run as https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[DaemonSets]. + +Cluster services are expected to have a high up-time and are often critical during outages and for troubleshooting. If a core cluster service is not available you may lose access to data that can help recover or prevent an outage (e.g. high disk utilization). They should run on dedicated compute instances such as a separate node group or AWS Fargate. This will ensure that the cluster services are not impacted on shared instances by workloads that may be scaling up or using more resources. + +== Scale CoreDNS + +Scaling CoreDNS has two primary mechanisms. Reducing the number of calls to the CoreDNS service and increasing the number of replicas. + +=== Reduce external queries by lowering ndots + +The ndots setting specifies how many periods (a.k.a. "dots") in a domain name are considered enough to avoid querying DNS. If your application has an ndots setting of 5 (default) and you request resources from an external domain such as api.example.com (2 dots) then CoreDNS will be queried for each search domain defined in /etc/resolv.conf for a more specific domain. By default the following domains will be searched before making an external request. + +---- +api.example..svc.cluster.local +api.example.svc.cluster.local +api.example.cluster.local +api.example..compute.internal +---- + +The `namespace` and `region` values will be replaced with your workloads namespace and your compute region. You may have additional search domains based on your cluster settings. + +You can reduce the number of requests to CoreDNS by https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-dns-config[lowering the ndots option] of your workload or fully qualifying your domain requests by including a trailing . (e.g. `api.example.com.` ). If your workload connects to external services via DNS we recommend setting ndots to 2 so workloads do not make unnecessary, cluster DNS queries inside the cluster. You can set a different DNS server and search domain if the workload doesn't require access to services inside the cluster. + +---- +spec: + dnsPolicy: "None" + dnsConfig: + options: + - name: ndots + value: "2" + - name: edns0 +---- + +If you lower ndots to a value that is too low or the domains you are connecting to do not include enough specificity (including trailing .) then it is possible DNS lookups will fail. Make sure you test how this setting will impact your workloads. + +=== Scale CoreDNS Horizontally + +CoreDNS instances can scale by adding additional replicas to the deployment. It's recommended you use https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/[NodeLocal DNS] or the https://github.com/kubernetes-sigs/cluster-proportional-autoscaler[cluster proportional autoscaler] to scale CoreDNS. + +NodeLocal DNS will require run one instance per node--as a DaemonSet--which requires more compute resources in the cluster, but it will avoid failed DNS requests and decrease the response time for DNS queries in the cluster. The cluster proportional autoscaler will scale CoreDNS based on the number of nodes or cores in the cluster. This isn't a direct correlation to request queries, but can be useful depending on your workloads and cluster size. The default proportional scale is to add an additional replica for every 256 cores or 16 nodes in the cluster--whichever happens first. + +== Scale Kubernetes Metrics Server Vertically + +The Kubernetes Metrics Server supports horizontal and vertical scaling. By horizontally scaling the Metrics Server it will be highly available, but it will not scale horizontally to handle more cluster metrics. You will need to vertically scale the Metrics Server based on https://kubernetes-sigs.github.io/metrics-server/#scaling[their recommendations] as nodes and collected metrics are added to the cluster. + +The Metrics Server keeps the data it collects, aggregates, and serves in memory. As a cluster grows, the amount of data the Metrics Server stores increases. In large clusters the Metrics Server will require more compute resources than the memory and CPU reservation specified in the default installation. You can use the https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler[Vertical Pod Autoscaler] (VPA) or https://github.com/kubernetes/autoscaler/tree/master/addon-resizer[Addon Resizer] to scale the Metrics Server. The Addon Resizer scales vertically in proportion to worker nodes and VPA scales based on CPU and memory usage. + +== CoreDNS lameduck duration + +Pods use the `kube-dns` Service for name resolution. Kubernetes uses destination NAT (DNAT) to redirect `kube-dns` traffic from nodes to CoreDNS backend pods. As you scale the CoreDNS Deployment, `kube-proxy` updates iptables rules and chains on nodes to redirect DNS traffic to CoreDNS pods. Propagating new endpoints when you scale up and deleting rules when you scale down CoreDNS can take between 1 to 10 seconds depending on the size of the cluster. + +This propagation delay can cause DNS lookup failures when a CoreDNS pod gets terminated yet the node's iptables rules haven't been updated. In this scenario, the node may continue to send DNS queries to a terminated CoreDNS Pod. + +You can reduce DNS lookup failures by setting a https://coredns.io/plugins/health/[lameduck] duration in your CoreDNS pods. While in lameduck mode, CoreDNS will continue to respond to in-flight requests. Setting a lameduck duration will delay the CoreDNS shutdown process, allowing nodes the time they need to update their iptables rules and chains. + +We recommend setting CoreDNS lameduck duration to 30 seconds. + +== CoreDNS readiness probe + +We recommend using `/ready` instead of `/health` for CoreDNS's readiness probe. + +In alignment with the earlier recommendation to set the lameduck duration to 30 seconds, providing ample time for the node's iptables rules to be updated before pod termination, employing `/ready` instead of `/health` for the CoreDNS readiness probe ensures that the CoreDNS pod is fully prepared at startup to promptly respond to DNS requests. + +[,yaml] +---- +readinessProbe: + httpGet: + path: /ready + port: 8181 + scheme: HTTP +---- + +For more information about the CoreDNS Ready plugin please refer to https://coredns.io/plugins/ready/ + +== Logging and monitoring agents + +Logging and monitoring agents can add significant load to your cluster control plane because the agents query the API server to enrich logs and metrics with workload metadata. The agent on a node only has access to the local node resources to see things like container and process name. Querying the API server it can add more details such as Kubernetes deployment name and labels. This can be extremely helpful for troubleshooting but detrimental to scaling. + +Because there are so many different options for logging and monitoring we cannot show examples for every provider. With https://docs.fluentbit.io/manual/pipeline/filters/kubernetes[fluentbit] we recommend enabling Use_Kubelet to fetch metadata from the local kubelet instead of the Kubernetes API Server and set `Kube_Meta_Cache_TTL` to a number that reduces repeated calls when data can be cached (e.g. 60). + +Scaling monitoring and logging has two general options: + +* Disable integrations +* Sampling and filtering + +Disabling integrations is often not an option because you lose log metadata. This eliminates the API scaling problem, but it will introduce other issues by not having the required metadata when needed. + +Sampling and filtering reduces the number of metrics and logs that are collected. This will lower the amount of requests to the Kubernetes API, and it will reduce the amount of storage needed for the metrics and logs that are collected. Reducing the storage costs will lower the cost for the overall system. + +The ability to configure sampling depends on the agent software and can be implemented at different points of ingestion. It's important to add sampling as close to the agent as possible because that is likely where the API server calls happen. Contact your provider to find out more about sampling support. + +If you are using CloudWatch and CloudWatch Logs you can add agent filtering using patterns https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html[described in the documentation]. + +To avoid losing logs and metrics you should send your data to a system that can buffer data in case of an outage on the receiving endpoint. With fluentbit you can use https://docs.fluentbit.io/manual/pipeline/outputs/firehose[Amazon Kinesis Data Firehose] to temporarily keep data which can reduce the chance of overloading your final data storage location. diff --git a/latest/bpg/scalability/control-plane.adoc b/latest/bpg/scalability/control-plane.adoc new file mode 100644 index 000000000..1256b93bb --- /dev/null +++ b/latest/bpg/scalability/control-plane.adoc @@ -0,0 +1,301 @@ += Kubernetes Control Plane + +The Kubernetes control plane consists of the Kubernetes API Server, Kubernetes Controller Manager, Scheduler and other components that are required for Kubernetes to function. Scalability limits of these components are different depending on what you're running in the cluster, but the areas with the biggest impact to scaling include the Kubernetes version, utilization, and individual Node scaling. + +== Use EKS 1.24 or above + +EKS 1.24 introduced a number of changes and switches the container runtime to https://containerd.io/[containerd] instead of docker. Containerd helps clusters scale by increasing individual node performance by limiting container runtime features to closely align with Kubernetes`' needs. Containerd is available in every supported version of EKS and if you would like to switch to containerd in versions prior to 1.24 please use the https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html#containerd-bootstrap[`--container-runtime` bootstrap flag]. + +== Limit workload and node bursting + +!!! Attention + To avoid reaching API limits on the control plane you should limit scaling spikes that increase cluster size by double digit percentages at a time (e.g. 1000 nodes to 1100 nodes or 4000 to 4500 pods at once). + +The EKS control plane will automatically scale as your cluster grows, but there are limits on how fast it will scale. When you first create an EKS cluster the Control Plane will not immediately be able to scale to hundreds of nodes or thousands of pods. To read more about how EKS has made scaling improvements see https://aws.amazon.com/blogs/containers/amazon-eks-control-plane-auto-scaling-enhancements-improve-speed-by-4x/[this blog post]. + +Scaling large applications requires infrastructure to adapt to become fully ready (e.g. warming load balancers). To control the speed of scaling make sure you are scaling based on the right metrics for your application. CPU and memory scaling may not accurately predict your application constraints and using custom metrics (e.g. requests per second) in Kubernetes Horizontal Pod Autoscaler (HPA) may be a better scaling option. + +To use a custom metric see the examples in the https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics[Kubernetes documentation]. If you have more advanced scaling needs or need to scale based on external sources (e.g. AWS SQS queue) then use https://keda.sh[KEDA] for event based workload scaling. + +== Scale nodes and pods down safely + +=== Replace long running instances + +Replacing nodes regularly keeps your cluster healthy by avoiding configuration drift and issues that only happen after extended uptime (e.g. slow memory leaks). Automated replacement will give you good process and practices for node upgrades and security patching. If every node in your cluster is replaced regularly then there is less toil required to maintain separate processes for ongoing maintenance. + +Use Karpenter's https://aws.github.io/aws-eks-best-practices/karpenter/#use-timers-ttl-to-automatically-delete-nodes-from-the-cluster[time to live (TTL)] settings to replace instances after they've been running for a specified amount of time. Self managed node groups can use the `max-instance-lifetime` setting to cycle nodes automatically. Managed node groups do not currently have this feature but you can track the request https://github.com/aws/containers-roadmap/issues/1190[here on GitHub]. + +=== Remove underutilized nodes + +You can remove nodes when they have no running workloads using the scale down threshold in the Kubernetes Cluster Autoscaler with the https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-does-scale-down-work[`--scale-down-utilization-threshold`] or in Karpenter you can use the `ttlSecondsAfterEmpty` provisioner setting. + +=== Use pod disruption budgets and safe node shutdown + +Removing pods and nodes from a Kubernetes cluster requires controllers to make updates to multiple resources (e.g. EndpointSlices). Doing this frequently or too quickly can cause API server throttling and application outages as changes propogate to controllers. https://kubernetes.io/docs/concepts/workloads/pods/disruptions/[Pod Disruption Budgets] are a best practice to slow down churn to protect workload availability as nodes are removed or rescheduled in a cluster. + +== Use Client-Side Cache when running Kubectl + +Using the kubectl command inefficiently can add additional load to the Kubernetes API Server. You should avoid running scripts or automation that uses kubectl repeatedly (e.g. in a for loop) or running commands without a local cache. + +`kubectl` has a client-side cache that caches discovery information from the cluster to reduce the amount of API calls required. The cache is enabled by default and is refreshed every 10 minutes. + +If you run kubectl from a container or without a client-side cache you may run into API throttling issues. It is recommended to retain your cluster cache by mounting the `--cache-dir` to avoid making uncessesary API calls. + +== Disable kubectl Compression + +Disabling kubectl compression in your kubeconfig file can reduce API and client CPU usage. By default the server will compress data sent to the client to optimize network bandwidth. This adds CPU load on the client and server for every request and disabling compression can reduce the overhead and latency if you have adequate bandwidth. To disable compression you can use the `--disable-compression=true` flag or set `disable-compression: true` in your kubeconfig file. + +---- +apiVersion: v1 +clusters: +- cluster: + server: serverURL + disable-compression: true + name: cluster +---- + +== Shard Cluster Autoscaler + +The https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/proposals/scalability_tests.md[Kubernetes Cluster Autoscaler has been tested] to scale up to 1000 nodes. On a large cluster with more than 1000 nodes, it is recommended to run multiple instances of the Cluster Autoscaler in shard mode. Each Cluster Autoscaler instance is configured to scale a set of node groups. The following example shows 2 cluster autoscaling configurations that are configured to each scale 4 node groups. + +ClusterAutoscaler-1 + +---- +autoscalingGroups: +- name: eks-core-node-grp-20220823190924690000000011-80c1660e-030d-476d-cb0d-d04d585a8fcb + maxSize: 50 + minSize: 2 +- name: eks-data_m1-20220824130553925600000011-5ec167fa-ca93-8ca4-53a5-003e1ed8d306 + maxSize: 450 + minSize: 2 +- name: eks-data_m2-20220824130733258600000015-aac167fb-8bf7-429d-d032-e195af4e25f5 + maxSize: 450 + minSize: 2 +- name: eks-data_m3-20220824130553914900000003-18c167fa-ca7f-23c9-0fea-f9edefbda002 + maxSize: 450 + minSize: 2 +---- + +ClusterAutoscaler-2 + +---- +autoscalingGroups: +- name: eks-data_m4-2022082413055392550000000f-5ec167fa-ca86-6b83-ae9d-1e07ade3e7c4 + maxSize: 450 + minSize: 2 +- name: eks-data_m5-20220824130744542100000017-02c167fb-a1f7-3d9e-a583-43b4975c050c + maxSize: 450 + minSize: 2 +- name: eks-data_m6-2022082413055392430000000d-9cc167fa-ca94-132a-04ad-e43166cef41f + maxSize: 450 + minSize: 2 +- name: eks-data_m7-20220824130553921000000009-96c167fa-ca91-d767-0427-91c879ddf5af + maxSize: 450 + minSize: 2 +---- + +== API Priority and Fairness + +image::../images/APF.jpg[] + +=== Overview++++++ + +To protect itself from being overloaded during periods of increased requests, the API Server limits the number of inflight requests it can have outstanding at a given time. Once this limit is exceeded, the API Server will start rejecting requests and return a 429 HTTP response code for "Too Many Requests" back to clients. The server dropping requests and having clients try again later is preferable to having no server-side limits on the number of requests and overloading the control plane, which could result in degraded performance or unavailability. + +The mechanism used by Kubernetes to configure how these inflights requests are divided among different request types is called https://kubernetes.io/docs/concepts/cluster-administration/flow-control/[API Priority and Fairness]. The API Server configures the total number of inflight requests it can accept by summing together the values specified by the `--max-requests-inflight` and `--max-mutating-requests-inflight` flags. EKS uses the default values of 400 and 200 requests for these flags, allowing a total of 600 requests to be dispatched at a given time. However, as it scales the control-plane to larger sizes in response to increased utilization and workload churn, it correspondingly increases the inflight request quota all the way till 2000 (subject to change). APF specifies how these inflight request quota is further sub-divided among different request types. Note that EKS control planes are highly available with at least 2 API Servers registered to each cluster. This means the total number of inflight requests your cluster can handle is twice (or higher if horizontally scaled out further) the inflight quota set per kube-apiserver. This amounts to several thousands of requests/second on the largest EKS clusters. + +Two kinds of Kubernetes objects, called PriorityLevelConfigurations and FlowSchemas, configure how the total number of requests is divided between different request types. These objects are maintained by the API Server automatically and EKS uses the default configuration of these objects for the given Kubernetes minor version. PriorityLevelConfigurations represent a fraction of the total number of allowed requests. For example, the workload-high PriorityLevelConfiguration is allocated 98 out of the total of 600 requests. The sum of requests allocated to all PriorityLevelConfigurations will equal 600 (or slightly above 600 because the API Server will round up if a given level is granted a fraction of a request). To check the PriorityLevelConfigurations in your cluster and the number of requests allocated to each, you can run the following command. These are the defaults on EKS 1.24: + + $ kubectl get --raw /metrics | grep apiserver_flowcontrol_request_concurrency_limit + apiserver_flowcontrol_request_concurrency_limit{priority_level="catch-all"} 13 + apiserver_flowcontrol_request_concurrency_limit{priority_level="global-default"} 49 + apiserver_flowcontrol_request_concurrency_limit{priority_level="leader-election"} 25 + apiserver_flowcontrol_request_concurrency_limit{priority_level="node-high"} 98 + apiserver_flowcontrol_request_concurrency_limit{priority_level="system"} 74 + apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-high"} 98 + apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245 + +The second type of object are FlowSchemas. API Server requests with a given set of properties are classified under the same FlowSchema. These properties include either the authenticated user or attributes of the request, such as the API group, namespace, or resource. A FlowSchema also specifies which PriorityLevelConfiguration this type of request should map to. The two objects together say, "I want this type of request to count towards this share of inflight requests." When a request hits the API Server, it will check each of its FlowSchemas until it finds one that matches all the required properties. If multiple FlowSchemas match a request, the API Server will choose the FlowSchema with the smallest matching precedence which is specified as a property in the object. + +The mapping of FlowSchemas to PriorityLevelConfigurations can be viewed using this command: + + $ kubectl get flowschemas + NAME PRIORITYLEVEL MATCHINGPRECEDENCE DISTINGUISHERMETHOD AGE MISSINGPL + exempt exempt 1 7h19m False + eks-exempt exempt 2 7h19m False + probes exempt 2 7h19m False + system-leader-election leader-election 100 ByUser 7h19m False + endpoint-controller workload-high 150 ByUser 7h19m False + workload-leader-election leader-election 200 ByUser 7h19m False + system-node-high node-high 400 ByUser 7h19m False + system-nodes system 500 ByUser 7h19m False + kube-controller-manager workload-high 800 ByNamespace 7h19m False + kube-scheduler workload-high 800 ByNamespace 7h19m False + kube-system-service-accounts workload-high 900 ByNamespace 7h19m False + eks-workload-high workload-high 1000 ByUser 7h14m False + service-accounts workload-low 9000 ByUser 7h19m False + global-default global-default 9900 ByUser 7h19m False + catch-all catch-all 10000 ByUser 7h19m False + +PriorityLevelConfigurations can have a type of Queue, Reject, or Exempt. For types Queue and Reject, a limit is enforced on the maximum number of inflight requests for that priority level, however, the behavior differs when that limit is reached. For example, the workload-high PriorityLevelConfiguration uses type Queue and has 98 requests available for use by the controller-manager, endpoint-controller, scheduler,eks related controllers and from pods running in the kube-system namespace. Since type Queue is used, the API Server will attempt to keep requests in memory and hope that the number of inflight requests drops below 98 before these requests time out. If a given request times out in the queue or if too many requests are already queued, the API Server has no choice but to drop the request and return the client a 429. Note that queuing may prevent a request from receiving a 429, but it comes with the tradeoff of increased end-to-end latency on the request. + +Now consider the catch-all FlowSchema that maps to the catch-all PriorityLevelConfiguration with type Reject. If clients reach the limit of 13 inflight requests, the API Server will not exercise queuing and will drop the requests instantly with a 429 response code. Finally, requests mapping to a PriorityLevelConfiguration with type Exempt will never receive a 429 and always be dispatched immediately. This is used for high-priority requests such as healthz requests or requests coming from the system:masters group. + +=== Monitoring APF and Dropped Requests + +To confirm if any requests are being dropped due to APF, the API Server metrics for `apiserver_flowcontrol_rejected_requests_total` can be monitored to check the impacted FlowSchemas and PriorityLevelConfigurations. For example, this metric shows that 100 requests from the service-accounts FlowSchema were dropped due to requests timing out in workload-low queues: + +---- +% kubectl get --raw /metrics | grep apiserver_flowcontrol_rejected_requests_total +apiserver_flowcontrol_rejected_requests_total{flow_schema="service-accounts",priority_level="workload-low",reason="time-out"} 100 +---- + +To check how close a given PriorityLevelConfiguration is to receiving 429s or experiencing increased latency due to queuing, you can compare the difference between the concurrency limit and the concurrency in use. In this example, we have a buffer of 100 requests. + +---- +% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_limit.*workload-low' +apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245 + +% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_in_use.*workload-low' +apiserver_flowcontrol_request_concurrency_in_use{flow_schema="service-accounts",priority_level="workload-low"} 145 +---- + +To check if a given PriorityLevelConfiguration is experiencing queuing but not necessarily dropped requests, the metric for `apiserver_flowcontrol_current_inqueue_requests` can be referenced: + +---- +% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_current_inqueue_requests.*workload-low' +apiserver_flowcontrol_current_inqueue_requests{flow_schema="service-accounts",priority_level="workload-low"} 10 +---- + +Other useful Prometheus metrics include: + +* apiserver_flowcontrol_dispatched_requests_total +* apiserver_flowcontrol_request_execution_seconds +* apiserver_flowcontrol_request_wait_duration_seconds + +See the upstream documentation for a complete list of https://kubernetes.io/docs/concepts/cluster-administration/flow-control/#observability[APF metrics]. + +=== Preventing Dropped Requests + +==== Prevent 429s by changing your workload + +When APF is dropping requests due to a given PriorityLevelConfiguration exceeding its maximum number of allowed inflight requests, clients in the affected FlowSchemas can decrease the number of requests executing at a given time. This can be accomplished by reducing the total number of requests made over the period where 429s are occurring. Note that long-running requests such as expensive list calls are especially problematic because they count as an inflight request for the entire duration they are executing. Reducing the number of these expensive requests or optimizing the latency of these list calls (for example, by reducing the number of objects fetched per request or switching to using a watch request) can help reduce the total concurrency required by the given workload. + +==== Prevent 429s by changing your APF settings + +!!! Warning + Only change default APF settings if you know what you are doing. Misconfigured APF settings can result in dropped API Server requests and significant workload disruptions. + +One other approach for preventing dropped requests is changing the default FlowSchemas or PriorityLevelConfigurations installed on EKS clusters. EKS installs the upstream default settings for FlowSchemas and PriorityLevelConfigurations for the given Kubernetes minor version. The API Server will automatically reconcile these objects back to their defaults if modified unless the following annotation on the objects is set to false: + +---- + metadata: + annotations: + apf.kubernetes.io/autoupdate-spec: "false" +---- + +At a high-level, APF settings can be modified to either: + +* Allocate more inflight capacity to requests you care about. +* Isolate non-essential or expensive requests that can starve capacity for other request types. + +This can be accomplished by either changing the default FlowSchemas and PriorityLevelConfigurations or by creating new objects of these types. Operators can increase the values for assuredConcurrencyShares for the relevant PriorityLevelConfigurations objects to increase the fraction of inflight requests they are allocated. Additionally, the number of requests that can be queued at a given time can also be increased if the application can handle the additional latency caused by requests being queued before they are dispatched. + +Alternatively, new FlowSchema and PriorityLevelConfigurations objects can be created that are specific to the customer's workload. Be aware that allocating more assuredConcurrencyShares to either existing PriorityLevelConfigurations or to new PriorityLevelConfigurations will cause the number of requests that can be handled by other buckets to be reduced as the overall limit will stay as 600 inflight per API Server. + +When making changes to APF defaults, these metrics should be monitored on a non-production cluster to ensure changing the settings do not cause unintended 429s: + +. The metric for `apiserver_flowcontrol_rejected_requests_total` should be monitored for all FlowSchemas to ensure that no buckets start to drop requests. +. The values for `apiserver_flowcontrol_request_concurrency_limit` and `apiserver_flowcontrol_request_concurrency_in_use` should be compared to ensure that the concurrency in use is not at risk for breaching the limit for that priority level. + +One common use-case for defining a new FlowSchema and PriorityLevelConfiguration is for isolation. Suppose we want to isolate long-running list event calls from pods to their own share of requests. This will prevent important requests from pods using the existing service-accounts FlowSchema from receiving 429s and being starved of request capacity. Recall that the total number of inflight requests is finite, however, this example shows APF settings can be modified to better divide request capacity for the given workload: + +Example FlowSchema object to isolate list event requests: + +---- +apiVersion: flowcontrol.apiserver.k8s.io/v1beta1 +kind: FlowSchema +metadata: + name: list-events-default-service-accounts +spec: + distinguisherMethod: + type: ByUser + matchingPrecedence: 8000 + priorityLevelConfiguration: + name: catch-all + rules: + - resourceRules: + - apiGroups: + - '*' + namespaces: + - default + resources: + - events + verbs: + - list + subjects: + - kind: ServiceAccount + serviceAccount: + name: default + namespace: default +---- + +* This FlowSchema captures all list event calls made by service accounts in the default namespace. +* The matching precedence 8000 is lower than the value of 9000 used by the existing service-accounts FlowSchema so these list event calls will match list-events-default-service-accounts rather than service-accounts. +* We're using the catch-all PriorityLevelConfiguration to isolate these requests. This bucket only allows 13 inflight requests to be used by these long-running list event calls. Pods will start to receive 429s as soon they try to issue more than 13 of these requests concurrently. + +== Retrieving resources in the API server + +Getting information from the API server is an expected behavior for clusters of any size. As you scale the number of resources in the cluster the frequency of requests and volume of data can quickly become a bottleneck for the control plane and will lead to API latency and slowness. Depending on the severity of the latency it cause unexpected downtime if you are not careful. + +Being aware of what you are requesting and how often are the first steps to avoiding these types of problems. Here is guidance to limit the volume of queries based on the scaling best practices. Suggestions in this section are provided in order starting with the options that are known to scale the best. + +=== Use Shared Informers + +When building controllers and automation that integrate with the Kubernetes API you will often need to get information from Kubernetes resources. If you poll for these resources regularly it can cause a significant load on the API server. + +Using an https://pkg.go.dev/k8s.io/client-go/informers[informer] from the client-go library will give you benefits of watching for changes to the resources based on events instead of polling for changes. Informers further reduce the load by using shared cache for the events and changes so multiple controllers watching the same resources do not add additional load. + +Controllers should avoid polling cluster wide resources without labels and field selectors especially in large clusters. Each un-filtered poll requires a lot of unnecessary data to be sent from etcd through the API server to be filtered by the client. By filtering based on labels and namespaces you can reduce the amount of work the API server needs to perform to fullfil the request and data sent to the client. + +=== Optimize Kubernetes API usage + +When calling the Kubernetes API with custom controllers or automation it's important that you limit the calls to only the resources you need. Without limits you can cause unneeded load on the API server and etcd. + +It is recommended that you use the watch argument whenever possible. With no arguments the default behavior is to list objects. To use watch instead of list you can append `?watch=true` to the end of your API request. For example, to get all pods in the default namespace with a watch use: + +---- +/api/v1/namespaces/default/pods?watch=true +---- + +If you are listing objects you should limit the scope of what you are listing and the amount of data returned. You can limit the returned data by adding `limit=500` argument to requests. The `fieldSelector` argument and `/namespace/` path can be useful to make sure your lists are as narrowly scoped as needed. For example, to list only running pods in the default namespace use the following API path and arguments. + +---- +/api/v1/namespaces/default/pods?fieldSelector=status.phase=Running&limit=500 +---- + +Or list all pods that are running with: + +---- +/api/v1/pods?fieldSelector=status.phase=Running&limit=500 +---- + +Another option to limit watch calls or listed objects is to use https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions[`resourceVersions` which you can read about in the Kubernetes documentation]. Without a `resourceVersion` argument you will receive the most recent version available which requires an etcd quorum read which is the most expensive and slowest read for the database. The resourceVersion depends on what resources you are trying to query and can be found in the `metadata.resourseVersion` field. This is also recommended in case of using watch calls and not just list calls + +There is a special `resourceVersion=0` available that will return results from the API server cache. This can reduce etcd load but it does not support pagination. + +---- +/api/v1/namespaces/default/pods?resourceVersion=0 +---- + +It's recommended to use watch with a resourceVersion set to be the most recent known value received from its preceding list or watch. This is handled automatically in client-go. But it's suggested to double check it if you are using a k8s client in other languages. + +---- +/api/v1/namespaces/default/pods?watch=true&resourceVersion=362812295 +---- + +If you call the API without any arguments it will be the most resource intensive for the API server and etcd. This call will get all pods in all namespaces without pagination or limiting the scope and require a quorum read from etcd. + +---- +/api/v1/pods +---- diff --git a/latest/bpg/scalability/data-plane.adoc b/latest/bpg/scalability/data-plane.adoc new file mode 100644 index 000000000..b98ce19b7 --- /dev/null +++ b/latest/bpg/scalability/data-plane.adoc @@ -0,0 +1,215 @@ += Kubernetes Data Plane + +The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped xref:./cluster-services.adoc[cluster services] in a separate page and load balancer scaling can be found in the xref:./workloads.adoc[workloads section]. This section will focus on scaling compute resources. + +Selecting EC2 instance types is possibly one of the hardest decisions customers face because in clusters with multiple workloads. There is no one-size-fits all solution. Here are some tips to help you avoid common pitfalls with scaling compute. + +== Automatic node autoscaling + +We recommend you use node autoscaling that reduces toil and integrates deeply with Kubernetes. https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[Managed node groups] and https://karpenter.sh/[Karpenter] are recommended for large scale clusters. + +Managed node groups will give you the flexibility of Amazon EC2 Auto Scaling groups with added benefits for managed upgrades and configuration. It can be scaled with the https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler[Kubernetes Cluster Autoscaler] and is a common option for clusters that have a variety of compute needs. + +Karpenter is an open source, workload-native node autoscaler created by AWS. It scales nodes in a cluster based on the workload requirements for resources (e.g. GPU) and taints and tolerations (e.g. zone spread) without managing node groups. Nodes are created directly from EC2 which avoids default node group quotas--450 nodes per group--and provides greater instance selection flexibility with less operational overhead. We recommend customers use Karpenter when possible. + +== Use many different EC2 instance types + +Each AWS region has a limited number of available instances per instance type. If you create a cluster that uses only one instance type and scale the number of nodes beyond the capacity of the region you will receive an error that no instances are available. To avoid this issue you should not arbitrarily limit the type of instances that can be use in your cluster. + +Karpenter will use a broad set of compatible instance types by default and will pick an instance at provisioning time based on pending workload requirements, availability, and cost. You can broaden the list of instance types used in the `karpenter.k8s.aws/instance-category` key of https://karpenter.sh/docs/concepts/nodepools/#instance-types[NodePools]. + +The Kubernetes Cluster Autoscaler requires node groups to be similarly sized so they can be consistently scaled. You should create multiple groups based on CPU and memory size and scale them independently. Use the https://github.com/aws/amazon-ec2-instance-selector[ec2-instance-selector] to identify instances that are similarly sized for your node groups. + +---- +ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16 +a1.2xlarge +a1.4xlarge +a1.metal +c4.4xlarge +c4.8xlarge +c5.12xlarge +c5.18xlarge +c5.24xlarge +c5.2xlarge +c5.4xlarge +c5.9xlarge +c5.metal +---- + +== Prefer larger nodes to reduce API server load + +When deciding what instance types to use, fewer, large nodes will put less load on the Kubernetes Control Plane because there will be fewer kubelets and DaemonSets running. However, large nodes may not be utilized fully like smaller nodes. Node sizes should be evaluated based on your workload availability and scale requirements. + +A cluster with three u-24tb1.metal instances (24 TB memory and 448 cores) has 3 kubelets, and would be limited to 110 pods per node by default. If your pods use 4 cores each then this might be expected (4 cores x 110 = 440 cores/node). With a 3 node cluster your ability to handle an instance incident would be low because 1 instance outage could impact 1/3 of the cluster. You should specify node requirements and pod spread in your workloads so the Kubernetes scheduler can place workloads properly. + +Workloads should define the resources they need and the availability required via taints, tolerations, and https://kubernetes.io/blog/2020/05/introducing-podtopologyspread/[PodTopologySpread]. They should prefer the largest nodes that can be fully utilized and meet availability goals to reduce control plane load, lower operations, and reduce cost. + +The Kubernetes Scheduler will automatically try to spread workloads across availability zones and hosts if resources are available. If no capacity is available the Kubernetes Cluster Autoscaler will attempt to add nodes in each Availability Zone evenly. Karpenter will attempt to add nodes as quickly and cheaply as possible unless the workload specifies other requirements. + +To force workloads to spread with the scheduler and new nodes to be created across availability zones you should use topologySpreadConstraints: + +---- +spec: + topologySpreadConstraints: + - maxSkew: 3 + topologyKey: "topology.kubernetes.io/zone" + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + dev: my-deployment + - maxSkew: 2 + topologyKey: "kubernetes.io/hostname" + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + dev: my-deployment +---- + +== Use similar node sizes for consistent workload performance + +Workloads should define what size nodes they need to be run on to allow consistent performance and predictable scaling. A workload requesting 500m CPU will perform differently on an instance with 4 cores vs one with 16 cores. Avoid instance types that use burstable CPUs like T series instances. + +To make sure your workloads get consistent performance a workload can use the https://karpenter.sh/docs/concepts/scheduling/#labels[supported Karpenter labels] to target specific instances sizes. + +---- +kind: deployment +... +spec: + template: + spec: + containers: + nodeSelector: + karpenter.k8s.aws/instance-size: 8xlarge +---- + +Workloads being scheduled in a cluster with the Kubernetes Cluster Autoscaler should match a node selector to node groups based on label matching. + +---- +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: eks.amazonaws.com/nodegroup + operator: In + values: + - 8-core-node-group # match your node group name +---- + +== Use compute resources efficiently + +Compute resources include EC2 instances and availability zones. Using compute resources effectively will increase your scalability, availability, performance, and reduce your total cost. Efficient resource usage is extremely difficult to predict in an autoscaling environment with multiple applications. https://karpenter.sh/[Karpenter] was created to provision instances on-demand based on the workload needs to maximize utilization and flexibility. + +Karpenter allows workloads to declare the type of compute resources it needs without first creating node groups or configuring label taints for specific nodes. See the https://aws.github.io/aws-eks-best-practices/karpenter/[Karpenter best practices] for more information. Consider enabling https://aws.github.io/aws-eks-best-practices/karpenter/#configure-requestslimits-for-all-non-cpu-resources-when-using-consolidation[consolidation] in your Karpenter provisioner to replace nodes that are under utilized. + +== Automate Amazon Machine Image (AMI) updates + +Keeping worker node components up to date will make sure you have the latest security patches and compatible features with the Kubernetes API. Updating the kubelet is the most important component for Kubernetes functionality, but automating OS, kernel, and locally installed application patches will reduce maintenance as you scale. + +It is recommended that you use the latest https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[Amazon EKS optimized Amazon Linux 2] or https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami-bottlerocket.html[Amazon EKS optimized Bottlerocket AMI] for your node image. Karpenter will automatically use the https://karpenter.sh/docs/concepts/nodepools/#instance-types[latest available AMI] to provision new nodes in the cluster. Managed node groups will update the AMI during a https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html[node group update] but will not update the AMI ID at node provisioning time. + +For Managed Node Groups you need to update the Auto Scaling Group (ASG) launch template with new AMI IDs when they are available for patch releases. AMI minor versions (e.g. 1.23.5 to 1.24.3) will be available in the EKS console and API as https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html[upgrades for the node group]. Patch release versions (e.g. 1.23.5 to 1.23.6) will not be presented as upgrades for the node groups. If you want to keep your node group up to date with AMI patch releases you need to create new launch template version and let the node group replace instances with the new AMI release. + +You can find the latest available AMI from https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[this page] or use the AWS CLI. + +---- +aws ssm get-parameter \ + --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \ + --query "Parameter.Value" \ + --output text +---- + +== Use multiple EBS volumes for containers + +EBS volumes have input/output (I/O) quota based on the type of volume (e.g. gp3) and the size of the disk. If your applications share a single EBS root volume with the host this can exhaust the disk quota for the entire host and cause other applications to wait for available capacity. Applications write to disk if they write files to their overlay partition, mount a local volume from the host, and also when they log to standard out (STDOUT) depending on the logging agent used. + +To avoid disk I/O exhaustion you should mount a second volume to the container state folder (e.g. /run/containerd), use separate EBS volumes for workload storage, and disable unnecessary local logging. + +To mount a second volume to your EC2 instances using https://eksctl.io/[eksctl] you can use a node group with this configuration: + +---- +managedNodeGroups: + - name: al2-workers + amiFamily: AmazonLinux2 + desiredCapacity: 2 + volumeSize: 80 + additionalVolumes: + - volumeName: '/dev/sdz' + volumeSize: 100 + preBootstrapCommands: + - | + "systemctl stop containerd" + "mkfs -t ext4 /dev/nvme1n1" + "rm -rf /var/lib/containerd/*" + "mount /dev/nvme1n1 /var/lib/containerd/" + "systemctl start containerd" +---- + +If you are using terraform to provision your node groups please see examples in https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/stateful/#eks-managed-nodegroup-w-multiple-volumes[EKS Blueprints for terraform]. If you are using Karpenter to provision nodes you can use https://karpenter.sh/docs/concepts/nodeclasses/#specblockdevicemappings[`blockDeviceMappings`] with node user-data to add additional volumes. + +To mount an EBS volume directly to your pod you should use the https://github.com/kubernetes-sigs/aws-ebs-csi-driver[AWS EBS CSI driver] and consume a volume with a storage class. + +---- +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: ebs-sc +provisioner: ebs.csi.aws.com +volumeBindingMode: WaitForFirstConsumer +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: ebs-claim +spec: + accessModes: + - ReadWriteOnce + storageClassName: ebs-sc + resources: + requests: + storage: 4Gi +--- +apiVersion: v1 +kind: Pod +metadata: + name: app +spec: + containers: + - name: app + image: public.ecr.aws/docker/library/nginx + volumeMounts: + - name: persistent-storage + mountPath: /data + volumes: + - name: persistent-storage + persistentVolumeClaim: + claimName: ebs-claim +---- + +== Avoid instances with low EBS attach limits if workloads use EBS volumes + +EBS is one of the easiest ways for workloads to have persistent storage, but it also comes with scalability limitations. Each instance type has a maximum number of https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html[EBS volumes that can be attached]. Workloads need to declare what instance types they should run on and limit the number of replicas on a single instance with Kubernetes taints. + +== Disable unnecessary logging to disk + +Avoid unnecessary local logging by not running your applications with debug logging in production and disabling logging that reads and writes to disk frequently. Journald is the local logging service that keeps a log buffer in memory and flushes to disk periodically. Journald is preferred over syslog which logs every line immediately to disk. Disabling syslog also lowers the total amount of storage you need and avoids needing complicated log rotation rules. To disable syslog you can add the following snippet to your cloud-init configuration: + +---- +runcmd: + - [ systemctl, disable, --now, syslog.service ] +---- + +== Patch instances in place when OS update speed is a necessity + +!!! Attention + Patching instances in place should only be done when required. Amazon recommends treating infrastructure as immutable and thoroughly testing updates that are promoted through lower environments the same way applications are. This section applies when that is not possible. + +It takes seconds to install a package on an existing Linux host without disrupting containerized workloads. The package can be installed and validated without cordoning, draining, or replacing the instance. + +To replace an instance you first need to create, validate, and distribute new AMIs. The instance needs to have a replacement created, and the old instance needs to be cordoned and drained. Then workloads need to be created on the new instance, verified, and repeated for all instances that need to be patched. It takes hours, days, or weeks to replace instances safely without disrupting workloads. + +Amazon recommends using immutable infrastructure that is built, tested, and promoted from an automated, declarative system, but if you have a requirement to patch systems quickly then you will need to patch systems in place and replace them as new AMIs are made available. Because of the large time differential between patching and replacing systems we recommend using https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-patch.html[AWS Systems Manager Patch Manager] to automate patching nodes when required to do so. + +Patching nodes will allow you to quickly roll out security updates and replace the instances on a regular schedule after your AMI has been updated. If you are using an operating system with a read-only root file system like https://flatcar-linux.org/[Flatcar Container Linux] or https://github.com/bottlerocket-os/bottlerocket[Bottlerocket OS] we recommend using the update operators that work with those operating systems. The https://github.com/flatcar/flatcar-linux-update-operator[Flatcar Linux update operator] and https://github.com/bottlerocket-os/bottlerocket-update-operator[Bottlerocket update operator] will reboot instances to keep nodes up to date automatically. diff --git a/latest/bpg/scalability/images/APF.jpg b/latest/bpg/scalability/images/APF.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c347bb8c540abdb17490298387afdcac6b903e72 GIT binary patch literal 262223 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

F9fd`3)s91eDN3UJ~{6k2@MP= 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

I{krht$kRfw(H6omvqH@wpPT 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/PLEG-duration.png b/latest/bpg/scalability/images/PLEG-duration.png new file mode 100644 index 0000000000000000000000000000000000000000..b60a6bdee7b01f52b0a61e1ac04a7b4ac00ce624 GIT binary patch literal 39119 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 A5C8xG literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/api-request-duration.png b/latest/bpg/scalability/images/api-request-duration.png new file mode 100644 index 0000000000000000000000000000000000000000..146775e4c86561c9d6cb8821799f8abd72af6275 GIT binary patch literal 35993 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/bad-sweetspot.png b/latest/bpg/scalability/images/bad-sweetspot.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac7b21f2328477473e8d64ab4b224ce6df2977d GIT binary patch literal 32641 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/bottlenecks.png b/latest/bpg/scalability/images/bottlenecks.png new file mode 100644 index 0000000000000000000000000000000000000000..63f811f4e34bc7ec0de2c3bf3fdac8ca0b9e73a5 GIT binary patch literal 30923 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�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%0D$sUUl3W|o;dv9RClAp> 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ⅈ z=t=kly52>Ah0X;Xa2}k|(=77bNN?Dd=*oPi#A~1D!&{PPZR>%uh&S5$Tv|s zUl+65smF_UyCtg^QD<3_v=g~u7`dn>e0y4qqek3`R8KVvUsvF zV#C_9xZ19+u0Hrixs&52nSY3h!2TyN{TbKLQV<+Iwp>eR_-CH~30v6@o|)JFzdrl_ pe*Qmq{l6x`|L32f9uy}ug1&b?k@|mLL;s5JL&Zl5<@e3Q{s)Ok=d=I- literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/churn-rate.png b/latest/bpg/scalability/images/churn-rate.png new file mode 100644 index 0000000000000000000000000000000000000000..cce2eda83cdf4ba2bd884e869e6dfebd1f1af2d5 GIT binary patch literal 34724 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/cores-1.png b/latest/bpg/scalability/images/cores-1.png new file mode 100644 index 0000000000000000000000000000000000000000..5423516a9c4487529936ca1395f5bb37443b6d04 GIT binary patch literal 13448 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 CG243p literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/cores-2.png b/latest/bpg/scalability/images/cores-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2a2d8cfb71cabd5e5b0a3f9460991b690591394a GIT binary patch literal 15976 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/cpu-1.png b/latest/bpg/scalability/images/cpu-1.png new file mode 100644 index 0000000000000000000000000000000000000000..06081668c19f3501f195a635c0db91acbb491e18 GIT binary patch literal 63481 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/cpu-2.png b/latest/bpg/scalability/images/cpu-2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a52b22abe42ad4f70f9f800ba76c025a15e466a GIT binary patch literal 65609 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
gIiEY1Ty(2B69 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/cpu-limits.png b/latest/bpg/scalability/images/cpu-limits.png new file mode 100644 index 0000000000000000000000000000000000000000..aab5e7aa165f12625014d99fe5d58f72ebd77716 GIT binary patch literal 21976 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/defrag.png b/latest/bpg/scalability/images/defrag.png new file mode 100644 index 0000000000000000000000000000000000000000..d870c49a8b3e19707805612e160a6e42a3f14b92 GIT binary patch literal 242544 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%0D&G#3kDyogjT%B8YULyDSp;jy~iR~rT!NI4b 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 BVYC1M literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/flow-addons.png b/latest/bpg/scalability/images/flow-addons.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3dc046c6bb35131c325af9051e23a33e606967 GIT binary patch literal 16585 zcmeIZby(C*^fyc_NQj~cD1so8(k%@l!ot!ejdU&Dje!Cx(jC%`bT1fmDa|eoOLs5% zeDM~zfA{k|@B8oidNW7z6kvD+2jS-R89`h;;yeI?m zfX_~Xa3Ao6YbUMgh=ztwbpD5q7ME}r7!K4z^@Y<5If#IfEtK`8v8|yAs~gnroC{6J zO#moDO`Kj*xk0UM90lBjssB(20Oj*)HfpLrBu-Ys)Gy=|sU&P2OsIHS*;(1CMewMo zsDvDhO$C&nJ^#xN{3lFp?&M@Az{ck4>dNZM#cJzd#>Tk){%`eFYyWV)xMCCGyWshE<$oD8 z|4$76uKX{9f`f$#ppo;AiE#Yw)W7TgOD|yywR13Wbo@8{zw7=>uV`-TWDCrugM|^; z#>vD1VE)_M#c=-b6n|w2v7JxIzb5FP+5b}uOuq=85Zk3GiQp+srBkD!32TC%iL1Jy zuZ~^wQdNUBZu)vWwf(|}e(Q7Q9ql{BUsI`FoFsJ-hAq0zyTX#XLp277${=UgRV+^| zP&!yC{q-FQwud`ti|fZdor#bDFlCq^SHlc_Y^-Mw|Ni)T;zM7B_`44u`k`UqPyr9( zI}1G4)-SPwKU4T~Voi5+ierNa#n8}!2i1Eq%OfB0iV|G^c3k81p2*>L;*2~0u>Ilv zLQKU@P(WXPDGWzd*{`uI%aD4>(I#l0Ke9s92Oi;&NcdvT5r7{>KwXhqZZ0JE19C|uR(9k>?|sH z>mL=M`5R#Hva_UjamNrKuKJOy20A^tbsSd~*Z08TZu;g?a4W@1W4Qiq+02 zTT|OeS9&NrmmMB5WWFriQNf(GJY4u;_}W>I>+)=EH6mT=oyXQra!p4`xhJxal$5w= zw2o|;e!%9)1j*Vauz)MmAz%u_HC%_~hbN4d7O#v)GwpxWejLwr^Kc19e(q!O$G@H9gDZWtV#&5?VEU7c7r+>Mi;Dh_~E?zPsaV z2$FwpM^Z3d&N7JL4bR;{v7Ik`QHZU>yr_{V^H0$Ucg-pzoo~Qiz1;eVi0p}Z$6l?U zK=)VQZ^R~-xDdlB+=6`iNj|obkQ3+HpFiKH@0wdb@Qg4+5_EE)6ZOck}G57EA z%njVT?YmY#`TEw5V`m(G=Z6_t>!n#dK%ET9^-lv_cyU@U7n0(FF^V4t#^84SVKn2Hw^U8%*Ro(r)nIOQJ zlfHup@OBy65HCPR;R{OtsKKQ*VW|-Q)-Rl*K~xL;sur zKI}LHo>aY}+&X`jqnI216QXxzO=V?eP>oNc$07R2dP?5b)7S1{cPW`j3Cw8~MxDxH z_!Vd~zj+InZu%b3{@}ZwQrB`lU-k9OXdQ;dAcJN=(kQ2$>(BbkChln)M$$Kb*IWj! zIa79K^Dfb9{$cOd5~o5@EbDIG>0T-1c%+YI;^e(YZ=T9YO4Cy8uKbZJ)O=rVqq}*C zl$bx$w@KT@xWlZE4P$nEhptW|;TvMZZUo1%o)h#np&DUZ&uq*vKL&cM?m?%meI%*b`0AKG=jx`c^ zJHeZWvGDy=z<+5rDO7l{zt1q2W#rg^Fn8Z?8$5mMpT$gyXU*-uI6WcU!8XR8Uca+v zb+R&2ob;hOqjqP#S8=U+T6%GyINPMmC=aeI*i@>j3N})?w!2xVdsu3=syx5d;R&H{ zIGcfCqEf$EaHp4$P6uIQ75K%4&IS0p<%g99)t}ekxP6c4x?2+>^{w4`S z@I>ElU>2_lMWl5|nUt-D$j7%|ESb}jq>tX)3I90*LK(hVkBQvlckyRtFP(D^Jqd6o zf-2^s=lW1A))5OL`z+!+H3H{G48F=DYHnMlX7YEqv||>r@|fVIr!+naFDiW}N45fG zIYCzH(*5e%UD-L(O)|1{Il+D`he9Puc_*1AiJom*wsEu!l(m4`<1l)@*<7E|=Qux= z$dd+{Kd||$xW+dM_Eok6r&C6!h7;nRqsTw!6Y-y8A2{EMS?1c01%8N>i-!^Ly2h?& z?JJOd;LS;bEIm}Ynv6s({QYDXG8Q|ioZMY8vD+`TYE9)L4_H`# zw-?@g$K>ecIT}YaT*0KRhvL*7jNig2saypeC@vEWkiM$BM}O$AvH zO<96&iIba#ci~D8N3V2jqLU;W^^hsrHJ^2s})*5g%LWV|*HTORlZ zI4!%UT8|~Lih6BF8B>n3Av(8R^?m!9Gw;)ro=vgM#Xp#)W#f~|^g1id*W1jSokvQ~ zryX_peT$ZTY8Y1EiwyP+tLB15)z@-m$c7MgrdFc#(4VTXfo}e>2H*kggGnTP3`?eZ zF!QLogP&btF$vVG0#4EQ!bPKU=!WZ-nx)d6YtxL|iu!2T*fd<$;Wo)uVp{CSHhsj& zYzo3|k;gCxe{S1>Z`irp^N@(dSZ%pUkC4uIRC(Rj=-6$_WU7zxWw*!XLHRXvG5fOQ zGIh6B{<=fxpj6#PgdrKl^|y2a{p!EcBj8)VxRPb-vE_^>#uGU``Uz1xW5rvYOkA_S z=V6gbzCzI9qLY+C$$aPl~C8Qr^Q!gI|GiA)y6|9hHj&gQ@oPFbE7`UETyBqEpFt*asL3AryvlsFL*jYKg~kBn%H!MSQJde7l0vT{~)t%lL*MiS*# z6M>Xa_QmK&-<yJ1SnP|+ireCC)%9&$0)Xc&?hN&}HaEO8th z93>CEtGO+EQ-?#aGvtFleyrqLP8>Rnf!7t>i7QT*C57xmySv(WgXfE)n&q@dJfc|= zUTQ&vADY8r#me1IRrU4$rOOCb!l9`*%g4>ub?rA!bUAhu^y4A;5V!w(P$iuaz!E&VeX`#P^m5Il@_lTGMqpWm< za~^4j@2PXcLRCME{zhoI6-kE-*A%$+xU_V?!_zb@5;o{GZ9$6I+LOFnf5J_C6hdftm~V9a)76lCwOraqsPJJlp7MflQ*_YtC@1 z_hRc=?&~}E8TIDKQpO6ea=C9ed3Fk9RXd<4DNBwF4O4Sp!slBrts;dQ`4FI8B7&QR-G zZ_{CTm=%_3@WRl{yz!r~A6X#K3AT3Ps$)gG^PnwTtEHb(0kfA* z4sl@ncu(k?(-5BpiI;C09ZN8B*HOQsjgt##1V${-_2 zX(|h_MSCZ8$+>~U-W=hIaoL_96R56qOV^$?0d!d>b_WPm$eQ?)WiRQzx1cG{!^R!%;4KWtzqh{a&@QWofM`9 zvSR+L*jB6!qbw%M`p1K-E?eF)@ISHqIj49vblP)`pk#W(-VVRMXq`%t1z=Uj=ej0- zIWz`YAg(jPEvEb%xDbk^Xn|rP^;tT}L047G=(fR(uOS_;3@<|^zs4!zl%}1HLuJ7$ z9q?n_HPVu2D7lJO$@S1pk(7G+mX}%~WXL*?;2vfoXQ{7(;l`=kfHb={WwtA6Z$W^x zhpe2BE;kx-Rv?hP8O^*)eOaX{-H4qTPGY8>O&EJ|^j>!Sa+sH!`PIz-f4lSw=O<{S zneM^{fG}R~M>9!OoPQ#Y>QgG%Z4-t|qmu?aDF!M+PX7-()wl1Lz_b4yazDl)j8R7q zNxib1FGK)xl1O_IgaF2)Dh?ngcy4$8`bmIxaS{P|V}Usb_fpd-cz_A3HKs9KP2U0t zKu*lSa#y0&2m#~-&XE&MWuhz5#GvVG zALI01yxqDZNtNArj&F#&e!cLh2^qwx^eXj5tJH97M?Q!(Vd*7)EuMbM;Qv>o5}N^L z-%~gw?ertsWh;t(7#}za76ltOuX>jc7^Hz>qwl6-~WxuK< z{0hBXN3V5bTuj@055Tu$EZzE-CPJw{huxun`}VB^dsd@!bpK->&D%4E$bFV0tCi8E z!Jz1OMXS_;`*ZDSXPQbz^S4$S0pIMqLGAD*9`)v(A9fmF(vaSvlMNLM89gF=yn;&` z7F(}2o>(Tnh5z*aO21rSrSn=(HyfYg>g*HunQU@_WX}NDpti_J2;EKN-Ai6w#W?n3&qx3 zXVo3Fk?9kn_5eJ!33f;IOvY1(hwZ>5oDbnL^O zvc@}xIt-83rW#5blaK3Hh%m9*Z?|3E5B!9zJLp$;aOi1nS{hn~r{?D5&saPV-p{gK zW0fk)W?8PJ_-Z7<(^_|u`pH3g|9PBb87X@XXka#R2|9XS?h2$yD9nMVxZSKT1xBD3Q~3ewd^^tVGZGx%U0*ta1~N0HDrt z`@uxP7oo!zo8B>y?HGJ0GGkGaB~Vt*4%NscYu&MIW%^y&h$w&WNoo=#Ci>yF`byZ% z=lgusXUtlBs$^h1;jr6sUp;z=rQknU zv`V$h)HGgCx7aS2V(u8sEA=6O(FvUTQC@$#`yhMKm8a#;A^x7sfA;4S&jORKn)T6| zimv@nv0sXGSK@rMYWgaym$vsZgGWV$57&_;>te7~n=@x5YprbUnyie+aY&|3N$s^A z8^hY;WzX&9n7$HaiI5xkW)y=O*1&k6 zdljYvyH?Saa_B^{$Mp0Tez{ecrGx`d! zvlY71M@AZ(v?*kuwE zWjbi%O2L$iz9PUS-v`!`53it8=U((kmluF(Ke`_=7gL;BTh=kd*5Y;IVHh?0+z z5nakfgL59w3O2N1a8vwmf;? zs@lUSsz^su0nbT26il|U7?&9bPxly9)Gg(gZB{@q=Rv$#$lSFopaGAM;h(2)(-l_6 zUpO%rR0J)BVE5r}W?YMn=M*+^X3ou={rRH$2PDqHDwS!Xz%^j|?s{nkUGY=PxkPXoB@C$B?tdKde%P>jbQ?Bj6 zGeVq5G2-!%zfMiccZ`m~)$mXw($-gMwW|V&6&>TC46>A^q0nya;y$14K1a%e3a-Un zCfVBfdwcNdY<qo?mn+M~9AH*8g zR6>denZX%tjPvem7EtFUww}#7)(P64x`tl85P6T@*i)(a?Fkz#1yau;8s|@6Cftz8 zI|(8QB}z{3#cSuv)Ab5Ko?QSCy@x11-maN)?@UqZ!!LT0lXJiOt>b$_e^)c>@Ia$p znRV^=pRJIbz;f_6zXZ_=YrQB$7B!_|jXoykUy1soRCQ&*^zv9g?NcY>(v74}=pQXA zD(lj7Z`@BW)7Dw;EuwRV1%k~cm!Aw42$n!8;-p?bwOv1ZxT`Vi=D`BLohO0g)VZ?e zXIqFT6m?dAmF2K3(SvKHnexId3t8I4t>$Kolp%b80u645R zl9k+52_Tf+#tIfVd*|Lm#?|hpQVqgp0IULGpKGn#MHMErlnBWw;;?H{iZw# z4BLG9E0?-jrIp=M^BpxK$UNjsCW<+RHCorPp+8r5XgtK*)3uF${X^(;Ij#0;(lP5w zUg^kLMtXlPlNmw%c)uFkLVcpB=PPF2 zCn`&PkjRImA=l&HeY|k4&@djLD;O+wr|{42n>U4xaL&97LDmJ^hHBAeGcz!Jwl`W2 z%fL5nMGlD=m_@F4j#9IItd>wOim`<~qz0}VWIIoDCK~AHuh(h@5Kz*Jo*cw_Llu4< z+jf0rS{Iqs;hFSCj?~i9&!?a&0-oG+xaGh2P}=&^kvj&ZmN4nh*qz)v>lU?EjB`0` z;@lX$<${Pm^Jv7*!0fKlVWqHdprNDfIL)u$Iw36r@A)&ww`|JF6teXB97uQ9uDAq- zu$@8)x#)bYUn@i9gzqYLGxq%Jo-NeRj6&tU4gZuDji>;r9>cb&56gtlVG#L9d6AC$ zjCpCAVwt2ffUl+h2(6#Zy-&$2p2M1@XkN3l-1@6y{c}fQ{RE7+!CFS}gnFb_P=%y3 z-dK;cnm8`UMFr+5rB$&=lUTC@m_2+wnU6EslP&hzg)^Iifsuqvg>|CF~ zd4MNas<3^y9Qc@pXMCVjOr&$eOD%_prdwf)3Xu9w#RG z$NKy|b}1OL5>Kv;)V++XJA(fhgw#$rk7VUc)I;f{3mE3A99z`aSB?zhSA)Yl9aQ4R z$@Wu>R}r*XF&UZCR||=l2tclvCdxF5x27Ty)$-ffV+*8u?jiYFyb7jrsAr#6ToMut zv_yKyJ;J?qe+O^PVn%}-!ULrH=2ne6GI_SP^KH|udcxDqlKqo1l^v1t8eYIpT_q|f z#>kTDumokP!^9^)*Giv^8(Hezz6hcG0MJBfz>w@dsTr+dCm)A}jI?yb^19a`b~t6- zCLa-mr2Vt3O}Lefw~SNsNoN~nY!Q?9^SSN=<(gd?u8EBuQf>K$Hn2**=Hqs-#cS45 z1qF6lXFrgf^t(kL`_2#N(>|T#gEK54B8b~pK$queKAy&9aw%RH>U6Y#0C||wKQb(Go}^f$>Zmhew4acDQNx@SVBgSn`7N1 zmsRMXT(!nNNNZ<;rR2Q9)il1t`(@~njjMeTxT1qB#Zt_*+zH4NB(9(ts!1FGgwizX z+nl@%&BamzfT*|Nq1%n%i&a6Tr~_b7O~P)McOq1Z5*Xu}C>|%Le^L4QY50+-jN@JP zqL479sh_yg|6fsdN>jxCrCdJ%r^A8h+TVYIdo`k(E%%$3SRzi-tLEN_HF7ma6dn^QDq~$V;U}gBs$J5&U{rlfCZ@OKg@ud9*U)3 zUh<&%=i;+7H7o`6UxxTpgc#=$y#z!;3`~5bDYaVwruo<-;$H|(ESeES;yGCIe-JS> z{D;Vo07B2weO>dd>P5_UMgRYot}N~UsRRO`y1F^qi>X!2Z2WaCgoT-l=pJEqikKJH zcK8JdLHHG8)iZOKL1_-D;UeePy|zTq+$!+q z9P~ftMGb9eNneST;}0WK3n@o);WsST+kJY>r_ao{1;U^P$Wkba0 z%L~XRBF;(!VT3+ZY@HY7w4u>B$LyZ@0cMD*y@T!=CM%Xwf^qC?VS;4%bE*=aqiPb@ zWt^`BMG|eeATq9NG5y=|2xHaNKRNv2dI$ji z+&@!P--%V>5=I9gC}zBX^WMLe_#Z6JVVzwgKr9yHO{U51Q1o-P0top+dl8B0jaPob zSnp+Zy&RwL0M%4AKy^srQP%*q-Fr0q#fLQi_;A?|(W8QM|GVQA9#220drEZ(GUxmV z^Xw)*2f0~^Q1%RoiQ;$JtxVIZAF(gXyoRU z&m(?c&|@aW)?D()j5Ofp=S_~-yXG-uluA;>4n+s@ZH_AUp98q~JBqi~f@pS4jFkME3J=%oFej*{#H7wUf2bs9nJrv~@q` z34xxCj?ChK8mCrb`|$(GeU9}ABiR6;KfDr%+4PF4+>eUcVge+&2H z^#pq3<#Ff8n$9PEmRf?vKwcCPggwDp%Zw>Z<}uMDj*7UufeCiqh)Dfg54NcN#AtAT z8IXZp!>z>8{Dbhw$Bv)ymoBSS3`Ym+N7HJXBIYp#bQvT*!PMyr-SlDFrxj!BY}KJc zcFoHr%Z)DXUf*|{Za6EgYo|*E6VZsUD(yWOWeoQ@YP^2!;AeD}QFsz({!ntdd%a6$ zIj_3QYR_j}rt$FD247?c(Ls6{C%vnXe)pP3Ig2t=ap5tv_1zw-A#;rWzH8Bq{KwXM zeUX&Bl|e+3lkB*Ju@C58W)O2$tXqWNyxC(=&W1t4bDRdT4=wSx={S^XZ4FQUioO^nY$b`= zhFz|V3^TF`uOAUK`JEXHn-NfGf9%Na+F*=a361zEuyG`s(!|p1y9AusK;CvuJC<1HC z^sLP-`q=6f6^sp5xi}u(J;>uU!C1y=87f?F@97+-IZvRl)@e{SG&0Iii5B5B*f3G9 zm0x@vyld)phPqz@-PQsNu5N%bZ9m>;p%C1UvJvi}jIq(GR37);wg=0|gwCgKOccLcnP|`e0!8Lp*Yns}SaB^}B*E9Ud@ZPdeYU{7+CiWB-mUBuzwM-agW~sX zNidIMucO7hJrBdqvtvE3t@WltXwP`!Ru}yY4F?ARAlTAegRph_pBxz<3-+`_eZ9dz z&P4Z|e#HTO?CFmd&e#`w6*Qz$G`7_9fs~jCLs~xw@ zw;jzsCbU3_K7|VUxJlV0j%Gan)FaNsvJrkSEG` zUw7x6RtSkbd)Xa!20J$RRcC$u5&G#WPFlRPn>-JbStYJ~a*3>DIdoXFd)@xEu%h~& z&CzgMXXcPe%I%pjWROUjj1cZvR`AO5VK%+2p?+W(`{G5xg3%$aVIygE*}+ZX>R`E&&Qb${CIwSa(NP zC?lPpZoMIF7Kvd++BVFR~GaxLNE;X!0u zq_z;f)nVb@jkAk%m_0BpWy^t0@{Z#{bp)<{J>y~?iR_Q&t`!b1!TR~FuB@UMQOj${ zV_Dnn)kEkadF<}Yyu&zcrA%70DS04YQP{a!g+;G~EmTnI(FuDWc zcLGs;GP3osoKN*OOAc%)DxT$mWp0uOZ@5?OtS|utG%7gs&b+=ZQEs&MvJl z<+e_=JHPuR?Kuq7F-MSxoIGU)%jc|i*oe-Yngs1_bjo2IBc?KIm1gEkdLcS-=212R zX&rXkktw7x>RoTQj&AgTGBcgEJ5FBfbA+ca4d2_KO|-6@J2BbeUzh%*nbPpGAd?rd zGoU}*!pPLpp(Ga)nKWl5wN9}UrrB-rv8%68i8Quk%Lrw-Y4uK3JBjm1PS#p}TpU5> z+0z(JLoceW7k8>Ll2nfReE8kuHI!q(S7Pj-uR_9g`Jh>JJ-k4Bkiy{;YA&Q*<)$9v zdi`chzJBe~3aF-4vhU%zBkaI-J&9s#L724tLmMSRNZ;!q6}VcF*4M>)`*!PihOgaM z?~oFJ++JIA`kIS)?`vw$rQj+L&<=s>6i(OeYQ10ccPohc(D|M%)518+K8=mu({Jl! zOg>y1TwTnIZY>L>Z2hzv?~PcMjMbN~&ImSbdt}=B{R1OquwI{&W1-Q5YV}Ncx1Q+v z=#h!wq@!V}qVUL$xi%r_2**6Ke=1XI{_w_fT3`Fi_i|!~pXnKd^QD+=k>hAQrr@fw zl$ynQm9hB}zR9^q!OJ(XwfPx!`t<3&QaCdi3MN!jc-ad~~gD2xut zL#vi=F1n^1zA3Mtk_1wX!AHp;C)ZvpxB!H@ItFNjn7OUJ3$$54rpR` zkN8}CzXVbw%=TxPINy%M&Zvp#d$+CsnI|?F%6meWbXC<&nus*P$f3Tq09djI-uURc7FYH*QyuP92K-(fN+o zcFk4a^H~@qxMRWBi*>h?`OMoCf{<_};FxD0%xADG{u$Rs5~rbYcVS@P>Gv0c%#=#C z7t0@0ourwhCd=cgcDosq_#`F^m%J&Svt$E4(3U6V!kO_>OtDByGNW_X!EYCeT7>V- zz16XowR^&v6qMdOLPKZhV_#jWEi6`zJXmgfA%eFAO@y=$RxyBm((ap_T@Rx<{$hQy zuEDGB)Z%o3@tx$pwPM{p_wjNu=TI+bb$_GNkpJ~I9+t3V=7Z=q&7FI`3(He`YA{@b z-J>-kh^vq3AW3NfLx>(Kp?m^Cx$009sW=2o(GQ#iZs_j33(J5`16b80@^?wi`v&aJ znu9YDmE=-RKNZ_5VGk|H$3*Nine zxfkoF^vUyr`-P?fUiw_xgViJyd@id63bE=RpKV`b7{_+eYOOGcv(n@CjVnky;=r`F z%BhH{u$UOI(XKTOEHG;_?6L1A^9c8*uwAM--7};4-I+hMpXkV}-Fobxhmcx-ZWg~S z;;grviwUO~&N$jE=>he791EMed`)_don150miOakVf`-n_e={t4XQ%$Xl!fY$(!TN z?zUCA#D<#uw`KVqJD_ZP4t(Sum^3P~nr^Qa=?yF``$ng4J;_{3H9Jqlm-?-YMHS!< zammSMHTw;$d#K){l7;!4t%H;3Heo)3&wP4yL!gq6U1x-%4$`nC*o{hxBD(P(CJ(}W z1>0$Yny+~ zg6efLYuKC?KF{DZIU3xpxL;6T*&#YiY_1W{%7skVDqkMS65v$}AN;bodBj#6a@w%v zAZ%Mlf#4e%RM(|$2E&6E^@~dDQ$y~J&n&Z}o!~;?0?X;MvvAXUWIZTBMC#J!NMCQ) zZ00!K&i;LsB@gs%(Lt{UGt+A9L_f9Ah-u-|w%4qYj%;L_`PoS!F00|kpd?{vw0lPBdNRR- zl(;s9o+Ms)(X(Bl`jdAeb044dtQ+{CFD`=8eb{Z>1rQLK{`4PjcUnXjH@-kkbv*m# zpx*K28WNt&(k~waU4Q8@^JLYW=&OH@3syBpMm&}35ZkUojZaFZ2Z8b`QZFP!Os}rQJcX!58nvJa~%-iBOn~HS`qJEzd#@S8O6%Oy*Zn4OT zW%!-9E>>$bk{TNZrIWI7SQ>hXdB1BmJKx*Wx+62G<9l+J+m_ol)&tRUcfliy%KN?1 z@gt`!)_Q09@?+fbV9e~fphp}$E6mK5Hi1V~PGdpMQKKC7P*WDnn(kHP&2 z$4{O4jp?c5gt%sVs#_+gkEx>k25-Yw>dp8IR;E!bAcugpKIn_as0mDc$C*p;gmUlt z?#)(QQ=OqEjR~`P!g3C)Fg>H1!JUxSBU=&E?J{$pXdp(t=y5!Ys-x=h#P@vR_^ zBPUNHE}NafqvqJy&6^1I+g)inCh?Cll2A3`U1=@VTg_6lGnGkUu6h(KZKmFRrEGO0 z*k3ZA>YrpKay?Z);nk0dDWdI91|sJDUaJS}^ZPLt#JjV7GnQMTMZr>|X8JvGoO(W| zi`upN^a2^Njl=x=21ABiTOE%kk3(}9LrAfE_})FxQ+Zd^ZlAdSLTw4BvP6Jfy5+;( zlIZaMJ;y?E`lrsziFCnoNnP=SF-4*_2Cn>PrcY29l))m1BwuZe{cU*0x%bz5|A&QS z-aoelY$AmVM@eJYUpg39Imc`SG;@@~NnFMn4d%0nBDmeGer3nny29?Q=PXAo9jMY< zc-Op#onahx!!YNV6!ur(HZ9JUvZe;TZx39pC(OIkGKAIj^gjKJIdh_rI7{ykSVRfT zNI2X3oXsp+CH|&7AT|`x8$1(8pwe2t;lgs-;?%btVrq7ts~fs~Vs7)DV6(dFWSerj zV^=LJSy!&+yX4pOWJ!vk87~{hPEs@T@m@NirG}eYMe>fRl!dr6w8LK_YaqM+l~U18njUvNoyQ0pN)=xN<8`xBb$T(&$6Yd>;w#Uko>e{g}*`iUu`YxK0=^k}wzhUWhnFM`*G zGyPgB=RbgKJ0Wn9C8Mu*53=$cfaCx;bfXK|doE}LNMz-%TO&0K7Hb7Cd;)$(;y-{b z@ct>s|MqTaOeE#`d!tkk_SaA=lHo-f@Tx9mdE>~n%` zu(Qsu#hz88;jc)c?)!CICIOF91Bhlu+fSDL*V|$#aI6EFUQ7CUKR`Ab1}%U+YGGWD z|BC_v)0e9OsBU1n>o=iYA{qrat^Zl6 zE$og2Rh3_5Q$z#goBME(*ew1XyyUaih7O&F7+**ac0%p_9$_LQ!-^-?|XF!%R5s697tkV+$5Mj0ry2#l8OZO%~j}DT#ec&sl XZkS`eu>Ixy9e%K+{IkNR2Cx1XA^YG8 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/flow.png b/latest/bpg/scalability/images/flow.png new file mode 100644 index 0000000000000000000000000000000000000000..3ebf93d2354298830483bdfa821f3e5cac75c10a GIT binary patch literal 13164 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/hpa-utilization.png b/latest/bpg/scalability/images/hpa-utilization.png new file mode 100644 index 0000000000000000000000000000000000000000..a77801c5c1fd9ee6623d6fd2491f262f40ae7b99 GIT binary patch literal 22953 zcmeFZ2T;>n*Efpbk){IDRHTFSA_z!F=^(vH2We75hY$ipqzNd2&;+E2AiYShK|zFo zfYKopfdGcyArO)q&+)v+^UVG3%r|%L%y(y=%!KSL_S$RhvVLprwf8@<`nu{@C~i^^ z5fNR{)KD=bA|km)M07!g>=J=e`+|&&@NvP<=`ze;Y*^^BTZ)=9U^{0nT+Vt zg-b*vKdTTC6aHNLRlYzd-z56uPdX8i=>?|$DcfA&{ilA6E78SYb({&GKVKSzH-Y=t zCrRFge_G5V{<}8GwLFr)%NJCBvNZ;q&JjMyy*14Jh=?d@f4(meWxl>nL_`d5HGbs( zNavx9gBL*9-qGu^lW-8g`zIHXT#yW*2ypVZXA1&&c>2i%$#eW!LxxcPNfzN?`?HF_ zyFAAu9ep-sFJC7%Nnuf8Q4R$PHa0dnUq@#dLlw1O?1XRf98diHy=6p1fIy%yP+Zu{ z*G1%xw6wH{sF;YDm=K|ckRQm?-#$pl(~tA7M*eO`#mUdX*VWtK)ytFZXS?=~y#oB@ zIXHd_`k&WddiuLM|0BuM?^m}79TfTbACWu4q9Xs(Hi1>{CsoGK$+3)9^7kUlrmw4mrl-G?FM;`&w7x{Wbf4 zQVG+qKp`jcKTAo0!eF6*gNR6pNK@s$anOa$Y|_`vCg*UMt#{Pdw3LEH-Y}Ltduo_^ zt>xL%ryAF24BiWzMii4V2Y&Jks z5(Lj}1D|Gy56xsqJ2}I+u3uy$xOQ_hqn7{*;0XiO2@wDV_}BLLT$xO zXN7(Rd^*Fi&;F(MiaoKr>wK;7LCSDi1|=qF=b+6WW7XufaqaicU3#q~ml&jBc~*HK zfXLnu{qTxO771iH12$S+{%0WUSU5!;S&;MLbF<+3aEG{;w?vMm5l|?=sEOs#vU|zG~ydbLJm}|lToO|$o#;gMWxzo#q z*;UF_2XQ!aySehK0w`Iv5UPRHuF?c*G-@RmQfatrNH*fDXVSSQdJh#E`PX~eMgKK9 zN*5RDV+nRokC{)Ikp_}NUO8H7wW#}s2m-%0raS{t@3Qg@I^dD2Gqk=D?Sjw|xk<8> z`&zuAsU@UWoB9ain1E5&%Z5$l}p4qH+oKUKaiP# zicu!SNZSI}W)V%@#MU>c)F?%boR6#`FVn(q1Nf%~Q%rk9HTR-t%DB@lTc5ALT)Gc! zTv*x)@7*pO;I0bV;NKLq7QlQHq>7XyI;}vN&{x^Waq7T4(-gR-a6C~xS#7=x^hu^p zsgd{pwFYlfS7|&nJ262p?}%#STd?+pA0wiuw{=6RbNiNps3d0)$7@mN31D>#eF_Fs z+TdD_T}qQ{4IOF*Z;+__FPETvi#fubL;co`&*Pb?QXa_LQ_~E$3NY<0Jorb><;TQ1 z(w|SEPf0I?DcZsF`>r-;X*SX=+=+5`p+symKRVNDcmpH7vV}r=`KixB#SddDOpO=s zKQ+7BwyCHIfDHf|tqlV9s&r;W@K=T6JU#CxL5Wg1r$>_X|ZG z@KaCpfG-x6gExZfKW3jo)i7Zq5RXvvq$X?nZlwDGq-Zjc^bT!dHUDA=3tgyQ&CA3G zQ=jQ$xB6D-cS!$PoKhoE* z_t==l2tP8Wv{(_`fQ{FGbCt@&W1;_H!tv80pEKpxd^O$6iduV1=E6&iowJ__4MIBy z%1x%6L9r2knN|w-j)_xS-F-%WY$#&;+T)*nyL2VonS@*_ET2whk4NUg3XpYC7t=$3 zw4~Bicvz5KXvgw2a!`XXrjx#7M!gK}f^l zhGBjfz{@ohu~~z;Q>@=Xsw})Dq9Q%G9pNGLGKnFjMW9UZ7fj_%Tog7$c29Zm=*PPYHNEa|Day%8?=4n}c_LUiYB0_1%l=`0@l$rI+Xlb()!@@*F8vfr4vl05ui5R&a5>)5Kjx4X-!@s=yg z_Jxhav56u%*l^)kFlybBL+h*o8`eAxHIe7F<_9sEX|ar!b4<-hA|Zvf1x4INXCw8L z+MHZj$D7m$63VRo3gg~@HbKybMUxj>ef*S{erZjAp=z+oIt3ePH9tR?oR-u!ymhwb zFsxW$x85tRo5=>?!QhS(N1tTzFN&h=5XVhDl=#oS=O;VsFthLSJ}dXC`p$AZkp|N? zzHR*&14kq^S_yHi-@2|jq_M?$(JxCXY38$@_Llg)!DHuR607kuXFus85uS6)wNj6F z{sd5cMM>VY-(GWY-__dnLP-XO_Z^-Wd1%^tE1Q;ZrSC0raX92#hc&l76Go-yRcVl=n z__0t!6)$xW5+6u+jNsT`Fqm15yC-X=vRlTmtBq*qiK9ByGo49OWtq3d4|75HTXM`S z3uY@%{vNG7T{f%Bxy9-WzZU-&@r#*Pxa49PfRpmAUY6Q>Zf&y5HryxhgH?`=rflx4 z{g{vhe3^g!=tOv=*_w6kI$ZxW31xDnXO?fOt!1J55Qu(+mP6=?3JO^Z%X3D_QT1+z z_f!@BBk*asO7hzFpS}J?;i<37X_VTbMW$ z@zQP{#`6hM^IT3YZrx3_6G`qg`_4`=wP$yvfPMI*>ZFfi685?GTM*H;wVO=bX?#ph zJ(S@%?(eLkl1*e-g8^p#cG0Fx9e4J>T>rVQ-N)#gLuQlP>=*anHcJ9KhY+D-ih!tj z=;}0f?m;zEL=m)dzL2aTN)AXD?nE(h?Athh98mS>9@YfShW1AXp_xkr*0rZ9*SN0` z7m}SwhkAI^Oezn|s@_!mm!J>FT~yjz&yiRg+Y^oFUGXQ-F9LL7Jfgim4e4dNxElwZ zS#8(lLjAiMtOsfgCj+l*1gUlk@Ows#Y$bcdYpZL9Me>D_s(j2S7jbeaCG0K^Qiw=m zbFOhJ{_WrWC@w(ie>fwyDJM-6<;qw$(BG3<-`%abuP8Xo%4a3JHJV=U3}uh1*==Yy z9B$f-qMxvFJYsvS>`ID`=J4chUhpa9;0Ja(Sh830I4R$-B0HeGaOv9lvm~v*UF55m z7qK>7Ox;Hvd=mmh4Pb)e$E~O9A3xC{Y=vhY?tSQDFeTYgG@LfIu=UMR+vl;30I53O zL30`gz2GkZvC&M|rDF%z$F5Pan5H%)dAMt{C<*eNo8RR5!w(EdF4e_N1T=qn)wx;e zVe?$^Pq-Bb=N$D`TnAZoU9F4r>Q$ru%Ma*tdMAaLze#m}uen#qi+jcq7S=qZwky2a zllK6lyxb@xD1STZ#M$!^^A3--{PibkJfE7Az4k+eKTT~Cyvi!7ky$88jwR?Msfc<` zD-7ui>yHj9(KC7zl(?mfer!@j29GZe=z2CLRdJxJlB707g|4oyES09 z!%x>`aO~$+dz9wyn>{B2az>lJ+*ox#=&+>`26`k>uVp-nl#d@VVbT-XJN$%c6g$gb zjkoitSR68WH?L`b`^N)}5G04{PiqSYWj)=ddZXO_IP&o;te%SN0!v%mVkLA@d5V#) zF`Lfg3dl3nSz~ZN(_ei7c#>>bO^eD9jB2sMQ{{VK*D$6#mPQZo4mim@+6kNdtktM# zRG^=0CNHP)d|+XZJHIZ=%4`i#1u`;rg{75G^BESV4KFx~^|6s@dK`9>(P3fTC?JlL`k=9pZWxIBx!m{zSiD6dq;}{HfXpL3Z!7hQ*Ih4_l*!PIrqE z$A1KW<}8=HHOe(_OW*h!b<81CP+w@P_S!1a@*SF}8BqI99s-id0w^%&pQp zoA=x=1bZE3#&ByjuxFfKVKCy?LjLI^H-=GK6lN#XkL6P2L#czFyVLT5lHTTWE~pr>QmV2upPpry+nam z_63k?>h5!DhrSO|T@J)Eq z8iP8oE4!OY(KzBj`*;ev-u1(MWxX1pea%;Omnpbxnl}9fAN(OeiUY|B#O_W!4nu zyiz5P$zKU!6&5>5;*DuPU7#FGQa!P04t-xk66;cz^wo2Fn*t^h#y-fnW(Vw}T?8i1 z3ld{Hkk=c_zTrc1%3L58SFUGvi_ih)lV5Ge zcZT^h5imXY{`bqNu5uYnU9Eh2A)ONMWJ4nEK6G=QHz?Tu#3(Rv97uzIKEoGJSIgW~e@@Bxps||~OYL>+t=?zRZDxe|6@kCX_`pa+FZ!re+IY z8!9hdTNjuoF_@cJ#={PbX&7z4_V8}$!H$uP6C_-gWhZX@kY9!%PJ7apA7U$KB%?-g zTz&$7`vaT9G<*~o`9?K~9_D$PI#q@^gaNzKxxO6qgkr$~5u1^dv(QY8#TDNid1tt1!og z$58KnRnw}6FyzOK_@{nVbE<}C05-kiZ7elk zehJb zUr61c&W-Duy!8jwFEWh3`0%U6#6s$=Fvz)59W#iJm|h-6iI|qdr2;rpfb6K9O8fU*OuCFe|cAvT6gRwg8IrITF=hG9CqqWjC zZJJMBj|xizfCwmqPRiAk)2=oMK9)c3+~BSa*=0dOv`W&SKK(bmzB;_v$^Vp9`=(I6 z=GG(#|q`YQW z71@hqY<}IQCRz<0h`xYmcH)LL*)JA{nk?S9>+Z>hOK&{WcWr2xm^b4lDs$y6F-XQ#xcS$PTRKyZoC1<`y zPpr5y%G*K5+)?%YV-#zs+n3dyF2k~^^KCjO&m^WVP~~RMts1CC7*}5yB(Onb<$~su zdE1uaUXr}TstoXb`}UhWqaG4 z64RA&JF7Oz3RHrXNo{LizhHe21z`Kzqlxw|QFzM&5OP&33|k_yLZ9#tcGy60<4{|9 zlTY0wv3KIml2M`A{LE}qzoX*MRZ0{Niu{0`9?~fk%eAxC#9*(FYLrwp6!5>Qs!Bbm z!3Og;Mxz)9TE#mk7sCzS*2j5$QNRAX#(&SmZ&B5Mi+?%G|HU}i4RR*tNGvUT47xK2 z{ft9I?~&aSbKLd!u1hhMhq<)wEB+`Ub}c*W7PcnuT;Y?8Cuuu z*bJ`GP5ll)MBy?7s}5i|`8N?p;7_@zD*3Mzah~pP357q`1;JMHxCs2*_mi&tYrczV z38GxWss2Ue)gO1~htN$HU!`TD8r03a{8T9&>xfp*g%#Z5d%WsIdL{yE{1)0)( zXSr9VQOis~kU;7mX!%6?*eRcs$=m-jP-%j`5m=((kl*|E%U;30mcgx8c^M4M_WmDoAl780a&tSFYp(5@9a0weg^U+}4~3`dAst zkbg~rk|tr>p!JM{>38XD`aFc_evp{;-$WPzv0!<qcx(Qh(+(hrS`*y)H<6pb&r2TX@o%lN38Mb1>VHS|->c%kYxTco_5UBRQr22o z7ek5(Q0cUOQR4UuO6`QX2~P2tlp(NsT|Rt|8KKaN5~gFo|7Km;QL+L=}STj|8La&S3K~WZvQR*J|%xgLH{`D z-+c9di~o-y?*Go1*?Cj<)_Az1-+laMVL?tvvkzSK7izJXcJiE4Kl&AVivA#vybw7v zbLsr*dlEtdGmj@P{+o6;H(Iy(GVi5x8Yj{}*R-83d*YG0vcKP)#o@yg1ws3t^SRxu^aJH>5C>PL!*K;^&GUoj?T zQPPkq35BG-a?CQKqT77-p-t6}cC(W8c(alIG|W7StmgxxE`~=7qiV#N6INk+`1q&9 zU=^i_!gOOhpV-vrEJ>VxUSxOYNWn&=PCu3W!a*Dg7dcvwi~M{=O4HJPwJ`}N8P8UI z<0ooa)9gg~mRIUzX~_+a((?`fr={8*(d_g^`X{F#H{8iBqX~1M&z%=f!^*nQ^Vj~7 z`nupn|D~(jT9?yqkLVJDWnu2Tb(&n|Ty3aO>mUC$@c*L>+^(8NW9++0VMW0ot*%&N zt@#HQ*1pZA4F%Vt>$NswPB6wj)58>oW}81^bO!eL(}o$UQn%6?pbcT+Si;>Ob)O>^ zVR^1>?g2N3T0i8p^>5dZ@;b-`-%xb$v~vW|-Q;Zic4YX;-O#ibRF%$<`q)w^j*@Sv$mU_${z&jHHDZ`SKqyoy8e8fUAepZzu;B%0sNN<-r4WYRwZZfS&AfoAxw zpx>VrFLn{->EO;RP<|PDnvz2W9Rku@7hK&I@UR&>aR1VQreU#SLBMkGAB)a>o(>z3 zx4dnpjG)($mO7uLiNV}L{UI5Hw)Qd=*T%aA-S?@u9xyZZkVoO$c;#6%tSml(m)RRq z>4PkSwPi%Lo=7C#vjNFH+1FCld!=RqL|f~X*yBG-qHg^FNO>f%{pp6kytx=%W^J1k zCRm|g_bnL=*L#Fy@CnRZehDKTm6dIj&y!VKrv4#9Tve9;bvNE+i;46a6$9q=>Ih7B zc!J(X7|(}bkijSTxrAA}LJ-+zJ@R}e1_En-^y9@W&`Y zXqvR>L$xh*T68IR0_76DNo7CT3PGwRP~^MzMAQ>BLo0ZNzSamVZTt?sFCgp-A^?-` ziq!Qzxq{fXNU2v%^{JtouJ>a6gOD8VHh_1dat%fo)N7s%B!qtoo<0%bu1W~X4e=9q z=nn~XAYbT0QH>MEB+I5((GW+awm{9=n#D-JC477heFx3#n(1GQx?oW)f}p(w@mz0* zt;-nHNO-p1%;FO0_e(lRImq$vIN)?u;A=>x_YR#KG#!>0h7_)H54pAL5t82*$PS{P zZj&Y#cyB+S9m%KY;(GKtOgqJMI~6tpSy7_$Fj;QbiCa%Nw-sEA+qU)z-cc+FiKhcK zzF3Rj_EYs$up?h?pi0u2nVZ3z8q32KELmZXk*49*v$+i96_>6J?0pV6jKOo6EC$-l z=}(nU26o*he_*$B&6`K)_2jP7VjeH9IC>V`t^sa-4s`h%(4;(R`e_RDjBZWADhzmu z`RGLg;2Ek~HmPBqI|dq%M|xzx93Z_O?%CJPxO76ie)T9N|0?iRSJ=VIgXzi09Gg)n z?=;O3Um(yplhlcQi}BlMiz{57FZVlOK;=}(ua@!fZsY9d(xb=-GEY4Dmy#Dhv}@YsQH zu}6(&PNj0dhZ$C7q^<2#k^cgy{pQN%-aJ<}douu@`!d~Qw|$*FYL=m@pp7qT&!x|6 z9W7sE;kMENF*Pm*XGfz<^6M<~>$2aTyf+Bh@nnN;J1ECLHzgtGky;UoJIL}Ya@)gU zuHT(j@@n+~M}jr&G(`FhJie0$HA_vpe>7^U>SGoHNls?Ny%!Gt7+~zQ8)W=)IIDkg zJbgX>tqX{79g9gzR)gh5P?{YjA|gYzP_}@U8@Q7-^@?{7*K0ezKK8syGfa5+sG4qD zokf}wf0DnF^=Tp=0Oy^MVn8Mj#~mGfY=bC1?*qq9_jIi=p~ML{Be#;)+u*Um)lKaO z(g;b@7Q?-btn)1GhWLV>!qr<(>^t^PzL~lK3SJVbd(>!{LL5e zPpy!*hXKu17}j+6FYEVvItOZbs`zn>902iVOYMHmt)ezz%$$ERD!hvrwr-=Lp|;>yn>7_H>kC)ZP?)=ZafO0- z!c`<>_z^CNRQ7%jHN@_@pp~t^@^oL)JmbV zR8canvC#*qtpW=5IUblevgaH10kasL?{9M`%oQ2LQFcHz4Q&2A0q(mtseYqNV)dl> zt3HN@(KUy9SHew;X6`}d<{gC7ar$QsaSBY>B<((z))VER$PyFG$sGN>dRr;Y^!mDE z)@T-3w|4XB0C!xWLRUKsKW%aVpP@2byq0buc+y?cW=jP(rb;H__#~#| z4I=dpa$bpaew<5n$@g!#TQ!+6{cRvF`#fW2UQKq(VaFUDF|U#X%-CS=KKb1I^&y|i&rKAsx?MAG*0#e(In7;I9jq<|1&$=W zx~>J*%z0?8TGQ-sb_Fp}LCFQAR^$RTOdmHYYFZD-K@EaMfzx0IIB?LGF2u01>TPYm z=eOw4TpRe44-vk$sW_9!v$dHw6t`7V%Q^9nRZk#MNcQ6^XnQm};`omE9@ljEFe5kN zco5~_I4f!PJZO>(Wz=1F|4IBU< z3`z_?OnOQsD(Q0Vx!!n_-xlrd*G(+9PV(2=wy-bLqO}rgg=_-$I^HN0oy){E9@8Nh z-KlQoq=kHJ$QH)zX2cG=!IrYFaE0t%KEi$HTL^YuxQNI$Z``KgvwDFV7>J0s(?%>& z8dVoYsC!PX@|Lau%HO8x2lb7QJgTf(a4`NDrpj&Bdv0O;2HGPrte)S5+c`a^*%`d zydo8pV!Qyv_0Z$imxT>aB9@jgg&cM(>6$F4DDb|+o|nKMNcJF(i3mz66%V*=1uv*I zH*p5|9whqhUZN<}OUB?x0PWXYb^5##%08}6oT`vkbn=1b1ZaF{ngj{OFba0E>v_lU zDZCiZ=6-RsNd?+~0yO`)D$EhmIrZS&%QynF|MEy!KawdshW^gm=T_=l7hc}5h?Ea% zQrU}z#L#)N?2Uh6d}RmM_}l=dJ269f9VoD@zb51#wf`p-LX|p z<;<_H0Mp?a5LRiRs44cfGY5G`%SFlq6Os>arI;k8&f!MEfv~o^AIlef0Vno@v`FG16P9` z&*rM1qnz0RI4m7OdtEQTw->9+ckwjpLtm=*`<1ig``q@jyCi#~~x^(ZWutOT2_>Q+H-vg%Ohhebwvv>Zf{^fKVM}#xhpT}fM z7jxp*LTyovQjxZ)5Ur%ZBrAbeW+a~(!q&*6njb^XuQWW_QSqEqRL3Zc_O+B2c`#S3Z2_>I{6Q520BYFg zY0jngpaoT?g@l}rESg-MkB?|)A8H-e;2WeJ_F)&Dpl#9x|A>ULJao5KxRIx;eEA^ zzjJ-E6@=V4s}+k98?d5!6heaTQz%fWePXKc3FLjvQvBT+Z`V~r-u?LE565qVidbz5 zW^Z<%afF1>T|NA?<&pw-P3e(J26M4O6Sr?-B3`EQd?Gzg;&|_aOi(D$#OV(*I?*i3%;jo}h8PO$ zcL&QO7?0C$iZ#D(TuAVqfk%4?MSumCRb17SuTC5axJn@yUsY~6bBC!=FlOGXBGs1F zn&?T|gQ%S*(@k$I?X)<~eSDDFmGg!IQ-okO10>DEF~ znydAT-@SPH0h-=2I1$X0FYm)wDnb(GaDXKNmj^L=8??lH#Sy3q}V zF7Ezz9B}yoack*-h~}H631Pg%aHpX-Q>g|pFdI@7eOXpu<7&l7+q2M0W9Lpp8BL?6 zPt0`oZV?yNU5}gqDuAGPqIbq7H*it8`MW}C6I9FTOS13Q0k}{)rE&fItPmAjrslVb z0U|JOH4wLy>Q*~NdHN;_VK{c3n{zovlL835=Yu_&iSYSla(PiKL zU@qjrR}!l2_z|qEXzgc!K&dm!!#2KdBt&W9rJJ-271v@oYW1z}WiAf8(A}enhd#E` zO6Gr`u&e-x1ze9A(`S;hXVmGmOWS0#Sgs#@>MX4^Tgpv4old9*R6TavQ z0V&nR)s>@k@wCHWfG^Va?>tR9LRj zlmxAf4r~L?)jz1&lM@!UdM)&_Q|im)yR*_&+yl6gp6R{CDTyT!e{AKyfv;$6KPzO!l=*h&R*{Z17B|WUv-|6 zze%)qeO#zD5PPE(-4&OSxfQZDeMo2R+E#&4hZsfl?8>YNpwi#Gd0XT%q1$9xBE_?5 z1j*P6-r`C}ROakV6~IEch3AKJxxw#RU!U4Jv`hzAR5F$=?=nx_M^BD;Qi5vwsmuj# zNTMj}CB_c7Z*2Ai>aN4oYyIlSKof#qlR=8jZtJ|vt@fIGN8s#B4z+g3^Eygnl5lgi zJhA?UPtk0mjMsWAPY+HJU;E|*_U8;*)2TT2W*;UWqZL}(Q|47xvDSL&225t?g1fUC zXNQ_-l>zVhw;#W?_~F7-gdWPuk(F9x%G0zp)rKn-iaoI0#Gdtap`B&auj)i!1&Ou> z&NS4%aUy9%&`<(WU$}t>40~E-@-}_lze&G(cjjmYov$!D5;V89zw^a(i*EZv@3)Sz z@82K2A7#sTR$fM0F`s&IrDAZet^Io+gR}}A>Sk{D6rd(%9{l+A+Q{ zew1x;Imxf7wIAJ~H|-K4itY{6v&mHOyy~^tHbQuy&>(wZ8{PE!_HpXto*1{~)kZ)1 zNUat%07OjQdEBV1K(W7awnSAOZj*6|&*sWY$h_3rv|st)eC;QoR*tyNxQ5!5cH!2= z5lXI2go9RV+dD3dmoakx@ML4r(f8<~d<7I<8FYZM+SHtzla!_vvCQ;W@T`4|YzK%h zvx#Prjk@T&7?Dg0Uc4j`e%Epcm^C8@fvG z80Vzpc1N|q1XJ+U{w|~B+}m9+>$;blbrmM{*|M;L^9}!WanHe#tn=ozuehZZ0U{y> zp`X76pi{R=vR}|04cFVsz$iUIJwTQwWYf*5ogHP$SOZJ_0<2q*t`K)q9pxFZOg>y; zpX+V;{**xQo^H>logZ3(hq%m_o4D&~0QC%q5|j4>$y&(OfRJ(8^oiv-9gxwgud96K zaX_l2?Q(kJS<}hPYq|8-DPb$4=t{oU$1}m9G7LU`!>Dlo)sY0mdb=|gF+HcakGgv! z+1mdHheR4qzF=x%FR&1u-?v|oFeZI^#rj%lKkNM)&0jytu(a}f@?{H9aWgYBasg7` zgL00Jw6UHKcb|;i2U(?Am&sH%D7HGkUaKlk=~Y%(N1>nWz^Ix+`s_eCF(%g&G6x8I37Ee%F@J3u~;?o9FlQbT)&I1PIP5TjUqJ z*Cikk%@DPidD*omZSUwX{s~_e_jx_8GZNQk5N>%)g%C|**?7Ju#LId&Xo=Y{C$GW~ zUe;eXLZ2;u%TwgXi`BPR7O>pCmE>{v{!l&e7pC}VB`-6#M&GK> zYw(F(n=fOq*DLK|QoAy1lwDarTFD|WzI`>_vw*QUEn;70#NWLcqx4|N1FxG3;eb}% z4z|oHsr5}{F}jhy6>{1fyc^=m9omq|Gpn^V)!YGV60bMjVwL>Fj2JNvWNIF3a}92f z7CzjmMu}@pP`G6>Ce@}r-A>Pje7J_@5eaI&IknSxdKp*`*V+RY=48CMx#`jc8RaWt zRdnx{G?6W4_KySSvSGAPXR5ShT_O$7K%TS3IHyXQ~U>_TpBAqs6vJ_~_b0~K1 zIb(1+=u30TGV?}5TnitVe)0O_;XAx1U*glx^4wjEo-@V5LgW zWf2uPhMEHt%zk)em@*40OleOa^WZ!n?22fM0u=U!Glr{60LbrtDD~P;TS8QqN~^}6 zsyKVKC8uS1bznRW4_(9}MO<9>HaB48s|DcPn-w=zRFTtC8l$xX4mBHv1$$Vk{85#N zrPfdDa^1|CJ!UmJ%PYwjec%@kZ4Y*}8s##x%PMY;30AQ}wP8^fbRdJ>pKHi1uexLU zG&@)x4a>!+Sy2wSGF?!@NmfI#Ey=S~u> z=)pD0HOJf(>)`K;Z{|Wwg>`fdii#ATYrxd~DO)r_EShs*2esiOc*%`^Jl|Gevx~;6 ztK{Zv+tsQ|g7V7QtK;tm&)^0{YtpHT=FND6lt;Q{+0ZvMx?6IU<68S8fMgm*BCE91w$rpOg{ZjPHOCkAbTt?YefWi328VjIbCx)h3Jy1Y(ur?;SE zrc|ceI@3s8ndHf?63{L}-r{9{C+7O1Wz$r>YG<({d?Q9k%r*IR=fSL}9uT)Q8eF~8 zz3OFpIn%lC?o%2l_T#DrE69HYE_eohf5mIH>PmBfPHO5sDU&1D`|a}liuI;mu{;% zuKkENEW53YEM@M$dkDTN-}rDyKPFiIQB5J@LVaA##)f11h(fm2!EO?wIO_0OEvYfO z6M{2Wc41p;?JVyr2*86lP9Hh5YN||Zl!mH}4 zx%3J$_gPu z%FB&;)4j-HC`5~-U1aSMHvgviu1|vV6Z*CF_Znjv%rcIK^|(c^fJD(dR4*UdG1m)V zP4Vw~43GTV5?Z0i3mC6;m{0$Y6F`Nx&8Kb4AN}`f_d+Hf-ZR)@EG2J0v5XEaJ-+m~a(Z91E0~HE%)|eSLvP6|yC){rcUFGW)g5K@4y=^F5E``zkr_R<|3?)VCVfB4=(N zs|BP5l69l10#@C9-t!E69(@Kt9F{u7U812HTZBb3lD>_sY&So27a4mvX5K7V;U$2m zH0!FtzAq7MmnbbG#7YcT5oO-BDQoO7}}|; zr?cs9HXCepyYbER*OK5%=b!-(NNbDM*RGqgGHug_^>@wrf?8#x3#Sd%9tD=)YT&yK zjUEDzFShJoj!m#nlV7>7VpG7`UTJz)JI!ma(<>LMT7kVR5vFls0Vyab=tIunw)?FqpUZ# zW-eobQG*7n22cxK=YM`4U?qSUm(T*=ghQP>(o9H~cqCYIGFab#JzD!AXcezrv$}?B z(W|wNDXsO+KDg2CDQqTge>ybUXOZ@z)Tu&YOU%l?%+1^|H{-I8(~MRT-ZuZoCw1F5 zh~XzkvXoG%<_MEImzEA{qfLKqG{abiBcO>>Ru|%e(kXVdO|`UU2ZWUK4Sm&v%z^et z*7C9+xkD94)`y%uWmckXJnV6w#R{SJz@Jb$(%1Xs%xerg65}KRnaKIW4H1Txn>^sF zx>%K9&yBt=KN2=R3|>aCd7zw` z^6-jpp%WA1fLxtbgY`>E#Npw(gUWh&xcSjG%WjphY6uFs;wKvUH@*F$pXmwa= zi=YuMk7}{1pWR~1kFegM&b2TAok^n)YG}Wp^>u~Giye<9GtS|{eYwr4v9B`8L00n?faUZ4EfdYB(`j&O)7pm9GYOfGZr=vvQnyT3w5rY8 zr(-M+SS2bm>KeD-eOKJmStdE@yDtuqtbnU17=oW5*(i>d-9sd{nijPSgpjK(Q) zsU;ja$V-ek$O!OL_l!BOx@QEhmMBh}gxbrOa?iH1^s-c(aoXyE{96W959#JY6a_GD z4gu7eXl=KbP*|#*lg~3sWpDSL8W~ws~d62Lfg0YE~&w zpq{z*q#{OLx4FAkEe#^#FZIuvMpGZ#kNM@v^sJUR1XSfWB4~#Xz;698P55Tqbb3XG z;Owqm;p}ya27dv>y@AqGN@;iAAr=_2oc}-vlU|hj`mDV}GoPN;+!WKsvi>8n=hou= zsD0y#Q*v`foQcFh-MiM@-N?Rk9h$?0GMR+af^~6rOGwM<+SpgeDeUrsOLAZ+Kp?{> zI-!4S`tvj_NB{_0)a-LZgI4YuFX5m?Wz7+6As`a$>Yp&&5#W95n!3|?hND|=3Lhvy|N)k(s* zv~MoFr7j+O8xpxT3>HCXyWs=BVUl>(zf~Qln4Z+m9-hH9LE~c>sds6O740oBgGIT% zN*UvBY`z~(c9;iRJ5mp;0l~xX;+b8=l*-5tOInl@+&eOJ;IwCfSm^1S})nqu8hFqBK$a94Fz1}u{yx0LC8cyLd6%xT*EBdLFcfML`^vV11_Jsr!J4IzQK3FS$RzE` zr35%42r&=`q;b_b2XcxsJ4{eHJT4mgu;x>;y+%_~1VfL6RJc8^J(hDDX3J+2)&7|y zDQudWoKaV*ed;cR_}8t`0Q>i)cd6|EvJsbVDK7iOH_7>SH+b~)>s^H$GW2Gc**OUmKBv~gfgOhYTH z#!2^&y1k_8@R`FRZe()Ai1OgLorWaf6neOLaBr;nRl^d~$?o2&CMH*~RV5-Tn5WL+ zvy-M%FZto+?*FTrJMBt3fx-aZI(258%xN>+nkK{+Q?ndXsm5JPO$|*=$r&qA0e4&w zvYISUfk|SbppFYJAi0+twipN3P!ZFU8wyIAiin}ef9&+8`3Um??)!VsbAJ!r%k(8e zTAP4X?qei`vA@{6!OfjgTsuFtv#`9W9(W){Dl!Du{WdZ|@f#eSjgJ|^m89jC&TQQG z2+jkZItFth<^<{rL~I^$z9G2BfnP_Awbi~dUL?|-T z_rp~4;?geQ#a8BMNhkb+b8kl!UP*6eHVAKY7c`M*x&el|>jZ5cZM^|Bnx9eI?*5X! z8r)lKkq!5b!}ZEawK$`}U2~axZj}C$aEm8Gn%hbJIX&>9Fn-!#y?_G=`P|-uDZ_ZcIt#Fv%5<}>^|bEx^P{-I~W&8fg%IT zcWd6;reu5HLU;FvP17>M&Z#?Pmzl@vDto!*&+`(d(h( z66~4E8u^TyFrMW^$SUyYvKGvJ3~E=KD+o|lB$2Df!c;z-e946xL3RBC;&$OvjI=+b z5zV8t2EgR0hEZx4YYH|x2^BRDho+6dn9Jp4J(7X;MD|MzO=V+;hs~j^RBj<-FZ{m{ zw_EO;<5xbA5DD-GLA+5YtQA?}OVK4I(gdl#WSyeeeH>%$<3LN5vYzxAC;G{G)N?$s z29Q8R#eWqf``<-`OY^F7n87`#cl4nx*Zg;GtKYjum^4GKp)z=R#dSz3Yt>Du%rMK+ zWiHl^i=A05Q4`5NWVuZHQcWa1!xk_aJM$@;AqD(IQ!{!ibs54ZB~bnrpUCQ=MR(Sw zfso*-qZKC1bQ^3-SLr;W>J>3yK+bmbGVjZrO`jPa(ARz13nspc;w${FiThv8V*^s` zYh%ls+H)M0rSNEr*V%^unMUI@}bq9H4}tI-xFlIMbunMO#XEYFUVzr;*K ze_EE~+o&lmf^)`arlTmw5#$IBz6vG%>_^N1+3t1W>X%L0=lX)PMpRxS8mQj4y`1N^ zmhIXdO)gplxM`Nja+`8JSsy7mb`1C#-6YXm&fb4{N4N)(y@?N-N^ z6JYc^(eeIc-=hal1&s#{^*dx&va0-j#4EZ}dLO_rr%@Ju*f)qg@1nDhAK}AHG2#9o%CMDF+ z6BMON?+Fl;P6#ywNJ#j?nVEBDyl1X+|NrtN&)ar+_u6Z(y~=MT?3TXf(ZgpCGchq8 z)z(tK&BSytjERYvm+c_qj%b#qA>**m0 z`J)|mdkNHgPsy8ESXii@FS_sKIOBKBQRU#tlhUH;XH< z(~6#RIWxU==4VBZF*kEE%3c$YKl1n(+fTk_k5z)z9U3n-H~+Ngv1^fxvd#Ni@BMt# z$wyg^pI6|~kXL^8GXgznc(_-VLyJRAfaUuC{+$@VX>D(B|3+C}e&oW13)qDPr~J}M z_|51!UqN|}pA3~Tz_Lesqx~q*{N*2vHg#{bT&)lP!DtWcjez~2yyQO^?do3HRISK= zFj{eeXn`Ix>6V9=e?}MqmPips*;RFS-k-CF!@kEXVV%LMk>US<@01v2BSl_K{sV%s zvz^!SJaxp~;vewcFQA|v%BH%WzVr^NsVHG+E z#K-9QTo9T52W_D^ugweetgWr#?^VdE*doSiybw8b9gwNmvN~K$;0}(f!T|nrsw5Lx z^cA$u3m87;#Z^$#Qy1dYPd*V<96b2^!=elS=obIadB#U$;(ds^p&?}P?!I@5hVG(m zQGn}(M~{zjk&_Se3tjm+z4cE%meTM?s~?SxjV)xp;!|$4JN=&PfPZ{^d}P=V3Oj^y zQ5d|a_;ac-56xA zcK1>*YT0ES=R+A^9Y6)&aM3>e^M;O9*)ogpoj?AvR6`_FSJ*4r zV9@k)rkKgYOfd$7-@ku%RI?f|N#dH<`X?+{$fEBr+!OZb5L=k;A+qU#JNtO^g9?<7 z?^NfP%l2kjZXi$UvU2dA5ldhR6Mb}t^D;5+pY5-g9~+`xs~gj_th7Z22y;yz zQ+7mJ49ym%LmVAlT~SLFHCk?t&_@?l-*NTm{gem|Bl;7s4}?A15UpD80%I)Q zJ{}Mn&eUbnOrKTPu04G0fmreTw1!xdL8Du_DC|v&u+}fPrZ7L3yH$qFIg4^(3zeb3 zjaaxk>^t(`Xs{=3e&ns^He2uxGxUSi&3g$nT zg<|`QY8F0x+_L4T4znFEG_Q26(^yiUAozr{ylyFdp>>M)_>t0+0v`kz6z;*&xaPJ0 zN{LZ9HeO3J1b$`OuFjN*KTFuQ>sv@ze|4bdlCl}Cetpj0Ao5!)HmJ0rPwKDCI-x7D zGOcuIEQ^LiL7j&zJoEzAlklTKyPF6MoW7n0JGsUAxujR?k!H76{DRN(Me`eW2YNn+ zu;L!?XN|0X7kLB&y#wVn*}ZG|TA-&PcK6TPMdw-OlNQDGlYvt$HW>aiR}T*Y6~1{B zS8DH!!J|Im>$h#pF+pm(w}-ybpNi*in`4?&o%;H&WV(2J7q!O5E{)}AjC}pNco7$X zOFidfeM8#T>$%D;F71>KX*Oe$y$ z1#FNtv7bH#Zrb*B>*dt+)|QtKZ$QtGi+$|v{a${QpLGE*=s4IW&ovzKm^2(6E-rS< zB@RCvFIjB_!k|Rkq9_^K>yfkgj-*PG6bb4Y;DeX7^IiI$G<%V{Mk0A`!am?IO6c_2 z?T*#aQHz9un$gD0&N5R_TEvT;(|_Gs+@iR0&xF0vo>si#G&V}n1AmA~q8`TfFC;4x z?o1DKg#@!6q`f}0q9x_u6HeLRGUMHI<8%d_O0F2I^@;K(3?caezzv1!3Jn=6l)n~P zx>VNpPG{WFkslPVJJxfZ+Fv_6$&Z=>aTvsI3I2!|KVqqR7R4@A=jK_rv(~Oz52jGx z#jB_uIOL7@cLrQsbd+1d4#>KUUR$CbI9wFiqSlnqD2d+s{t#mj>TS36DPi{U@-BTD z))hE&1$P>~@^sZ=qWWXmqn$^rO4cl*u63(TuI-VM0fx9T2N({%E&+eop$<3&J=4Wa z-Q+*B@31U*BhLT|3!LP^`2;rmls7BQln{HOg6`ld5zAXP*hYT(N>h~On10vA%5nGh zVjsd_A*kgS#Z)P2f!Q`Oqzj%>h*ua7TG512GrjL2T&r`btBD4P8q4lPU*Jfs4-7Ep z!s{L2dTu`#N(_8fz>IHS9;lM&YEDg<-jU45-_GK%3>!aXATFIj%_bmW3Cp7+t~K-7 zz^`WD;9u+{#l??|4EKp#!ep(Fj5ic3CnZGBty`j{kVL#>97=m(1c-?BQz(t;0 zmT$juuAV&K14#+8Th|6dx2$;&yl(3}r?mTnSu{GyGTJu;_y2Nd6jR&0EVo9}2{Dfx z@olq`n?3hL5D*S*QKs}njnh}kWPtjhN7B8G>_TE1lfjp@;nPm4d; zTBE}IAZUfzWDl%i>e_2gYtGS?M-$2x=_)kg1Phs90DesZFT=b)m>E|IgAHv|GA9r1 z=V#`M@+D>BXiGjA&XwwHjQoU08g-N{-lA{6n0Za$W3J5=Ieg$c+j;4><=6gw4N|mT zsS2Ebw;dcd={FI~F6oF2+Q_ffGk{9@eq_fUl^d027F>`dJ_c^mT)572@B09}==Y5s zaxGXt61n_1o)x_H(ULBN%TeBFB{Sr5C2h)pPVgSFPpHsTUW*ZWJC-@CDm~FGngB& z57?!w=$))cGBr~t)6q@~b?colMgRDMaZa{I+Mu~lC3~%<@wVqfsJo5j=0khZX(pLd zGVx8%C6&&L4+}U7m1G1fR*re&=9=$MGe5evU7G439+casf2^Yn3!x1_B4mv%xnbm< zjCzR?msOVwLm|RE{fS^QH1^NplySZUXVEu{ZrT6Ee0(i_m58nYgrQ^Z8^yrN{NCiU zzVIJjJ$9b@>}@#;y<%*}=fLxWWEf)E$$;Ftacj0~cc&|=@R%RAFIAR4yey}V-$ZXl zG;|z=e=#`lfQ4geC`6K(J(wjJjG+@S%IN-$0mgd@MGG)Zh2LA+7^AY+^yBvPvft5K zT9w=MHpY(jnrtzaY}y0q8|)lmwK>F=>rqi#(VBN3|1!2SChAaEywGyrGDm+gnmfv zV45llI;L!_EAiE5gr~Bc;4^lOS0nr(FUw@K zkF~X(N15BJ4HZd^O7FPUU8@+Cg()o5K75n>#;MkS1*!%h-UewJ=NN%4&Ser7^(u`242XwN@_Eb6+uMaBurZJN|u_L>|yG_zBS*j&~~SEUWX$A%(8 zU+_~)_<4}gbdlYuw3jOC2M`725AnNQyW3#?eB-)>juInTB%J7so259N%TECIhp47< zj&2U+&q)%Yw8;6agmGBGVSiF4{}n6Y*=iN0wikT)wk&!<6RbhjEQP~4y9Ts=g9sz7 zW#4ASxA=3E6#RCIEI#Bqe!~*!3J9FopCpyfr{GydTkN9a8%;2V=h-}V(e4LB5vx-4 z8?{BO+AQHLzG!MKCV)lNZTl^9`)$T@mK1!xM5@Lwl~cFmlV-zVO|e|`Yydik^@HSm zkVKS2vPb9k7hr>*aR7|~0b|(;*wktC<=r6a@-7Vnfb8~wDIYmWoNgaxGoC)(CS&MB zyJu1CAL`drmKTxT)c)virVTSuyIWDsA!A)TU%Ork#5BB7iEro>gKW25RtE2`gTcWM znuf0o`M`&KD)4k79%u^{U!{5?t_m#q))5To@1cvz$O7@r8i^1+P(C-SZIc0|)l>JG zgA(!Otm&mVhbrV~>sjr;*aU8859y|gT5d$B0R*gszEuI$K`#EeuR$mLwALSGM8E++ zbRkOilW<#wY?^4TklbJN_N8zZ7O^_XuW%H2q4xA?ixtfvdw_q7nuf|}Cjrd*-coVc z3F_HI>~2OeH4>~gYgV1g5->Z{lUrqJG?xH-fUaqW(DQE{`(VC}Ja6N))3!c~Xh>^} zxj@DQp9>wczZ#CeV#CT)cUDi{oaH==APZziwg*7#22{+FjTDT}9NN-C>@ohw$g zYapdNG*aqa&pqMW<|&Q|%XJ9Fa<{78XT7Jfq<-Ci1w-_Q6vX%esH-=;mcrfTf`oSv zu%XIZ-%!$sTw--0Ccbc&G~aYI2|JxYbOF;R!Q)mNA54w{UF^Cx;rPvnN5{+$)Uo&} zueTa-Bn`ALY^{(hG4=JUtaKzg+qsms0-$M`gDW%YNy1XjQvTnxvi;-hiU-NlZOo#!PlfHg|61Y(GN!Ss#c| zSpU4teF&APgVkOXl)Chn3A;Wqu08RZb|Hq96{9`%xG5jNi`#U&hq1C1xcL67+ySBv z@TREWgjrI4AT&v|UG|5{k%y{sya7vcPNPxmZdExb(WVk3F-27fNVj?s* zQQ;aa9lSqS$?6=`+2|1W(j3X1da!lh16LBS`3&$yhtR)W;WAC@8FDlrKL-ezSqZrf@&6p?}(9i?!p zlzh-SHZ$>YyX2FjySpW#a4deQxv+zZfTKfG^0ET~KP800Uf^{pz!+X2L zwhCTTM$%{_oa!~%yOOc1A_lkEZ82h=RshPxS0vD$M|XbB>63%fBzH*JfL@^7OqI2y zfcIpPCDa3Q&(5Ny@!bEII?X+&!otZTK+_%Nn9#ETMWCe8sBiAN+w8uckQOXcj6dM= zD{uGPf8C=STDfusUOsvOUaZ~qMo0<>JQq0gt=$}ZXnd;?GxV|=i67X{j0MeW8#pnx zT7-NX3-9P;>}+KS{Tp~ERLJ@p-RjunIk^2R1$P#S7SCNIo{kRII_{V!@H`-BZJ|=H zmGenSMd>r~uA`}3N>asrhfhPaCZq0j9mV=B-O@)3oF1#V9=dFwUzTTa{ct1U+g ztSKsEF`M>E4S?=vb_H2XL)`Y-oLberQOiv#*fwx$9tyu(Hg!@i6vp6d4XKQnr zS3Ugrl-JTO^nmBwG3(WX%pU<^N>CQ{mL3%I)ddodYH|cm4Y87Z(jXxsy;Y)ebQEIl z1K)gD!|DR;S0-fuyv+!d{9^DJJird%!f37(ZaL_Z5a7$=S@7XrnZQx=){~F&8X_kS z^YG?Nna3xX)PO@Z&~%Dr%9n`AI2?GD3*1vQzpqNHsLFU5zWr! z{$DH)^p;g6vX}^TTDX@Lta4{~Q+oQ|C$&g8AOyHmp73J@bSVqV0~V9fD09`RAd3c7 zf%n1k#?d=V%k(9-iLI2395Vj2Kf}WWW>&;jBYe`NE>6&CoHQ>7xeb%XLjuvO&oz~7 z=2mJonDv%6Xpu*&gRhegi5IJ-s62z4=UJ6CX{;R(Q{tb~$)Qzr9Syda9$H+~MGTud z$&Cft*3zHRMaw0Uu>6?yC@dAcf+k~!>a#&ht5HOZnWq`GbJ^cW@fvR>qr zBu%iQ!lkNn>nXLEd|Kx+I?vL5{tNL+8qKqoyq@Nar?0`BO-2z80b`r>-dpOaLyN11 zWJTRzdxHRM-?J!E@%)}Tq7b>ej-YoD??nYpOF;+rqVOWeSGJ!*ww{tdnAAJ52wSbaN_ffCl|x-PnQu^3PsVZ&mO=}D!7}VIQzIeA+mBCliIcVp1@|TIt}%9Z-#8qt2H?3KQm<*k zBe5~mY&nEVtIPxw#LFSO8xV#QbbW+gs{+Ob5r={*Fpo}{U)8RMq9_Jd=;U>6c2s3>@yKD8z3by zEQidagH2zm_7qQEB4T+n2ub_KPycpiJ&jtO#)GV_U8*58ZLP012Q4-?y}0=Jn#ZFk z(n`d#%NxS_N7!u|7D>aJ-k2I81}h(Y^>9_m1X;lIbo)n#u9c>>4S~#V40`Q%hO1%q zsEQobN5tBYrj+g*-G>B9#}rHXbqhoVGFGiZdE9G$WPY$trYfENui=wx`}RRl3ah7! zSY$^tYft;Yf~r^#N-m387XTl2NfMVZX+p;)fHa1~j2C%gl?P1Ctf^H~fFum#zk4`WENqIo^#3bub46X{DZHk&8rsf<9~+tM$SAj`6~= zeImz%1kO3GRd)quv)Xj>bOD3)nYoQI;!;vx^5y{z4>nEV@9PDIX9J|CKLOde7Vj<3 zDsNWLoOA;)HVlpE&!XI2zt~y0eSF#|weJM7Zrx(a%Z2$t@SOxp?-8~$t0y(P#8aIM z$QfPvi#w@N>71!;8|Mttr&R!spgPuZdJVFZ^W~?x#|$fl4OKs{2U|FjfGtbg{)#Fg zWT%NM4AVz|Om7LQg5tw=8z*?`n)E?dUtWRj*mFS>`v7N@_z%Z$6>A{$xh z=?9p@q@B<8Vi-*?Wt;RGv;@O<&wT61ek&FDOWJVsfck!uA839h_|dFv*TE$`!K~{_ zyhG>!y8b<$YNBAT`tI;CBc@y+T1m^V!P<0SApT=qe!-EBAC<&Tw&ZJC=T!ve1h>9f zSxhvv32qXZ`P)F!Z0e@MQ&IHb{YzZ~hYpS*cR3;io}z=<>=p<>$OsfPC-8i7^GQ4f zwA%@M-))8H+8=zFGK$4nc0<%O)6ivQ9zt^^4=1xZd3&1Kz&B%Xh#kOwR`k_}{ zXN3M^Af5f0mQ|wWOi>pCZ6^wQrw0u@VLW11T-T{4AcG6UEQf1an6~MN-Z@<3_ zZ1H0WE14--;3y)9S~=d|?tl%4?C7bXE`N;P*+2G7%wJktKx3svY@TJ%>Fev*RulLl zwc~vk>CxLq(K3^T^#V~3Yl>LgfkP07&Fv*X($v5}oU$@5vQYH+^H(pQO0n2<0nFTW zi)>3PehemFyTVpwf~i$~XGpG**JybadJu4WBidwN`e8OdwpV;QMqrM$9~?9d33};4 zwaxI#iRW?GfM;2*u$&q#>)Lcz1?)S!?{K~r%Q40+UKYL4A!nfmA*OStw^W~aP+&7v zIj5ggSFyfkImePRC#0$JxN`*9kYOO82{G?tnlk(HNu#+9WOzp)L~?qg;M`nAt81aYpqdk5dxMKd7B<#POX6-` z#KPM<#&)xS>3-L#{dl_GY$oUwqKzsw#*~#*MZsGh}GgoC_7s z{ui-!W8!t;`8AdA8BJ>Gp?o81cR>9Ea@{ZD-SbdJsXyw5VQk61!Z864A2V&vqwA&t z)L_Y=K27P*v}*A!q2XJ|t9_a)pX=)dLZ|_cxsdL-p8YDptV`bxoGGx*Xcqh0xhw

0Spv!-p6$=&V`<)Z;J3h`zw6I1PAj(iK`b( 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

X!+h{ngT-Y0&{b5D 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�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�Ucu!iP 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

GjX{+p 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�leIAmUT<*?7MxJ^6tsq$*pB=r?lZof&tSg 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 H#BVXmmv;^Wr!c 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 Zfj4n&pyBh|-%Ny^BET9Tbov zgx*3Y^xok-ap~S`zsvo8d+qQ1I6scpg^BZ-^BH57F~&XaG4Zv6yyPV!Y9bsQoJ&%V z#g%YyKq z4gBEXoPX<&0|GuT13wDMxHx#gCocAR^0{9e1B`T6Cyij`pnkAM$F0r zkZA||=hplj{O5;12MV!cr~ap<_+y=av;qqaBNAf&$ELxE?(hup;ov;LkrEeu>V&(j z2||KPN+_uIJTw>6sq|gesAziY9~gTpT)ymdW7`)8_u<0r&r!a&s@`V$o*8O*e{FLzm_j+I?p6FFFd~saG2mkR0eb%}AWC>5@Z(R9%;~rdn<891O z@V8`PwR(Gx9-O&;NgV|7OYl|K0n|0sQ~W;q*RJ!LK>l z6=d87(Sh^nJZ2O#YRd1`>`z^^Ke@!0RnQu0#&$(SdYs0x;!&uZS(#?Tt`gW z^h~Mi!F$ym*d{G|TIhXh*;wuvZ<`yVPNR`Z48M0pRQNCHUm(u^W<97Cbo#c~GaC{6 zdBZvpqNa^qvKZN^f6 z+S$dV$62w;$xYXLJBJvJA~({UKYIVpiPm`*oC`kL^JfbW{;PlOjy`v#=0JkhWxpp| zIYS<^F6Non5^_Dqvid~cet}#vCx@-}GpCJ7wZc{CLR787G@~q&MOE1$OHO?yN6lnSa2V-E*v*_Cth zDzaT%nz%6A%4eC8O9M|d9hy<5=igP@FQtvnuu>QJL(uhc7I6>|}N#H2t$y$0|*ZX&uK>>3j{Ej5=e}N+%r5O1j2fvmQ}A z7f-P6FV9wPMVON89}=>RJvC|44XD7IS9q6V^~lE?h! z6H*227Lp;CowkcwQCXe>Qag)dBRSVr88wF8NCz|a6>twLS1ZhN0{lf%T=rJe5d4Ra z?JxG#t~UgmZprZ}9(mJgiXP=^#_?L{IPB2I9=+@BeA-H9`}u|b4hpOu_JFu-%sK

Z?(vQ}`H)bwPhU%B?!kH7TId7h?ey#Zaptek>c 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 6Jp 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 W#fxq-GL<{P--YwK8pY~Yg8u`5Gf<-d literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/slowest-requests.png b/latest/bpg/scalability/images/slowest-requests.png new file mode 100644 index 0000000000000000000000000000000000000000..682f9f03d31b189cb6cacfe5cc234855b90cc668 GIT binary patch literal 100313 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 z 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/spiky-scaling.png b/latest/bpg/scalability/images/spiky-scaling.png new file mode 100644 index 0000000000000000000000000000000000000000..1295090c5e43fc2acdce9c5542a3168572cc5a3c GIT binary patch literal 31759 zcmeFZbySq=7e5LENQs~bC`bs>DJeC8bR*p$-N+Cl&8UFVl9Gc`!q6!>pwgvugGhG| z&F@7$=iqnUyVkw`-gQ}vnU}{W_ukKE=j$6a6$mmu(k?y4^P7_G49-ZJn(4Vf@Jx<| z^{X8XO&gu!-)CcVrvLf}+oECq>0 z!(`?}FZYZ4Ois@g4Go|8@)sQ~Ddi3t8pzRBQ`b#bSxLy;*^%R^g|nF@$8*PLm!r@` zo(lnwj+SmuX`VYeIJpWv7p48xLkM`jZ04k;`PIeEUX)f>S&c^08DdGp&%wpPMGMBG zp`j6hSXc?EOUe8h4*VrbYvbnjOo)>c3Wah&c{rRQ)|?Lo1qC^|xH-AG*?}JHuAWYA zPoJ|pxzhcf1J#7-%3ude~twl zkn{3iI3IFwasE3uFjVBSRY={^)!D)Qa(XQ%TQ@Mb$gj@-+x*{Zzenl*Hw-NB&zP%? z|2shM|7yV1#{V6l3bC~WC~~Dh}F4I#H4ya|C!EhnnY-F_G_iiGBvX*Uvc z|SqPiS8jm_30SF&VFRd154%P`DlCU zxJch)wrW(4fBd=zL+1h+f2VQhjo4;bHw5MC2$^eV>^zBlM`uYD$yCnq*7e>KpBQMq&Jj<&d4~f-F_M8t_waf3?XN+%7 z(29NYgpX6ceHkgFz#-%WJ3Ux2XgBREgBJaQ0yx^#>^H?M-c=Np~vIC$N9a&_}0+0eI_g4_4|V_SmdOzyXZ z?3`^R{<@6GwWpA+m5h0e9Jc5V8-+v8E0TgkGlLVh^;O|#PP%M_&+ure+pq?t)!t~9 zvtLd!SndH^ID6{s9$UU@i3eYWV$lK5#L(CS@4C?WF~!KZf=CgX?y`vJRj}Wy{Q5KS zXa+1~xSy2}Jjs!h;vb*#5b>m8@8x(_0W{d>fI^^ifUY-c)AxCW$n*Y!9fx42TKmY; zb*#6MK68eGR+U%^La#j9$&lx=%f@y34aYF^tfL>o^LdQ=^P<#`Osq~;=VB7-tHeH* zCernNAL8I#=ZN7nI+pO9?$bV+D1yf~OvxO5u7E0@t!T{IFH*B{PMsQ5Z?tPK>-yLF zY!}tePj31l?g>|GkQ=;I&sHt)+X=3?^=R$((NJ(iOwz%6p8~WasPnIjr6==j9OK4Gj?X?SvNK|V!P7!VP2^@|zK~}{ z{yTj}bbsE&NeYvg{ibTjxqPQZPnYLTVShsBS!6x4`j25ZPqzl$z7KTdYX$n%>e(wA zc_i5PSf+GL;$@SjqgrZ6Am49#x2H&-bY!*mMv<9#N>lkgi(wPBh`U#Bk$unq^m}Qs z1ogs^52VF~)dKYr+P>)L33uaLqbF!jR2h3feH94O_b_Gh@jkwf3VCI*GJ7`Pm5WSp zo*;=0WMwa9iYaXK$L4Sp@<#&4~JEO((0v6S%qu`hbdSe?14+aUA1 z4m}SlFHT>z{&d{CCvKjEJfH&AHkatf1$R2c(IDqJjjvyk=0JD6;`u%% z?*4(C&POrRQmrvAU+SY3&)T^TlXHEiy*PQ#?t9g9qOK_`zVSm%;mWb?5eaEAoDM#k zV?rW390fz4bhIiApYO>WZEl{cP|F223#^M*?|sDLZuQR2Ki#L?$zl~~k7bEm+qkZ% zMtrt+2JH;ztavSO>(<2w$@w-(QnCr$%U!^1(Yyd0d@Qv0APS=~O+6X61 zHh?UsC8M?U>e2xLfa)osxVj1&=;v*kVsb{BP`bZvA*S{k#$Q7lA7SC-x8SzT{?&>G zBRTnNT^cSGbP&P?RQl*I#1l7d2LClbPMAhOqg_e>Tf|?(f$b6gKiOV`60sER&FYK9 z@SToi;Z!Z`Q*iZ6?3X#&;c5DPK9X6~k%fY9c#78uUbXGIMrm!9@-eM1WTIof)L|-2 zi7|Np{$IP%BWrtZs->+BXdsn@3_@L6{_{cjB&}#u6mO+RTkEu^8Jna5w5p9lm||XR z%H@L_>e~FphUeq>6-ecEjK5B*CI`Apn9sJ$L%xz#R;xqhcdj*RJ;la6oTH77)baCQ z{8B25kssH&An)18h;OCho_`81B36^$i=oio-Qt1s0OW*wfx?=_=kYWfl6{&zzpHiZSI~lB(8&C}38l?}pH7QHM$SVk$W3c^Q**lLe0_a!$zC1IgyiVBd<>)I zdJ%A@%>ptO+)N726qrch%E2;BNG(;0&>e~5N+tZw{C5Gez4zZ(-!LQ+ZzL(6md%rF z!C*xkSZ}KM9;TRQ)-o~)Cy%8tY7-XtYu%XgPFw5i^;q6GE zf@)rgv!pI@4R&!;gPJ+EmM99mhM#2Ch#dD1Ve6IFR~YDf9jiBttFOt-5&mNwwFQYM zf{(kG%BG{H*sFqA*%~3i^Sjmx=8C~* zt7cEuXT6=Z^HqdMW=qRA^7#c@?Wmq{P8VAERlGCR1kmNln-J$99VoO74j-fCn+LyH zy6D*RpL}1;tBH-1A5!$G{pP>46u$vj;E;e6=j5%Wj672lskF1txP5(;x8XTT;Dc7{ zxp|}Yqj=4}m;W+7KwJV~6N%JAOYqyba#9RhN2&gm2MS1mU5cmSSHLg!HCnh%teixQ z@?YFc0~mMUpvUv?4uFY)t}v}Pw|PhZ;^x{VH+$px{t}Tlmm>22PkNQ6A<8t-vUhjp zpXkfsU8O2bRH=AkkKV=dcxJuu1K%GFOAvBLPamr4a}2~>U0j)l@$hr&2gT$?G@VyT z-1rJtsc^4T@1!@jD5b&hnD%BaVypcH=Oi;aK_NttNOxX6+3~7+5O2X^d#BG`AXGV3 zd`-8S3PRB`F9db?7meS+xu%fw2mgC3qAmf6MWO4Z_zkQM z-q(1+bUOnHfUTqkFPl$Jn_|#8J)6Im{X+Ra!e!Elo5n?u?$SoFq8A)gId~~M*b_S2 z-FovC%>ClOd96Vh?%_LZPak0agPp(V$#fgI=#QD1`~EU(JXwJ`tE44AU&VxUHQpks zfWGn(-Ot-Nb~F@m5pp_EwbLnXTtt-y+S_8c{a3BkSftdE0cF$Ug!k`3gs>{z1uYj& zAAPWl|8)KuFeYYDc6VjU3E588_d-Z)Edy2kH7vb$X+K&{CV#r~2XDW{AX|TacfIE8 zRm^icJHTjlB&uMQ8sVZtwUzTKX1lSY(yR9;g@vMdS&GZobMD+qg*1OhgoC}q8~Tsc z^%~g%1D%S_Yi`+|d(3fI>P~8w#Ov*G)9|>t=DsI+bRIXU!asD4u!2R?g;enh&^qdb z3N$Tu=%&F%*W~!0`_3lVL{YHwB;R4@p$Mh^pz2j&SaE%wA#i#z224;Y^`Yp=v50oz z*=o2+)UWsmESjvC;@M43m{$8H4i-L9{ZI)SQ~I#jk58-A&esb4*HCX)qPE+zvg#Fw z>}mFUVs69@ML5~6uf+qlLpwW4lwNT`3Hl=cWqeOu{bF~Nf%_PKa%KC_WH-0>O6DuO z0FU=~Y8#dK1iBKU111w8*ux_)44}_)s^Le;2I!2hSHzIjmOoFzE3b``A0IpJz8!fSU`}mns-n%ZBZ?s&@K)O0=15OO+uC?ED4UezE#z=~dH&f*SmlkX%qQYfeH z!2KuFjd-tPYOC;c*9d_SC5ffCFKHpZeW_zr^`eO}OF5o(p*CZ%O(yBy8?T#m78dM3 z2}DjXl2O%*7y2xs>rI0x-aUs^ZbXTk1rldvFlHKAygv1rT;0iGtWxs%EQkJ^xWsJY zrhH9UjSDxK9>DYoKHL~V7;jY1*(~D)WvO@zn;gy~6}19-g7I_jwZ;qqsHokQ|E6Fz zVzIKd<*vl9W2eUgK8`~5Ub`^JoTwOOZ^xHj>d!x-fgjXIvb0%Mkx~T>8Kkg`4adV0z0ulu*uhYB=%#wtE}D;$!+y>6JYXN%8*X;2Zgs&ZPFI z^!Bna{ck`tCrjTBDH$($@SEybti`A>{py)-f;$l}t%Z#kZ#&4yUHX1ejDR$FsuMlH zxQgp|IsuJ&&pIPwuWDrRG@Pvnt+d;i?f=OtlM`&ACw=0=E<-ox%eJJHL5!d|GI2ZR z4yQPv7(i^i(P97T5MkJyxJ|yn)Tdg>sol=jX4}v8VwF3#j9>ZJjt=gc8?krJzX8~j?3gS!*hEBgd*_~h6B~%h_S{J=veG+4zi4a(0^Zr6? zFn5tQmUQ5yOLGAzoSh;ixhrO78jjDVuJcc^SopDRINB7?Hg_2JU zwi72OoBa&CUD-Ht@cMHPPwthAMneztwH~~Y#JNq7D`AqucmI9aMtQu&f)6oGaYxmy z_Mdx(p1p`2ee>4z+f=zwqp1c+kwkyu6%Y0w&%&Ap?(h9HN95Qm2D6R|Va(=Hl`SyA zXzaTj-N=H`m=F4w7wM*esN+>GLEz8uGpz=7+LXztI3}Blbt!)iPS?ohSna@`Z|pXc zUWrZJDMEt{KF3mY@I+QAk@9M`K$PXK`aI(4udqbuQ=p}PyYv=P0gWtlVfp|1Mwd)h z&;#TkRuNuzMGn+5L1PX2D%evc9n1n0mnIW8bQ`4AUJSP85z-&P%M49v_bQAO%L%3_(0R`epe6VupJNwthO z_J&hvAl|!zf@T$m$)yJj&OJf}?CMRxK6~{_h<7IUOn6q?##q&A^IV!UoGQ5m z2NcM*m3!f>vf-cg|H*D#5g9AOKE=_%FIVIvxdNy>W2$uVVC_~VUGg>=RN z#-{~+(Bp>w=DdUIFYjG579XQ_T@-U_GBEtv?{v-rkRWZSothRvdAK=NZ2#>s&uYg! z4ufHK_d8ImZGbUA%?weK ziz?>Bw8iALl!{goja17UhYPtSd~nFT(DIEybNC<3He~}PlMBzw*TWJ{Jp!?4a*ERF zyG!1cUI*bk0CXC?*A{ax=Bxpvy)5(Xy-VX72D+^rV9`V)eG~Nf4L&)Cq8Mkn<2F_N`{Xq{YtdXZF*vth2Jp2`6b#Nb zKsWGma;@yy)}TPFSUI)Htc}VOSVDvdV9U$LGytihdO?1f-1!o{~!5jlsqwYEwn8r5+ljjO~Hf zvBx)-;$Lv`_uzm=iDtUe{@lZljSr`hss}diu~W~=sqcoCu$&nm!J(8)n?i0kWd6vL zniQZhq&43qb|@5I(0&^tThABJu(uM$31c%wms2kg&Os~%^xN*WbuRp@0y~1A4ZdjK zIj19&gKJag;~mb`BfXUJ-&g~J|4WT9aR3yYW$Asm*pl?#afrdX_qbj1dwlQS=U!00 zFeez&wQ3=O*>|(pDry?C|580m)h(qeEH$t*Geh73$`Ilvgy=wclJRP`V+F5~DE4Ey z2ymDY|B*U0*b6`rvmDZPDP3Dr@ya^)_VcbS`)pj_<~Uf>ejR5{p)qYqwH8>G%cxQAMCMALTpCNxJBW_~rod9<05=3^hZIg;ae4 zt}%4^9*xh}{()~;IiRxoX3eawx|ian#Q>t45@%oaMA1ODxPUg+H|z=%KgaQz4YHp9 zKAc>RF=k^a7+EJz53ioa=m>*K90MBg)4rrqze}_e#DPA^z9HnSA6c<|X z^64yK{K)?tQygx~R6xeO6G*PL*qHZEJ$&^R^ylbufa+nfWU-P0)Hv-;{I@bxFN`ES zH;bsqa(dE*5yNz~NcS40+=b1g#*%MtWt3e3$Th>CY{{cP6JpgMev8 zYAf$}*3a(8%6}?S{XhouxG?;RAoDmF%^oLtr7Fe)Sh@>Xw8N;?f@a9(om!+QZ5#=B zd2J&OBcUq}BfjgdtBfwuzsei{f1*3`G}R?c$-^rb79T#y4S^8L1n#9?&5yU2`dKIr z%01fX7vXbZ0Prsk9DeAZrQ5lI#q8n+d6H=CTcLqOFCwCr9NyvntH)` zLPpK5PtvrJHZ`&nW}%WUaAzP+4-HWexqKoZNl>pJ&O`oFW)b&LSS9qqy#dm$ z&+0}$pdDIt(IIrwSv360#t#3O^H|#6)&r&*Ocy-^eZmzAo-6YndM;_rgf35cm+>`gpo%^OorBayQ-dR=C zpQ?t>Ca+&mF!TPA}U<)YCQ)skWDwba|pEKEB(e*WG`5qjf9ZO zq0`vWyOiVDYf!Qqf(3Zj_N(sH&-44#L=VUGSTDZIU+$w67b+Kgju>$iX!#)NQJJW6 z{7!%meVlL|YJZ}bvjHVJ9`c z(_0Sopj52F_3NDV7v-^d=1PuthD!IM^Qud_QVZO6-k)2QH1{XhMt z#SGq_Go!{OXrrU7k;7-XH%1=KKc!Efzsb~Z+PX-^AQSYa67!BrNB#$qF}%q(MJZ(X z28K3+{+^TP5_sl;#LJi48yIi7>&1stdxp$6Eyql?f-_{1KTv}DXcA|((Ovo|w z4BQ|hg^CP;MDD8C^Vfs?YH5ajVx_CBvv{}s)^JE=nxkYv-(5@UF^t}yq%wNsv-f|I z7iX#aV&b;&grQF*B-Q+bZ2MA!9rFGn${L$b)eWxVo#k06o*0)(DO+K<9`uo*$7KLw z%zx@U;1vBxU}c9*?5DhnXJZeuN63IVqJGnPKA*U&MRe#!g&(rVzBBx}4|VIl>RR0p zvR67XV`IO2%aT`9U(rQ>Z-T6z%DvZj`O(Bhu6gPzDKwF+s;cw-be%z{_n~>f8Caci z0#Tv4sA>=P9y5hD)$A4SPDUb`4sIi!ATY4-`sO9;B-m5)(9$y^cf9J3@r) zzOADdRi@W?Tl6F0T(!eT+a7t^Bx&nJUcbXiKLZA%ew%IC3kswI!vT6EqkfOa+r?|z z@hwXO=%I#Wd0DOOL;}4ko_ma6Q~BL$)@Gci-?ddA_6t!`@^GFVXDdA5B4toaqEr|0^Mw4VF4S$+8)~{N!~avogVM#@jW0u zs9W2fZvKhe{djyaPQs?~WCCIy8Dks4BQq+YehTMBtZzl?xx{26b-stS?i5h}jI5BH zXY*20)OY%L*FCA*{-Uq?{LMvo^>T<4Pt8r}7+10d1X+v!wos>H>Qxvu%c&EM=-4Km zU+$0AGIHJ2XG>u9Tzg|XF&u-^Yf zE$`!5@D-P$@+O*Eeu|CnK?puAti-VVGLc}XWUu{K;xBUP1Apu6Iqgf0=2Z51=$C@x zrZ?TJPrE3S&0?7uIwP~~i;wYf(IV%mU?2LOED?Wr8N-oejs|Q%CMMWY?USQa3vb4s zLyMK2FM?QngH34)H0;#v@7kK;w*0Zl2mqU`kI5PWIA@-;rku>vr(OJ`#Tk?GZ$;5| z#yZP9AMM%2tWY#S`qE=Z?I&GIhSE3xIJ)A@fH@y$mK$S@N%W2j9Y1qpthn=Nk>Nuh z2q6-#nSb$!(bvgr-#Lwek0UUQ_P2@T4XihjTqX_d@G0zsL$t+q1)SC>WR(npF_bO2@qS;(9{KI*_{w zizfLmVnf5_2ZNrSK3p`KXgHrrEg-LUhnyYGw}$)AV|@yG>{*r2n1=@CxDvKds{;v- z*H}WmBiT~anMn=SZ8qbEHcYpzbX_a6sug=KjxyALC^~%0HJIM7ztCvCEj5LkkN4r7 z+@H`3z%{_{*TpXl&DQE1Q;hH^J&hYTjbL)zrZ)QRJ8`@t zyU}+-tSu8De8Th~`t`rz6E%I%Q1M$~%rCwhHcu|r`<%cV^={#A*cnG>XXefwWKPB= zT%HWYEbl(hzW-z0{R%pk1hhm~%!AL!y3LhoO7u+|7AImhaUb~p?sFR8{dkoTz_@MnN+gK?MaZa;nauGHyNXKaq0a`Ipxtkdvs7X(eFP9dg>2tHKyI)Okkc>@9(KPk^Z( z2v>vvUB2LsoOqKyGx6wC2Yl}4&Hc7sDj(7N-^iWxvgraEw?MX7+LQGXxkUxB-f%B@ z4iVI&>VxbGOzkh@JIcs_NfHzHX8qg(xrs^r3gSx>bUy51DcIPp?mvid zJn9z^C8Mwg!b1v@Gkr1fU%9>ddB%ZQ84#5o!Ms)ECaV_=g#8nYr#X@<`8rm7$vW!p zYTmsY7*?d!SV#yT9ix?Hb0AW^z{fOdDi*2D!n&-UkZCMRr9DTE3&=4Q-rX>LL^~~F zJ^eIZ&Y7Dqr*GHH>99aEsS*I)Z%WhBa!z`J|mE+Q_mim!?YZl|FNINWiZum z7v2SmeM1LSz8p_e+8=H+H5Osn62<87`aUJ#$ zk1bW3eNs$>=jpNuxLl8;;XLt`tg^1EF!l z;J&gW>tKWVqSgvB1>QzS^V^kS}266!%oODTPoVp;`x}Qi-Tp%|g$DurEh`Xjm3{r*Q z9A42j_ZBSRXxXZTB#01hUr1_K@@P7)Es=Lf^QBNR5`7DjvNH6Lef$|^BPQUhlbXsE zPMAeUwBv{c*M3yqV@9SX5UTbrj)T%63Sas$o|8c0jJ6bb7Bg!r%+l9it&Tk z-YM`$wzZ(nbu!BPvYZR4s81irJ@)eOwH2zVRwtf%+gJH4$1hGso=TfefS9qhE3=Y1 z@EkvxB^d7K_$xqF)l@`%kS>e?B*4Ymz~T`0%+)-sFCo~p+k8tsb*8Y!Lzl%ERj2w+ zJaVdi-}4&BV+GZ$a>%Kjc}@zT^D6wyU_MCSc?ZFZsQPORv5oKccdb+(&SI~I%tRBD zs@kBL3seyfsnkX4aSzHTVd0q6?PKMJ3CFi$6KpSAi?D2!@ZsNL;@?<_;+!l8KP9Io zx)Uj`57PpQeyF`$-}Gfj#Hsp!18+74jy}KD1XO878NiC_-QlkY3a5uy#130q0JbwJ zp(8${!1Y|^q?nUWt&FODP<3yeU(s(8ZZ3X3kX?EW%i-H z?wmg>;#bgdE_Y^xLad$TICS}1&mKMXC+v5+1@>Pl9Xa3}PM=XEH&iYRX`r*1OnzP= z{Um4rv(%_rs6vxV=iw!I1n$4xCAjcWGWIji>3=&{t17A#-;-#pL^X#6i@trQa79tx z?Dn&4jIm<1RDL2?lwz$}_0oXwCVsYNGnnUvcxgc34Acaoxnp5_*yUJ4WB)BdTBIot zoCf{oP`z@BVOD+J=QMugP%7d9HDZ2eq#rtAM%vsDnynKD3 zng=te&iRW2Qrq>V_|3B)Do306z2OFw8NV={n0^aJx7b;GgYsjgRv~O?ywF=pXm3Lp z0|2k<{siDtfiDFJ-E2m&_BNe2i%6f@bQyNG!<|)UIG`XPoKf1Qme}#8Omn;yQxwbjU5^6eJQ?O5|G35(5$=(&Y0D_){1R2lf!eJ zgV*)Cc1|1LhA5*M#h@uCZ~s&aT9}y5@W!4wmS6!`l`e$^(4xl6YrZCVGiJ1(p*>kR z*`g_*8PfBRRWa6S&!Nh8^-ZsnV;mMioQgU1klZl7@R+Pg)F0cWE&VcqwvZP zap6ssgYT8g!9W@=Wl+EtJD&hv$48NDmiqg&*O^TT?(PMZYfUp&wKPw{!1M&#k}%V511?bW0} zWVzze_^*nRcU-V9WGeB~^_$;D4iGkKOjb=m?0BxIaUcnz$6X-fj3@myL%C%1f}hW$ zEq3M9kA%@*x-5npgjoAjs(q;fVIsGSNzHy@=e=sR=K@o~D$}A)UB7Hd6tIthp$F(Z ztz~xc(&8NYWoqE(bEog5viKW42B4enp!^Xj83se3g!6M~0On<~PoLc`_`tpYt`2*L z9R*vGejFq2gS!Ap#n18TMhEDfksD7P9Y-h>Gwb^t*}1RzyLmW})8T|kr+?nOc|s=k z&HQnlj9(bB?!2sERLFHaU9NA_VEJpq`V)v!@54CsqI+J=qO)~AAK;>1UvB`3(bZv9 z){U;1%X%3a4A2mff*c$`{AF_A1kSO#Gv!`~82AKA|JqOwODTgXW8cI%OlH=*alO24V9da*Z$Yf_f(yhM28RzhzKbOrhHON-vDv zw`1<=pr44=|4bjX<5zpQGH*n=vlp-J^UE<%C;8U6GE==@QVsViqv!9DqrzK~wp5NY zu`=|NWpnXJO}uU2++dCg`;LjnQCxaG)xD7|_l8u=Mn8Vjh3{VY_nmeWJ%ee{6Sh?2 zpLI*NdR0S6zoHXd?9TVlSJg4B^E#WN4}Nqah8vO~rj`wVJiOb{;*Np6)!9l7H|+)1 z?h@Sz6>q}Q_BitRf~`$Iw{PvXlRVQD{ISvV7;_^zjgx-&F0zu&ywroex+vGj_ugmJ%O?3uWS6DXS-t1rf>SDd9Q!jIZo?&M?wcE zUP^R0rs%HB7_Hv9}&@5ScY$!6U{XWS2R&j$4 zn@C>WT>QBoH?7J`n$T=*#{AwFxra|b&aj?)w}dLr%+2>(>KkIm9Ta{h-1O9<9TH)b zTmyBUr9SJ0rGj8e)f9T3-c>mE^I<0byl`}t|92n1yu9NPp6I} zpl(TR&BJ0p8QK%I^DefHeabZLT(>ct?@E==|9I_iT%=)HbR6>G>HT7sqz@^d!X8YQ zBz}r5o>#)V*HA10cHJqJ*bG*Ruz$-FGj47a$ZT3r!cf(AOhJB|rR(#9L7dyA0W#{; zVtyq9+K1-VOA)IH5BVQT(!qs1Z4IM{jBMdD1Z4MwWJyt|3ma4d$N8DY-7&MLMGWZz zPkX`7D%TK2cq21|JIAx^t1%`Ll-x1xRm(d^*GOQ4QPOQ+HL)D5t57%`XS=Q?!rUIF zmyTI!Z`arp?U+N2_s1hlhJxqEO!cOf{?`LJ#hbf6b4p%19T*_8v+cXWCC<4SsgI*{6&z_4x~-}mK#9!|j1Tx4ZW?IlL% z1;jQrb1RdNIGvoSUC!T}MmO5g?uVL=AE+W@OK~iu4k1|EwDSm#Kh{g(gtsgVIS*+oIBa-ap-Rx zaBRAh-HYAY%lL$P-Pb)C9FfF%;QX#6<*?#QeZjxKg0f=nsxwQ`vDC@?*xlK!L^_-E?v1PP~@vX z_58r{sK>vqAN^#x8`XZAs9|AX9=cX#!>L!X2|5~FU$u~tOfC2DXfLhinVYE(_8ZXA zoVB?2D@L)2)o>a=&rM%=*VA5K(C^M(q4;US@1m;MOmS@xt9S0&%=~UaII#Gd;14_vuGy zJtQ?~F5eyNWX^h(zqvl@UTTKUX3#~eOK1w=P`*um@RxHEslnh8Pj%La^NP8x-aCDk zt!NapolG^<1aCL*Sv4!`oHFz)4&ULL6&Ml&51fm9b@1e6<~i!I2>KB8vY+qp-N#gO z!nAj>u}!P;NfLya%w0S-?_szZIZsWEp$;j@ZaO?$P#?WJx~f!Rf@$)>F+b{plEC_& z*LitwCXBiqhMRx?ggN5$=xb8YI}3aQ9>J%+qo-SuWYBijF*T(fF64W4m2s$yLn+D6 zsH2eXx72hSM_p(3xgpuYgOm@&cHX|xysl%l&HsJ-L9&vANbqW#z9|Vjc&r2BdDNX+ zBH!(p%I!U7;px(k-@_|Bs)tbA7PIkAs>l%>dj)l9x-XM|nM?gxUR$kIxlV2tbS@u$ zT(7gZYGV%s0Heyxp>8tC-0K6j>_R{)AT6Gs(bR1iSxfg(^n<6xa2kWJf`E&#O6c)8 zVJ)IwE2(01`hC#QjbvG~-H~QLXRZf7p6Ti*8DzS?OORPj-C-i$ovLIV`wS;Gv2Una zcZz0NcNZRf|G4Vz^}u_G>;)^|CwwI=JN;o}6S`jV=sB z-lacH*ua4IH{6-U_Ld)oXm3V-w1@M0>?tG;6-4&BDtenGj^ftIPOGl>hIJ&7GoeI|P9rI1dGK-J$CHxo`XCx)4WWHHh!akG?H94w#FdZhB%((8>_(GPyDx3q zMV2WDZ@eC66|Shm_)+*&z`S!rx>4>#+`ezqV8@;1bTV(t-1C!c9=MyK<2$czD`?kGsOS7_gy+kVKN$xVg$QtjxN8~7qyg`)z zx_eOJhVf`F(x8^#<$&0zP~IQ4;b&%f(V7EgD7UE9h$Nwc4+}Ct4=$)ueQCOPin9k_ zdfg*f+2%PH;ffa-=gu{}7|^=5XGk%$Th~S<>cObvOSxLvuh)ZUK^g)v{pzQY{n5F# z`Stc5YqRo@HYG*#a*-}%wPU)-gy-)1rrNMrZSvmfd*tT9kao^}3KZ1Jc5}cr#J!bh z5?iL>JXezpv28glpU70^SWv&SwV-`A*=iDQAlpE@xFP2FOk>&BblkZuW3lUy+f^T? z9lU-l9J+^@Qn79`vbY$AJwq$gt9N+XV=OfszC;3F+-3w>- z_qC}PDL>cpbX;{3gj~>{{{v!1pzem|;}H zWhK)q)&H=CDBC8?ig9pdOz4cvsIJDYmPb9SKd*Gl5Bg;zimI5dW@G8tH_i)|&CpLC zq-y=RrF8FoL**CS?!3}$6_#LI=1+y$qk?Z+dd-F7hbiK{DyWv-^*hVf1DuWo7tOn? zd{r2WOV>_(Js_Jg?J?KVo@akHBSWtk)Z*sxqlT<8+6tAbjpRO1Slrg$TM1Msk}C8x zaCl>oHpy{ufM}inOpylVuvq)hmUhsxSlv+RsFoOKPsc^&Ts1HpsYzbaJ?HQ>hm6$2 zFik|Tp4%0~%APUWpS^_sC~1PZ+xMkk)o4$fWOC9igIB9V_>PnBvw5%2SwoBxR95<@ zd$*AH6?3pmNaoQK`7KY8N5@J0lRQ%VP_L|l@ua1p(9aD(ZCrl8FHMD{U*-OX)hge{ zBqCKPb(_Zun;a)0riI9Esxt8&Ti};lCl$CV)L?nIl3o4W4-#$TgzmHc=BNdI%?&!*G{{H0ffiP;hgs-8C zrDOk5-ih?7a~sDPD=UawbOXA2FJ{&5R>x0b{~FoFG8vT*PjV=03ntdytx?6T+UvJy zQh99P%YMdPgw5^9@4My=i-GIYD|US(lUg@4``>o>#F5Oa=aBsnF1oYSVL5$Kr^vDn zT%+2G8K}CWnP+C{xnVEQzZb(LiotM|zP!B@^+B=k2k3X_k6UvD zMzBe2Nzu?A#a#Yh0H=3Z%37goQL58B(XL$(75*gJ)%Xl`X9eG-k?+EiRNX^<6frTK zN;%yF)1zJI;9RddFCN86cegXS?y{As_rhH!Mf7L z)@Z9-nTi3}M78m(zXk91wETqH>N5mAgAbV~DT7kST<{$4D6DZ(kEc4-Z8$Ea@O^w$ z<_+=`TS?!CHa$y(W&Wix&XiTuaZ|_CBD+i)>f^IBaU;#rJEjuTQa2>mF&H_L8C3nx zpDSzo^S(DPOiUiK@x1P{sX|Q~T2jOS`O2ZxM>$biQdiq4iyGV;j@zjGxhS?QOZdn) zzxm=?$6CD61Q9#@tF4O(W4M(Syv$L*7;;Lu(Lb%@MtuKFx%*@H@InGl%;tkG7vC@{ z;%hmb`}cIKjc5qdoM*g4D`d~77L+a14&50d2|cG2(wLWB@!A#i&E_H#ji=iTIyb6R zJRh7n1b0rW^<&57Y=8(2Yh=i0$p!BokBG+m5V&8X==5?EyJu%YWrd=&+8N;&iO;$X z9-RU+s+O7E)1)#VHI7ekK?NVK!r%8$f0?HjoR(w|kPNiSJ`lGEK2Wu*__TIyQOC*q z$@%uIczD_UD)_8aE!#8ES+X~9Quor>+Z$1U*;nW_<76UEt*6p|jdd0qIW?G)4V}9~ z#AFGxE8x~PG8W-%HyBK`uBucx%Q?Trs*RZ4e)E&8Q%A*wDmlK0E_ICk>&cDeRZJZx z@<}_A*KXlSYLtL6nw;(KCBr;nHwp8 znpD<}^9b6*EG5^?O1Qlsg9ZczAFT%HK|bz3v4VczYl#`mI6tZxuISKzIuRK1iWYK| z3%p&P38RoaQsa>}CrfiiX56PIy!$)D`A@8oo~Dr)af`{K^jBU_?GR)%)-4SQ)c3Bm>*fH;kbuZM zld19v6b1e9lXn;H6UADrbW@i^7Zzs*DX3PxGzx*j@jQ-dt$a9p)rY)_w9%~a0x3Tq zr`-N9){7Lgmgd&aIAKQO{yrz?i(+O4VA3znZyW8_Y9*UE^lYAX;E#`6^pKrrPkryi zJ=v5UW{c%atAsYiOE5FkeLJXCXQSImxd2_bAK;bT&~O|Xo1mXQ91l8GbxX^62K9EH z5X^Qkq)|dL zsX#~Sa{4K|PmtF6@9txFyVUC6&Joyw7kV2Bhr4f%F8GqlrQ_+^PUcbGN0yh-E!^zm zKF#AtHn@3}o79ewU8b16f%GjGX3a^3S|yU3oP>POBFKW%5^|YwQ;Jc%iCSWxI6ock zswl9UF#vDuq-O}QZC-Q}<4SZ#3^}d$&{b85i@ATE1*t2t=VEH-3X-fD4qfyV^g6|m zuN#5+mo{4vl;NbGpDn*pyhguUgKbRB8;*O#ZaOFk)Eq}EhmRq=F20fAbuva6WWsUs z4T;Zbxsn3vU#d;{XXNX&-fdyrYNA_=bjD%}7e~j#te~4Q*t4?sRTq0bge&^x5J-@= zEb0&`Lfx)qot;?UP(bW2iS~8lp7@IHTZIDefqgCVy;B4^V;li#`=?PxH{j;!aH=>bJ!15*@U*>YgJ+(L>?gCfE(sf#xvcg=oO-2dg$um zvLMi34b(=L+q})+%*U{5@4H*^5~4xEG-KtvFVtXU@Xc-+uX%^$dzC+fR*P0lnD3X% z0$4y|6UiPObzsj;g@@l-*?c`=7rbX%(6gmwZS7~CfAgRB7B)&8yNpkJ_v_E-`}3O5 zN&067SHj3Hwi8EAaO0~k-x@(R6NfM-&td)YwIZ?dI(4KKcumed;YkCfCj zR2n*+ZrSP8r#B^9UEn^CiI^>MzH?bcU&?99M^FlWV3cA3oc&vdo z^+cW3Sl?)qJTsPz(;hpk58!7GZ0+R}b#D-<;5% zGzkLV*!OWC#W!ZRZWbp8^fL1^msMhp_idi%%4>1DDKmagQr(Fw&}QP*5zAR-xE(2! z`NU^8pQ843VAbj;M8B@XjSLT z2VPzWIsVDvwX`y``MC9$Uy0qft9sEBlWZVPec$3b#F^T^HSw+gmXnjWO|?!_g%ZQEe~o!p$za;|=_64&fTXOC}H?PLeW#z!p6iE|wdY2feM zR^R)zuFkN^7+<>z0tmo42euzT7jg)kd2t*Nu?9Pt8_?%Tw=dXe6jh zoO`w>Vu%2TlKW;Rjk|+{$`{YK7|C+)jfkKvD@CLXl)Y4&w#H#98j^knRx=J71X7^Q zmSQ>ap?;|!gSXL(kQ^oP*(eRsumK{{?Cs+{)%0wRTFLif+R|PYA!eLpLs9^>rG;PP zB{gY6YCF^$_! zF+8c4Kz*Qr9+aL*WDNTY*g~=)zVNRf5!aAR#e|>VWf90l-Cq_C^vr2lqyP(r!BW-X9tb^qFp zR(2p5L;ZZPFvnT8}3$NY1ewg4Y6UZ{B z*)`BK$7@BPflRxeYYJa~uokA{KREF`M>+KpGu`3)%EtuI&sh0I#{&*R^#-fUMwOdkM-A)SU)M7gB2WN< z3r4Cv%SiI1&9N!;PVD@z2YI6FXWYDTS1w5`d z#FA0i#j=V2y**UjFF(sNEdDE{Vha2pHTW?0;B|m<@z*H7QUW}~upIT0sqg=Y=!B}Y z-y}E%H@*^F!tipYJ$*`10=QQQ^(P~WMs=>irZ5Y;n7I?^bXPH_oF{hxVCC2tfV?MS zkdvoP&IN-Gr*HJ#`6`vk1fd8;GCaQ6lr`(dVemzCV|wmQl@w^TaRB5RBU}24dT?TL zmLaNWMCyr+0L0mn0gFa7SrgVWlGe=JgyLML(V#gH zDEb_XUeaFLVT0dA!a;SB_l26|K`yJwgnGIRLp0B2A} zY@|>1sTi53VghR7ky!ZOzAuNZ?5b!_B|e^(gE(Jr?^nxAtV`_*QRd*i$ANdJw}*iy zx*xhRd_Q@~+T7I=dQOGioAlwp9rzw*f$?Dr{c-Z2xwu{Wxov&lD`0N^Ul?A zIvepqrukrdrZM%@z~)UI`T3DByzePVrD~VKSS!S{jgRXa);}YMNhb#ycm<%|&8V2fz}d|LQ1B6^E6Wt&pFqO556%-1F)?-oGR7_%0)Y z!K3;}&Qn^c^homMIgM3r5U8a|I|r>O*85D-!2p?YW(2R9Ci2~?L)q46HK&cfZj~1$ zd3+eeT@`{AItC0@Q!$7SgGszQv^`^8)E?&U1t)q|Dl~w7$BNYsrA8lV~iDI7*i+qU}j6}6?&GmTUF|} zle)YKLF&O~|2`+8})rJZXz)jjG6tNe5Yl{A#;0+TcD6f8?>e>pnPm zqAstff@>ss9`28?9jD>gUk+&$`zjU&{vi(LN?tuc7(6&qQL@Kg}$vW*BKi=r^lNj6KuRcOR#w+ z`3?ks;`lnZO<)G!-ZyGoT2hgK&rGZ)CEk`h%CtTnseujR5?pJ+spDUqB5O(e4ny@y z?^Uog-x~b^JmII^2^n*HT#`)x;b$UFxfxf8un&r?>D9@fz4WN?rSjO`8a}IUd0uC} z>C?GuSqk4zb?oj6sLG|;s#AZa$uGM9iK?(8u0AXrQ6c6RXPo#?7TeP-iTu$HMAK!E z3T@sO6*l>J7MWH>eZ!4Oh?)I@@7OUYi79MI2M31#MY`I%Xmuw6jKNcNIxu;RmHY#u z8()P ztxIAykoo)RD52mbmq^ANSgP_GDNjQ1&CPnUMHyY<3&t0Y`l5(J%IdV0w!0s9R{0S^ zn5660x>}q%9(6~2V z7d_|lFD=y{ojxSH!Zg~4YU8)<5^V@F+Rw=~)%*%*`c3fae}{0VHeQU$=<0=q|4JRi zAQwz;w=T|S+BDr!o6E!(M%{Xc5)D`uv^S%k&o-aH;?1r|`lR1)Vpj;P96)Hf{F|Li{+* zBn&ZUA8M(O?D0jF>EF-C?%!=1cP&5)(LZ5V=amfs(hJ z3hzwqbzl8V<0IoM1NmUDA*}}r55pIMZM6ZRDlLi)pLA7?_<>dwi-8f_7K8YqRA$dP zKGVaq7g{Yx9nHe;vc+R>qsgiqpXWt}MpT=Br1-(I-<&ZeF5h6Sw@>;CC2z@h-Rn9* z&55lVPu*YG3c1@jgUu3|9-?-7C=^)2|VE!z8RCI@<0p6E+AiY+d6kMmFMj8OCEL`oAKX z>KIzPG&sMcs;nxRnT@^2udQ(&VD=UYplm}d7J>UWrWYzgVWIJxJ#TVAP{Afrz2s&l zZ^~s;Hl4aE58WBp{Ji$SXh2h;;tyP6Z)u^8-o0-s#@hV|9kNrM(74U8z}lxDvCW58 zoEv~XQuJo2A){MWwRM(4k-GfZiialOLaSIY%%T+|{?HLJx}J2)y%Xrc6R$fj!~$|v z+CSC&(9?wR)upMsb%B(e-&hfUPslr2T}%35ih6kSFgZkp{oZPw!_)(OUDf*YT0YIV zcUQ<748>@+=AKIlf;SsledoWl9KzE3CsvE&i;R4?A{vpnsa;4%D*yU^2eP5nap$*-~%L`K2c`W z&Wc<%3+PnuFh3~1Cw<8)oiUYPtoASzWL3e^p>4#~TI}KBUzwM~R6A%-RWrxYs8@bu zYaIpQ95X064G(P9sc_j!bErGkIC9q1rh$;^RYGRcen(S61U;~9=O^7)PqEtCOVQE% zoYVBa$yv2HYmpxF{j{u0>SFO+?hfuM196eu{ot3Bz{8 z#7|ow7A8w|)HQhxa>Z+NEK4_DUx(09@oie{HdL9mwmm;ruuPE5PL(RCP8tKw6*A4a zeA;FqwmA#NRksg2suI-0+Y#((0QTJa0)(308*Nm0U#4l|byN^)gMTcxw8;DNLV#0D z>Aiy%xn9)Azp*s=`=R+;gB(^(nW9WZ%{OVF*@?;h=2HOe53P1_?ROQFObWQxG&~;& zelh$UpTngzk)etq>qv!%X=LY*_e`33!KHY*B$tb1L>9j*clQmgboW$vmO8*w8t4ZC zW8?Q-KFdSeq>F;B^LBdG>Va`u6bo^%LUvGu`>gxWFm&FvJ2m%!r_kp>>b}iP0Isum z6jnU=4nuG`9%JDXvH3-@+|ooFM(p?zJ^1@QLunBzPusly;{D<>gr<&n@?1d$+~l-Y zQ`MrT-6-lo#~f37n6~Xutrn5xs@EME@8?uJWumRq+ukq|?mb+SNA{uay2mZmuy?(@ z^=SGvYWOEom4YLaIW9NgA^P!Db+QwOO~2M24l`xzp`KpSimC)WaQ$j&uYP1fjP;Xf z%&s-PX`4jV#!m}wzKP`dM$?^?9ptDIJ-Xqf=}6@tH)p22E{-k3f2^Eu<&*nFgtS;1d1EIt05LkOmqw0h?0R^5lTfCXdqGax76>W6w z^Tv%WU3u$P3%T?+Y8NI0YrhAR__Vk_+!|~vWa({tAC)F-_#AAP=9bD^_awU7NjQ^# zpNo6|u@1{6EUeZpPfe+IUvy?ZD`YGm_jcNxoDAm_E9p#CCqm*OK(0AISDqKDC?2GG z3M+wvmYbWFMDO+{+=LGL-8FR=D84l&!%Rt%mt_aSqY+ z)6T#`Pk`aFUExVOtd;ih5zL*UNxwb&^?ryqywM`B zg2A2Buo8TxRA#czQ?k{nrBc+>S^=-iMhjI_lMt5IZxN+hh1bwWHH9~ z4l%kIGSKujc-+Mw?0ZD#0#Irt*$p4-e8n>g0;5FR# z>0Ow|UUlNREb1RQ`h=}(l_=Tu1ebOB_HY!SSz0dLbH5}~1^cyg;C@9cyBHo~cf_CQ zx7(6*WAvx5wV4PAAq;~IYire$KXvvN#%y`MtiR6uK>zpPx{BzCui0(KF|h_Z$lI(; zp5||Hm~T7~i5uCCWupL&g*!K0))gRFEkDcj+vt{<3M++#LGbr_Yf+*;{Gz_k!pZ7P z0!NL(HMvQL3^&!y-YG}xW|SetY*H(3kD#-rLaD0%IKN7Wp>N8Q^mQobbv#piZNn|5 z_hQPkn|cr3?j$Hkp)9Gby88xq_M_Z~u7x!{3MS3fi2J0OH_~kaZ7qwuXPPeYQa25? z3kGwn>tz4|0q3yfBM@aa$)#!^_H)aZhPywtb1EC1b!oMPa`nsm>kSblsWi~@V z?MCKw$32*9`xFo>*_pC-;hghe_*bN)n^_UpqKP+#?KDljg20vebf#cPPN#k; z31m_{Pnok)@1F$JM8bxs@Cm8SvbQ-z3kI-Itu?z{H`IP3;QZN_>9_b%$_J+w5i(3Jv6{@v@u}*p>DZ!2_Uÿ@=>`B@#(wuhR09rU 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˅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[cMUx5AL1H>tdgaDL~>Li&r7 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ν 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/util-vs-saturation-1.png b/latest/bpg/scalability/images/util-vs-saturation-1.png new file mode 100644 index 0000000000000000000000000000000000000000..936fd3ed9804cf1cc2376af9bc9bed776e86dfe4 GIT binary patch literal 25565 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 NNu$%pvJK9L`~`eKI=%n^ literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/util-vs-saturation-2.png b/latest/bpg/scalability/images/util-vs-saturation-2.png new file mode 100644 index 0000000000000000000000000000000000000000..17799c9f6f8ea2dfd7e4eccedd5f51276235ad6d GIT binary patch literal 34826 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/index.adoc b/latest/bpg/scalability/index.adoc new file mode 100644 index 000000000..18ea20a97 --- /dev/null +++ b/latest/bpg/scalability/index.adoc @@ -0,0 +1,51 @@ += EKS Scalability best practices + +This guide provides advice for scaling EKS clusters. The goal of scaling an EKS cluster is to maximize the amount of work a single cluster can perform. Using a single, large EKS cluster can reduce operational load compared to using multiple clusters, but it has trade-offs for things like multi-region deployments, tenant isolation, and cluster upgrades. In this document we will focus on how to achieve maximum scalability with a single cluster. + +== How to use this guide + +This guide is meant for developers and administrators responsible for creating and managing EKS clusters in AWS. It focuses on some generic Kubernetes scaling practices, but it does not have specifics for self-managed Kubernetes clusters or clusters that run outside of an AWS region with https://anywhere.eks.amazonaws.com/[EKS Anywhere]. + +Each topic has a brief overview, followed by recommendations and best practices for operating EKS clusters at scale. Topics do not need to be read in a particular order and recommendations should not be applied without testing and verifying they work in your clusters. + +== Understanding scaling dimensions + +Scalability is different from performance and https://aws.github.io/aws-eks-best-practices/reliability/docs/[reliability], and all three should be considered when planning your cluster and workload needs. As clusters scale, they need to be monitored, but this guide will not cover monitoring best practices. EKS can scale to large sizes, but you will need to plan how you are going to scale a cluster beyond 300 nodes or 5000 pods. These are not absolute numbers, but they come from collaborating this guide with multiple users, engineers, and support professionals. + +Scaling in Kubernetes is multi-dimensional and there are no specific settings or recommendations that work in every situation. The main areas areas where we can provide guidance for scaling include: + +* link:control-plane[Kubernetes Control Plane] +* link:data-plane[Kubernetes Data Plane] +* link:cluster-services[Cluster Services] +* link:workloads[Workloads] + +*Kubernetes Control Plane* in an EKS cluster includes all of the services AWS runs and scales for you automatically (e.g. Kubernetes API server). Scaling the Control Plane is AWS's responsibility, but using the Control Plane responsibly is your responsibility. + +*Kubernetes Data Plane* scaling deals with AWS resources that are required for your cluster and workloads, but they are outside of the EKS Control Plane. Resources including EC2 instances, kubelet, and storage all need to be scaled as your cluster scales. + +*Cluster services* are Kubernetes controllers and applications that run inside the cluster and provide functionality for your cluster and workloads. These can be https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html[EKS Add-ons] and also other services or Helm charts you install for compliance and integrations. These services are often depended on by workloads and as your workloads scale your cluster services will need to scale with them. + +*Workloads* are the reason you have a cluster and should scale horizontally with the cluster. There are integrations and settings that workloads have in Kubernetes that can help the cluster scale. There are also architectural considerations with Kubernetes abstractions such as namespaces and services. + +== Extra large scaling + +If you are scaling a single cluster beyond 1000 nodes or 50,000 pods we would love to talk to you. We recommend reaching out to your support team or technical account manager to get in touch with specialists who can help you plan and scale beyond the information provided in this guide. + +include::control-plane.adoc[leveloffset=+1] + +include::data-plane.adoc[leveloffset=+1] + +include::cluster-services.adoc[leveloffset=+1] + +include::workloads.adoc[leveloffset=+1] + +include::scaling_theory.adoc[leveloffset=+1] + +include::kcp_monitoring.adoc[leveloffset=+1] + +include::node_efficiency.adoc[leveloffset=+1] + +include::kubernetes_slos.adoc[leveloffset=+1] + +include::quotas.adoc[leveloffset=+1] + diff --git a/latest/bpg/scalability/index.html b/latest/bpg/scalability/index.html new file mode 100644 index 000000000..ba88ef9f4 --- /dev/null +++ b/latest/bpg/scalability/index.html @@ -0,0 +1,3073 @@ + + + + + + + +EKS Scalability best practices + + + + +

+
+
+
+
+

This guide provides advice for scaling EKS clusters. The goal of scaling an EKS cluster is to maximize the amount of work a single cluster can perform. Using a single, large EKS cluster can reduce operational load compared to using multiple clusters, but it has trade-offs for things like multi-region deployments, tenant isolation, and cluster upgrades. In this document we will focus on how to achieve maximum scalability with a single cluster.

+
+
+
+
+

How to use this guide

+
+ +
+

Each topic has a brief overview, followed by recommendations and best practices for operating EKS clusters at scale. Topics do not need to be read in a particular order and recommendations should not be applied without testing and verifying they work in your clusters.

+
+
+
+
+

Understanding scaling dimensions

+
+
+

Scalability is different from performance and reliability, and all three should be considered when planning your cluster and workload needs. As clusters scale, they need to be monitored, but this guide will not cover monitoring best practices. EKS can scale to large sizes, but you will need to plan how you are going to scale a cluster beyond 300 nodes or 5000 pods. These are not absolute numbers, but they come from collaborating this guide with multiple users, engineers, and support professionals.

+
+
+

Scaling in Kubernetes is multi-dimensional and there are no specific settings or recommendations that work in every situation. The main areas areas where we can provide guidance for scaling include:

+
+ +
+

Kubernetes Control Plane in an EKS cluster includes all of the services AWS runs and scales for you automatically (e.g. Kubernetes API server). Scaling the Control Plane is AWS’s responsibility, but using the Control Plane responsibly is your responsibility.

+
+
+

Kubernetes Data Plane scaling deals with AWS resources that are required for your cluster and workloads, but they are outside of the EKS Control Plane. Resources including EC2 instances, kubelet, and storage all need to be scaled as your cluster scales.

+
+
+

Cluster services are Kubernetes controllers and applications that run inside the cluster and provide functionality for your cluster and workloads. These can be EKS Add-ons and also other services or Helm charts you install for compliance and integrations. These services are often depended on by workloads and as your workloads scale your cluster services will need to scale with them.

+
+
+

Workloads are the reason you have a cluster and should scale horizontally with the cluster. There are integrations and settings that workloads have in Kubernetes that can help the cluster scale. There are also architectural considerations with Kubernetes abstractions such as namespaces and services.

+
+
+
+
+

Extra large scaling

+
+
+

If you are scaling a single cluster beyond 1000 nodes or 50,000 pods we would love to talk to you. We recommend reaching out to your support team or technical account manager to get in touch with specialists who can help you plan and scale beyond the information provided in this guide.

+
+
+
+
+

Kubernetes Control Plane

+
+
+

The Kubernetes control plane consists of the Kubernetes API Server, Kubernetes Controller Manager, Scheduler and other components that are required for Kubernetes to function. Scalability limits of these components are different depending on what you’re running in the cluster, but the areas with the biggest impact to scaling include the Kubernetes version, utilization, and individual Node scaling.

+
+
+

Use EKS 1.24 or above

+
+

EKS 1.24 introduced a number of changes and switches the container runtime to containerd instead of docker. Containerd helps clusters scale by increasing individual node performance by limiting container runtime features to closely align with Kubernetes’ needs. Containerd is available in every supported version of EKS and if you would like to switch to containerd in versions prior to 1.24 please use the --container-runtime bootstrap flag.

+
+
+
+

Limit workload and node bursting

+
+

!!! Attention + To avoid reaching API limits on the control plane you should limit scaling spikes that increase cluster size by double digit percentages at a time (e.g. 1000 nodes to 1100 nodes or 4000 to 4500 pods at once).

+
+
+

The EKS control plane will automatically scale as your cluster grows, but there are limits on how fast it will scale. When you first create an EKS cluster the Control Plane will not immediately be able to scale to hundreds of nodes or thousands of pods. To read more about how EKS has made scaling improvements see this blog post.

+
+
+

Scaling large applications requires infrastructure to adapt to become fully ready (e.g. warming load balancers). To control the speed of scaling make sure you are scaling based on the right metrics for your application. CPU and memory scaling may not accurately predict your application constraints and using custom metrics (e.g. requests per second) in Kubernetes Horizontal Pod Autoscaler (HPA) may be a better scaling option.

+
+
+

To use a custom metric see the examples in the Kubernetes documentation. If you have more advanced scaling needs or need to scale based on external sources (e.g. AWS SQS queue) then use KEDA for event based workload scaling.

+
+
+
+

Scale nodes and pods down safely

+
+

Replace long running instances

+
+

Replacing nodes regularly keeps your cluster healthy by avoiding configuration drift and issues that only happen after extended uptime (e.g. slow memory leaks). Automated replacement will give you good process and practices for node upgrades and security patching. If every node in your cluster is replaced regularly then there is less toil required to maintain separate processes for ongoing maintenance.

+
+
+

Use Karpenter’s time to live (TTL) settings to replace instances after they’ve been running for a specified amount of time. Self managed node groups can use the max-instance-lifetime setting to cycle nodes automatically. Managed node groups do not currently have this feature but you can track the request here on GitHub.

+
+
+
+

Remove underutilized nodes

+
+

You can remove nodes when they have no running workloads using the scale down threshold in the Kubernetes Cluster Autoscaler with the --scale-down-utilization-threshold or in Karpenter you can use the ttlSecondsAfterEmpty provisioner setting.

+
+
+
+

Use pod disruption budgets and safe node shutdown

+
+

Removing pods and nodes from a Kubernetes cluster requires controllers to make updates to multiple resources (e.g. EndpointSlices). Doing this frequently or too quickly can cause API server throttling and application outages as changes propogate to controllers. Pod Disruption Budgets are a best practice to slow down churn to protect workload availability as nodes are removed or rescheduled in a cluster.

+
+
+
+
+

Use Client-Side Cache when running Kubectl

+
+

Using the kubectl command inefficiently can add additional load to the Kubernetes API Server. You should avoid running scripts or automation that uses kubectl repeatedly (e.g. in a for loop) or running commands without a local cache.

+
+
+

kubectl has a client-side cache that caches discovery information from the cluster to reduce the amount of API calls required. The cache is enabled by default and is refreshed every 10 minutes.

+
+
+

If you run kubectl from a container or without a client-side cache you may run into API throttling issues. It is recommended to retain your cluster cache by mounting the --cache-dir to avoid making uncessesary API calls.

+
+
+
+

Disable kubectl Compression

+
+

Disabling kubectl compression in your kubeconfig file can reduce API and client CPU usage. By default the server will compress data sent to the client to optimize network bandwidth. This adds CPU load on the client and server for every request and disabling compression can reduce the overhead and latency if you have adequate bandwidth. To disable compression you can use the --disable-compression=true flag or set disable-compression: true in your kubeconfig file.

+
+
+
+
apiVersion: v1
+clusters:
+- cluster:
+    server: serverURL
+    disable-compression: true
+  name: cluster
+
+
+
+
+

Shard Cluster Autoscaler

+
+

The Kubernetes Cluster Autoscaler has been tested to scale up to 1000 nodes. On a large cluster with more than 1000 nodes, it is recommended to run multiple instances of the Cluster Autoscaler in shard mode. Each Cluster Autoscaler instance is configured to scale a set of node groups. The following example shows 2 cluster autoscaling configurations that are configured to each scale 4 node groups.

+
+
+

ClusterAutoscaler-1

+
+
+
+
autoscalingGroups:
+- name: eks-core-node-grp-20220823190924690000000011-80c1660e-030d-476d-cb0d-d04d585a8fcb
+  maxSize: 50
+  minSize: 2
+- name: eks-data_m1-20220824130553925600000011-5ec167fa-ca93-8ca4-53a5-003e1ed8d306
+  maxSize: 450
+  minSize: 2
+- name: eks-data_m2-20220824130733258600000015-aac167fb-8bf7-429d-d032-e195af4e25f5
+  maxSize: 450
+  minSize: 2
+- name: eks-data_m3-20220824130553914900000003-18c167fa-ca7f-23c9-0fea-f9edefbda002
+  maxSize: 450
+  minSize: 2
+
+
+
+

ClusterAutoscaler-2

+
+
+
+
autoscalingGroups:
+- name: eks-data_m4-2022082413055392550000000f-5ec167fa-ca86-6b83-ae9d-1e07ade3e7c4
+  maxSize: 450
+  minSize: 2
+- name: eks-data_m5-20220824130744542100000017-02c167fb-a1f7-3d9e-a583-43b4975c050c
+  maxSize: 450
+  minSize: 2
+- name: eks-data_m6-2022082413055392430000000d-9cc167fa-ca94-132a-04ad-e43166cef41f
+  maxSize: 450
+  minSize: 2
+- name: eks-data_m7-20220824130553921000000009-96c167fa-ca91-d767-0427-91c879ddf5af
+  maxSize: 450
+  minSize: 2
+
+
+
+
+

API Priority and Fairness

+
+
+APF +
+
+
+

Overview

+
+

To protect itself from being overloaded during periods of increased requests, the API Server limits the number of inflight requests it can have outstanding at a given time. Once this limit is exceeded, the API Server will start rejecting requests and return a 429 HTTP response code for "Too Many Requests" back to clients. The server dropping requests and having clients try again later is preferable to having no server-side limits on the number of requests and overloading the control plane, which could result in degraded performance or unavailability.

+
+
+

The mechanism used by Kubernetes to configure how these inflights requests are divided among different request types is called API Priority and Fairness. The API Server configures the total number of inflight requests it can accept by summing together the values specified by the --max-requests-inflight and --max-mutating-requests-inflight flags. EKS uses the default values of 400 and 200 requests for these flags, allowing a total of 600 requests to be dispatched at a given time. However, as it scales the control-plane to larger sizes in response to increased utilization and workload churn, it correspondingly increases the inflight request quota all the way till 2000 (subject to change). APF specifies how these inflight request quota is further sub-divided among different request types. Note that EKS control planes are highly available with at least 2 API Servers registered to each cluster. This means the total number of inflight requests your cluster can handle is twice (or higher if horizontally scaled out further) the inflight quota set per kube-apiserver. This amounts to several thousands of requests/second on the largest EKS clusters.

+
+
+

Two kinds of Kubernetes objects, called PriorityLevelConfigurations and FlowSchemas, configure how the total number of requests is divided between different request types. These objects are maintained by the API Server automatically and EKS uses the default configuration of these objects for the given Kubernetes minor version. PriorityLevelConfigurations represent a fraction of the total number of allowed requests. For example, the workload-high PriorityLevelConfiguration is allocated 98 out of the total of 600 requests. The sum of requests allocated to all PriorityLevelConfigurations will equal 600 (or slightly above 600 because the API Server will round up if a given level is granted a fraction of a request). To check the PriorityLevelConfigurations in your cluster and the number of requests allocated to each, you can run the following command. These are the defaults on EKS 1.24:

+
+
+
+
$ kubectl get --raw /metrics | grep apiserver_flowcontrol_request_concurrency_limit
+apiserver_flowcontrol_request_concurrency_limit{priority_level="catch-all"} 13
+apiserver_flowcontrol_request_concurrency_limit{priority_level="global-default"} 49
+apiserver_flowcontrol_request_concurrency_limit{priority_level="leader-election"} 25
+apiserver_flowcontrol_request_concurrency_limit{priority_level="node-high"} 98
+apiserver_flowcontrol_request_concurrency_limit{priority_level="system"} 74
+apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-high"} 98
+apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245
+
+
+
+

The second type of object are FlowSchemas. API Server requests with a given set of properties are classified under the same FlowSchema. These properties include either the authenticated user or attributes of the request, such as the API group, namespace, or resource. A FlowSchema also specifies which PriorityLevelConfiguration this type of request should map to. The two objects together say, "I want this type of request to count towards this share of inflight requests." When a request hits the API Server, it will check each of its FlowSchemas until it finds one that matches all the required properties. If multiple FlowSchemas match a request, the API Server will choose the FlowSchema with the smallest matching precedence which is specified as a property in the object.

+
+
+

The mapping of FlowSchemas to PriorityLevelConfigurations can be viewed using this command:

+
+
+
+
$ kubectl get flowschemas
+NAME                           PRIORITYLEVEL     MATCHINGPRECEDENCE   DISTINGUISHERMETHOD   AGE     MISSINGPL
+exempt                         exempt            1                    <none>                7h19m   False
+eks-exempt                     exempt            2                    <none>                7h19m   False
+probes                         exempt            2                    <none>                7h19m   False
+system-leader-election         leader-election   100                  ByUser                7h19m   False
+endpoint-controller            workload-high     150                  ByUser                7h19m   False
+workload-leader-election       leader-election   200                  ByUser                7h19m   False
+system-node-high               node-high         400                  ByUser                7h19m   False
+system-nodes                   system            500                  ByUser                7h19m   False
+kube-controller-manager        workload-high     800                  ByNamespace           7h19m   False
+kube-scheduler                 workload-high     800                  ByNamespace           7h19m   False
+kube-system-service-accounts   workload-high     900                  ByNamespace           7h19m   False
+eks-workload-high              workload-high     1000                 ByUser                7h14m   False
+service-accounts               workload-low      9000                 ByUser                7h19m   False
+global-default                 global-default    9900                 ByUser                7h19m   False
+catch-all                      catch-all         10000                ByUser                7h19m   False
+
+
+
+

PriorityLevelConfigurations can have a type of Queue, Reject, or Exempt. For types Queue and Reject, a limit is enforced on the maximum number of inflight requests for that priority level, however, the behavior differs when that limit is reached. For example, the workload-high PriorityLevelConfiguration uses type Queue and has 98 requests available for use by the controller-manager, endpoint-controller, scheduler,eks related controllers and from pods running in the kube-system namespace. Since type Queue is used, the API Server will attempt to keep requests in memory and hope that the number of inflight requests drops below 98 before these requests time out. If a given request times out in the queue or if too many requests are already queued, the API Server has no choice but to drop the request and return the client a 429. Note that queuing may prevent a request from receiving a 429, but it comes with the tradeoff of increased end-to-end latency on the request.

+
+
+

Now consider the catch-all FlowSchema that maps to the catch-all PriorityLevelConfiguration with type Reject. If clients reach the limit of 13 inflight requests, the API Server will not exercise queuing and will drop the requests instantly with a 429 response code. Finally, requests mapping to a PriorityLevelConfiguration with type Exempt will never receive a 429 and always be dispatched immediately. This is used for high-priority requests such as healthz requests or requests coming from the system:masters group.

+
+
+
+

Monitoring APF and Dropped Requests

+
+

To confirm if any requests are being dropped due to APF, the API Server metrics for apiserver_flowcontrol_rejected_requests_total can be monitored to check the impacted FlowSchemas and PriorityLevelConfigurations. For example, this metric shows that 100 requests from the service-accounts FlowSchema were dropped due to requests timing out in workload-low queues:

+
+
+
+
% kubectl get --raw /metrics | grep apiserver_flowcontrol_rejected_requests_total
+apiserver_flowcontrol_rejected_requests_total{flow_schema="service-accounts",priority_level="workload-low",reason="time-out"} 100
+
+
+
+

To check how close a given PriorityLevelConfiguration is to receiving 429s or experiencing increased latency due to queuing, you can compare the difference between the concurrency limit and the concurrency in use. In this example, we have a buffer of 100 requests.

+
+
+
+
% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_limit.*workload-low'
+apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245
+
+% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_in_use.*workload-low'
+apiserver_flowcontrol_request_concurrency_in_use{flow_schema="service-accounts",priority_level="workload-low"} 145
+
+
+
+

To check if a given PriorityLevelConfiguration is experiencing queuing but not necessarily dropped requests, the metric for apiserver_flowcontrol_current_inqueue_requests can be referenced:

+
+
+
+
% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_current_inqueue_requests.*workload-low'
+apiserver_flowcontrol_current_inqueue_requests{flow_schema="service-accounts",priority_level="workload-low"} 10
+
+
+
+

Other useful Prometheus metrics include:

+
+
+
    +
  • +

    apiserver_flowcontrol_dispatched_requests_total

    +
  • +
  • +

    apiserver_flowcontrol_request_execution_seconds

    +
  • +
  • +

    apiserver_flowcontrol_request_wait_duration_seconds

    +
  • +
+
+
+

See the upstream documentation for a complete list of APF metrics.

+
+
+
+

Preventing Dropped Requests

+
+
Prevent 429s by changing your workload
+
+

When APF is dropping requests due to a given PriorityLevelConfiguration exceeding its maximum number of allowed inflight requests, clients in the affected FlowSchemas can decrease the number of requests executing at a given time. This can be accomplished by reducing the total number of requests made over the period where 429s are occurring. Note that long-running requests such as expensive list calls are especially problematic because they count as an inflight request for the entire duration they are executing. Reducing the number of these expensive requests or optimizing the latency of these list calls (for example, by reducing the number of objects fetched per request or switching to using a watch request) can help reduce the total concurrency required by the given workload.

+
+
+
+
Prevent 429s by changing your APF settings
+
+

!!! Warning + Only change default APF settings if you know what you are doing. Misconfigured APF settings can result in dropped API Server requests and significant workload disruptions.

+
+
+

One other approach for preventing dropped requests is changing the default FlowSchemas or PriorityLevelConfigurations installed on EKS clusters. EKS installs the upstream default settings for FlowSchemas and PriorityLevelConfigurations for the given Kubernetes minor version. The API Server will automatically reconcile these objects back to their defaults if modified unless the following annotation on the objects is set to false:

+
+
+
+
  metadata:
+    annotations:
+      apf.kubernetes.io/autoupdate-spec: "false"
+
+
+
+

At a high-level, APF settings can be modified to either:

+
+
+
    +
  • +

    Allocate more inflight capacity to requests you care about.

    +
  • +
  • +

    Isolate non-essential or expensive requests that can starve capacity for other request types.

    +
  • +
+
+
+

This can be accomplished by either changing the default FlowSchemas and PriorityLevelConfigurations or by creating new objects of these types. Operators can increase the values for assuredConcurrencyShares for the relevant PriorityLevelConfigurations objects to increase the fraction of inflight requests they are allocated. Additionally, the number of requests that can be queued at a given time can also be increased if the application can handle the additional latency caused by requests being queued before they are dispatched.

+
+
+

Alternatively, new FlowSchema and PriorityLevelConfigurations objects can be created that are specific to the customer’s workload. Be aware that allocating more assuredConcurrencyShares to either existing PriorityLevelConfigurations or to new PriorityLevelConfigurations will cause the number of requests that can be handled by other buckets to be reduced as the overall limit will stay as 600 inflight per API Server.

+
+
+

When making changes to APF defaults, these metrics should be monitored on a non-production cluster to ensure changing the settings do not cause unintended 429s:

+
+
+
    +
  1. +

    The metric for apiserver_flowcontrol_rejected_requests_total should be monitored for all FlowSchemas to ensure that no buckets start to drop requests.

    +
  2. +
  3. +

    The values for apiserver_flowcontrol_request_concurrency_limit and apiserver_flowcontrol_request_concurrency_in_use should be compared to ensure that the concurrency in use is not at risk for breaching the limit for that priority level.

    +
  4. +
+
+
+

One common use-case for defining a new FlowSchema and PriorityLevelConfiguration is for isolation. Suppose we want to isolate long-running list event calls from pods to their own share of requests. This will prevent important requests from pods using the existing service-accounts FlowSchema from receiving 429s and being starved of request capacity. Recall that the total number of inflight requests is finite, however, this example shows APF settings can be modified to better divide request capacity for the given workload:

+
+
+

Example FlowSchema object to isolate list event requests:

+
+
+
+
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
+kind: FlowSchema
+metadata:
+  name: list-events-default-service-accounts
+spec:
+  distinguisherMethod:
+    type: ByUser
+  matchingPrecedence: 8000
+  priorityLevelConfiguration:
+    name: catch-all
+  rules:
+  - resourceRules:
+    - apiGroups:
+      - '*'
+      namespaces:
+      - default
+      resources:
+      - events
+      verbs:
+      - list
+    subjects:
+    - kind: ServiceAccount
+      serviceAccount:
+        name: default
+        namespace: default
+
+
+
+
    +
  • +

    This FlowSchema captures all list event calls made by service accounts in the default namespace.

    +
  • +
  • +

    The matching precedence 8000 is lower than the value of 9000 used by the existing service-accounts FlowSchema so these list event calls will match list-events-default-service-accounts rather than service-accounts.

    +
  • +
  • +

    We’re using the catch-all PriorityLevelConfiguration to isolate these requests. This bucket only allows 13 inflight requests to be used by these long-running list event calls. Pods will start to receive 429s as soon they try to issue more than 13 of these requests concurrently.

    +
  • +
+
+
+
+
+
+

Retrieving resources in the API server

+
+

Getting information from the API server is an expected behavior for clusters of any size. As you scale the number of resources in the cluster the frequency of requests and volume of data can quickly become a bottleneck for the control plane and will lead to API latency and slowness. Depending on the severity of the latency it cause unexpected downtime if you are not careful.

+
+
+

Being aware of what you are requesting and how often are the first steps to avoiding these types of problems. Here is guidance to limit the volume of queries based on the scaling best practices. Suggestions in this section are provided in order starting with the options that are known to scale the best.

+
+
+

Use Shared Informers

+
+

When building controllers and automation that integrate with the Kubernetes API you will often need to get information from Kubernetes resources. If you poll for these resources regularly it can cause a significant load on the API server.

+
+
+

Using an informer from the client-go library will give you benefits of watching for changes to the resources based on events instead of polling for changes. Informers further reduce the load by using shared cache for the events and changes so multiple controllers watching the same resources do not add additional load.

+
+
+

Controllers should avoid polling cluster wide resources without labels and field selectors especially in large clusters. Each un-filtered poll requires a lot of unnecessary data to be sent from etcd through the API server to be filtered by the client. By filtering based on labels and namespaces you can reduce the amount of work the API server needs to perform to fullfil the request and data sent to the client.

+
+
+
+

Optimize Kubernetes API usage

+
+

When calling the Kubernetes API with custom controllers or automation it’s important that you limit the calls to only the resources you need. Without limits you can cause unneeded load on the API server and etcd.

+
+
+

It is recommended that you use the watch argument whenever possible. With no arguments the default behavior is to list objects. To use watch instead of list you can append ?watch=true to the end of your API request. For example, to get all pods in the default namespace with a watch use:

+
+
+
+
/api/v1/namespaces/default/pods?watch=true
+
+
+
+

If you are listing objects you should limit the scope of what you are listing and the amount of data returned. You can limit the returned data by adding limit=500 argument to requests. The fieldSelector argument and /namespace/ path can be useful to make sure your lists are as narrowly scoped as needed. For example, to list only running pods in the default namespace use the following API path and arguments.

+
+
+
+
/api/v1/namespaces/default/pods?fieldSelector=status.phase=Running&limit=500
+
+
+
+

Or list all pods that are running with:

+
+
+
+
/api/v1/pods?fieldSelector=status.phase=Running&limit=500
+
+
+
+

Another option to limit watch calls or listed objects is to use resourceVersions which you can read about in the Kubernetes documentation. Without a resourceVersion argument you will receive the most recent version available which requires an etcd quorum read which is the most expensive and slowest read for the database. The resourceVersion depends on what resources you are trying to query and can be found in the metadata.resourseVersion field. This is also recommended in case of using watch calls and not just list calls

+
+
+

There is a special resourceVersion=0 available that will return results from the API server cache. This can reduce etcd load but it does not support pagination.

+
+
+
+
/api/v1/namespaces/default/pods?resourceVersion=0
+
+
+
+

It’s recommended to use watch with a resourceVersion set to be the most recent known value received from its preceding list or watch. This is handled automatically in client-go. But it’s suggested to double check it if you are using a k8s client in other languages.

+
+
+
+
/api/v1/namespaces/default/pods?watch=true&resourceVersion=362812295
+
+
+
+

If you call the API without any arguments it will be the most resource intensive for the API server and etcd. This call will get all pods in all namespaces without pagination or limiting the scope and require a quorum read from etcd.

+
+
+
+
/api/v1/pods
+
+
+
+
+
+
+
+

Kubernetes Data Plane

+
+
+

The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped cluster services in a separate page and load balancer scaling can be found in the workloads section. This section will focus on scaling compute resources.

+
+
+

Selecting EC2 instance types is possibly one of the hardest decisions customers face because in clusters with multiple workloads. There is no one-size-fits all solution. Here are some tips to help you avoid common pitfalls with scaling compute.

+
+
+

Automatic node autoscaling

+
+

We recommend you use node autoscaling that reduces toil and integrates deeply with Kubernetes. Managed node groups and Karpenter are recommended for large scale clusters.

+
+
+

Managed node groups will give you the flexibility of Amazon EC2 Auto Scaling groups with added benefits for managed upgrades and configuration. It can be scaled with the Kubernetes Cluster Autoscaler and is a common option for clusters that have a variety of compute needs.

+
+
+

Karpenter is an open source, workload-native node autoscaler created by AWS. It scales nodes in a cluster based on the workload requirements for resources (e.g. GPU) and taints and tolerations (e.g. zone spread) without managing node groups. Nodes are created directly from EC2 which avoids default node group quotas—​450 nodes per group—​and provides greater instance selection flexibility with less operational overhead. We recommend customers use Karpenter when possible.

+
+
+
+

Use many different EC2 instance types

+
+

Each AWS region has a limited number of available instances per instance type. If you create a cluster that uses only one instance type and scale the number of nodes beyond the capacity of the region you will receive an error that no instances are available. To avoid this issue you should not arbitrarily limit the type of instances that can be use in your cluster.

+
+
+

Karpenter will use a broad set of compatible instance types by default and will pick an instance at provisioning time based on pending workload requirements, availability, and cost. You can broaden the list of instance types used in the karpenter.k8s.aws/instance-category key of NodePools.

+
+
+

The Kubernetes Cluster Autoscaler requires node groups to be similarly sized so they can be consistently scaled. You should create multiple groups based on CPU and memory size and scale them independently. Use the ec2-instance-selector to identify instances that are similarly sized for your node groups.

+
+
+
+
ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16
+a1.2xlarge
+a1.4xlarge
+a1.metal
+c4.4xlarge
+c4.8xlarge
+c5.12xlarge
+c5.18xlarge
+c5.24xlarge
+c5.2xlarge
+c5.4xlarge
+c5.9xlarge
+c5.metal
+
+
+
+
+

Prefer larger nodes to reduce API server load

+
+

When deciding what instance types to use, fewer, large nodes will put less load on the Kubernetes Control Plane because there will be fewer kubelets and DaemonSets running. However, large nodes may not be utilized fully like smaller nodes. Node sizes should be evaluated based on your workload availability and scale requirements.

+
+
+

A cluster with three u-24tb1.metal instances (24 TB memory and 448 cores) has 3 kubelets, and would be limited to 110 pods per node by default. If your pods use 4 cores each then this might be expected (4 cores x 110 = 440 cores/node). With a 3 node cluster your ability to handle an instance incident would be low because 1 instance outage could impact 1/3 of the cluster. You should specify node requirements and pod spread in your workloads so the Kubernetes scheduler can place workloads properly.

+
+
+

Workloads should define the resources they need and the availability required via taints, tolerations, and PodTopologySpread. They should prefer the largest nodes that can be fully utilized and meet availability goals to reduce control plane load, lower operations, and reduce cost.

+
+
+

The Kubernetes Scheduler will automatically try to spread workloads across availability zones and hosts if resources are available. If no capacity is available the Kubernetes Cluster Autoscaler will attempt to add nodes in each Availability Zone evenly. Karpenter will attempt to add nodes as quickly and cheaply as possible unless the workload specifies other requirements.

+
+
+

To force workloads to spread with the scheduler and new nodes to be created across availability zones you should use topologySpreadConstraints:

+
+
+
+
spec:
+  topologySpreadConstraints:
+    - maxSkew: 3
+      topologyKey: "topology.kubernetes.io/zone"
+      whenUnsatisfiable: ScheduleAnyway
+      labelSelector:
+        matchLabels:
+          dev: my-deployment
+    - maxSkew: 2
+      topologyKey: "kubernetes.io/hostname"
+      whenUnsatisfiable: ScheduleAnyway
+      labelSelector:
+        matchLabels:
+          dev: my-deployment
+
+
+
+
+

Use similar node sizes for consistent workload performance

+
+

Workloads should define what size nodes they need to be run on to allow consistent performance and predictable scaling. A workload requesting 500m CPU will perform differently on an instance with 4 cores vs one with 16 cores. Avoid instance types that use burstable CPUs like T series instances.

+
+
+

To make sure your workloads get consistent performance a workload can use the supported Karpenter labels to target specific instances sizes.

+
+
+
+
kind: deployment
+...
+spec:
+  template:
+    spec:
+    containers:
+    nodeSelector:
+      karpenter.k8s.aws/instance-size: 8xlarge
+
+
+
+

Workloads being scheduled in a cluster with the Kubernetes Cluster Autoscaler should match a node selector to node groups based on label matching.

+
+
+
+
spec:
+  affinity:
+    nodeAffinity:
+      requiredDuringSchedulingIgnoredDuringExecution:
+        nodeSelectorTerms:
+        - matchExpressions:
+          - key: eks.amazonaws.com/nodegroup
+            operator: In
+            values:
+            - 8-core-node-group    # match your node group name
+
+
+
+
+

Use compute resources efficiently

+
+

Compute resources include EC2 instances and availability zones. Using compute resources effectively will increase your scalability, availability, performance, and reduce your total cost. Efficient resource usage is extremely difficult to predict in an autoscaling environment with multiple applications. Karpenter was created to provision instances on-demand based on the workload needs to maximize utilization and flexibility.

+
+
+

Karpenter allows workloads to declare the type of compute resources it needs without first creating node groups or configuring label taints for specific nodes. See the Karpenter best practices for more information. Consider enabling consolidation in your Karpenter provisioner to replace nodes that are under utilized.

+
+
+
+

Automate Amazon Machine Image (AMI) updates

+
+

Keeping worker node components up to date will make sure you have the latest security patches and compatible features with the Kubernetes API. Updating the kubelet is the most important component for Kubernetes functionality, but automating OS, kernel, and locally installed application patches will reduce maintenance as you scale.

+
+
+

It is recommended that you use the latest Amazon EKS optimized Amazon Linux 2 or Amazon EKS optimized Bottlerocket AMI for your node image. Karpenter will automatically use the latest available AMI to provision new nodes in the cluster. Managed node groups will update the AMI during a node group update but will not update the AMI ID at node provisioning time.

+
+
+

For Managed Node Groups you need to update the Auto Scaling Group (ASG) launch template with new AMI IDs when they are available for patch releases. AMI minor versions (e.g. 1.23.5 to 1.24.3) will be available in the EKS console and API as upgrades for the node group. Patch release versions (e.g. 1.23.5 to 1.23.6) will not be presented as upgrades for the node groups. If you want to keep your node group up to date with AMI patch releases you need to create new launch template version and let the node group replace instances with the new AMI release.

+
+
+

You can find the latest available AMI from this page or use the AWS CLI.

+
+
+
+
aws ssm get-parameter \
+  --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \
+  --query "Parameter.Value" \
+  --output text
+
+
+
+
+

Use multiple EBS volumes for containers

+
+

EBS volumes have input/output (I/O) quota based on the type of volume (e.g. gp3) and the size of the disk. If your applications share a single EBS root volume with the host this can exhaust the disk quota for the entire host and cause other applications to wait for available capacity. Applications write to disk if they write files to their overlay partition, mount a local volume from the host, and also when they log to standard out (STDOUT) depending on the logging agent used.

+
+
+

To avoid disk I/O exhaustion you should mount a second volume to the container state folder (e.g. /run/containerd), use separate EBS volumes for workload storage, and disable unnecessary local logging.

+
+
+

To mount a second volume to your EC2 instances using eksctl you can use a node group with this configuration:

+
+
+
+
managedNodeGroups:
+  - name: al2-workers
+    amiFamily: AmazonLinux2
+    desiredCapacity: 2
+    volumeSize: 80
+    additionalVolumes:
+      - volumeName: '/dev/sdz'
+        volumeSize: 100
+    preBootstrapCommands:
+    - |
+      "systemctl stop containerd"
+      "mkfs -t ext4 /dev/nvme1n1"
+      "rm -rf /var/lib/containerd/*"
+      "mount /dev/nvme1n1 /var/lib/containerd/"
+      "systemctl start containerd"
+
+
+
+

If you are using terraform to provision your node groups please see examples in EKS Blueprints for terraform. If you are using Karpenter to provision nodes you can use blockDeviceMappings with node user-data to add additional volumes.

+
+
+

To mount an EBS volume directly to your pod you should use the AWS EBS CSI driver and consume a volume with a storage class.

+
+
+
+
---
+apiVersion: storage.k8s.io/v1
+kind: StorageClass
+metadata:
+  name: ebs-sc
+provisioner: ebs.csi.aws.com
+volumeBindingMode: WaitForFirstConsumer
+---
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: ebs-claim
+spec:
+  accessModes:
+    - ReadWriteOnce
+  storageClassName: ebs-sc
+  resources:
+    requests:
+      storage: 4Gi
+---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: app
+spec:
+  containers:
+  - name: app
+    image: public.ecr.aws/docker/library/nginx
+    volumeMounts:
+    - name: persistent-storage
+      mountPath: /data
+  volumes:
+  - name: persistent-storage
+    persistentVolumeClaim:
+      claimName: ebs-claim
+
+
+
+
+

Avoid instances with low EBS attach limits if workloads use EBS volumes

+
+

EBS is one of the easiest ways for workloads to have persistent storage, but it also comes with scalability limitations. Each instance type has a maximum number of EBS volumes that can be attached. Workloads need to declare what instance types they should run on and limit the number of replicas on a single instance with Kubernetes taints.

+
+
+
+

Disable unnecessary logging to disk

+
+

Avoid unnecessary local logging by not running your applications with debug logging in production and disabling logging that reads and writes to disk frequently. Journald is the local logging service that keeps a log buffer in memory and flushes to disk periodically. Journald is preferred over syslog which logs every line immediately to disk. Disabling syslog also lowers the total amount of storage you need and avoids needing complicated log rotation rules. To disable syslog you can add the following snippet to your cloud-init configuration:

+
+
+
+
runcmd:
+  - [ systemctl, disable, --now, syslog.service ]
+
+
+
+
+

Patch instances in place when OS update speed is a necessity

+
+

!!! Attention + Patching instances in place should only be done when required. Amazon recommends treating infrastructure as immutable and thoroughly testing updates that are promoted through lower environments the same way applications are. This section applies when that is not possible.

+
+
+

It takes seconds to install a package on an existing Linux host without disrupting containerized workloads. The package can be installed and validated without cordoning, draining, or replacing the instance.

+
+
+

To replace an instance you first need to create, validate, and distribute new AMIs. The instance needs to have a replacement created, and the old instance needs to be cordoned and drained. Then workloads need to be created on the new instance, verified, and repeated for all instances that need to be patched. It takes hours, days, or weeks to replace instances safely without disrupting workloads.

+
+
+

Amazon recommends using immutable infrastructure that is built, tested, and promoted from an automated, declarative system, but if you have a requirement to patch systems quickly then you will need to patch systems in place and replace them as new AMIs are made available. Because of the large time differential between patching and replacing systems we recommend using AWS Systems Manager Patch Manager to automate patching nodes when required to do so.

+
+
+

Patching nodes will allow you to quickly roll out security updates and replace the instances on a regular schedule after your AMI has been updated. If you are using an operating system with a read-only root file system like Flatcar Container Linux or Bottlerocket OS we recommend using the update operators that work with those operating systems. The Flatcar Linux update operator and Bottlerocket update operator will reboot instances to keep nodes up to date automatically.

+
+
+
+
+
+

Cluster Services

+
+
+

Cluster services run inside an EKS cluster, but they are not user workloads. If you have a Linux server you often need to run services like NTP, syslog, and a container runtime to support your workloads. Cluster services are similar, supporting services that help you automate and operate your cluster. In Kubernetes these are usually run in the kube-system namespace and some are run as DaemonSets.

+
+
+

Cluster services are expected to have a high up-time and are often critical during outages and for troubleshooting. If a core cluster service is not available you may lose access to data that can help recover or prevent an outage (e.g. high disk utilization). They should run on dedicated compute instances such as a separate node group or AWS Fargate. This will ensure that the cluster services are not impacted on shared instances by workloads that may be scaling up or using more resources.

+
+
+

Scale CoreDNS

+
+

Scaling CoreDNS has two primary mechanisms. Reducing the number of calls to the CoreDNS service and increasing the number of replicas.

+
+
+

Reduce external queries by lowering ndots

+
+

The ndots setting specifies how many periods (a.k.a. "dots") in a domain name are considered enough to avoid querying DNS. If your application has an ndots setting of 5 (default) and you request resources from an external domain such as api.example.com (2 dots) then CoreDNS will be queried for each search domain defined in /etc/resolv.conf for a more specific domain. By default the following domains will be searched before making an external request.

+
+
+
+
api.example.<namespace>.svc.cluster.local
+api.example.svc.cluster.local
+api.example.cluster.local
+api.example.<region>.compute.internal
+
+
+
+

The namespace and region values will be replaced with your workloads namespace and your compute region. You may have additional search domains based on your cluster settings.

+
+
+

You can reduce the number of requests to CoreDNS by lowering the ndots option of your workload or fully qualifying your domain requests by including a trailing . (e.g. api.example.com. ). If your workload connects to external services via DNS we recommend setting ndots to 2 so workloads do not make unnecessary, cluster DNS queries inside the cluster. You can set a different DNS server and search domain if the workload doesn’t require access to services inside the cluster.

+
+
+
+
spec:
+  dnsPolicy: "None"
+  dnsConfig:
+    options:
+      - name: ndots
+        value: "2"
+      - name: edns0
+
+
+
+

If you lower ndots to a value that is too low or the domains you are connecting to do not include enough specificity (including trailing .) then it is possible DNS lookups will fail. Make sure you test how this setting will impact your workloads.

+
+
+
+

Scale CoreDNS Horizontally

+
+

CoreDNS instances can scale by adding additional replicas to the deployment. It’s recommended you use NodeLocal DNS or the cluster proportional autoscaler to scale CoreDNS.

+
+
+

NodeLocal DNS will require run one instance per node—​as a DaemonSet—​which requires more compute resources in the cluster, but it will avoid failed DNS requests and decrease the response time for DNS queries in the cluster. The cluster proportional autoscaler will scale CoreDNS based on the number of nodes or cores in the cluster. This isn’t a direct correlation to request queries, but can be useful depending on your workloads and cluster size. The default proportional scale is to add an additional replica for every 256 cores or 16 nodes in the cluster—​whichever happens first.

+
+
+
+
+

Scale Kubernetes Metrics Server Vertically

+
+

The Kubernetes Metrics Server supports horizontal and vertical scaling. By horizontally scaling the Metrics Server it will be highly available, but it will not scale horizontally to handle more cluster metrics. You will need to vertically scale the Metrics Server based on their recommendations as nodes and collected metrics are added to the cluster.

+
+
+

The Metrics Server keeps the data it collects, aggregates, and serves in memory. As a cluster grows, the amount of data the Metrics Server stores increases. In large clusters the Metrics Server will require more compute resources than the memory and CPU reservation specified in the default installation. You can use the Vertical Pod Autoscaler (VPA) or Addon Resizer to scale the Metrics Server. The Addon Resizer scales vertically in proportion to worker nodes and VPA scales based on CPU and memory usage.

+
+
+
+

CoreDNS lameduck duration

+
+

Pods use the kube-dns Service for name resolution. Kubernetes uses destination NAT (DNAT) to redirect kube-dns traffic from nodes to CoreDNS backend pods. As you scale the CoreDNS Deployment, kube-proxy updates iptables rules and chains on nodes to redirect DNS traffic to CoreDNS pods. Propagating new endpoints when you scale up and deleting rules when you scale down CoreDNS can take between 1 to 10 seconds depending on the size of the cluster.

+
+
+

This propagation delay can cause DNS lookup failures when a CoreDNS pod gets terminated yet the node’s iptables rules haven’t been updated. In this scenario, the node may continue to send DNS queries to a terminated CoreDNS Pod.

+
+
+

You can reduce DNS lookup failures by setting a lameduck duration in your CoreDNS pods. While in lameduck mode, CoreDNS will continue to respond to in-flight requests. Setting a lameduck duration will delay the CoreDNS shutdown process, allowing nodes the time they need to update their iptables rules and chains.

+
+
+

We recommend setting CoreDNS lameduck duration to 30 seconds.

+
+
+
+

CoreDNS readiness probe

+
+

We recommend using /ready instead of /health for CoreDNS’s readiness probe.

+
+
+

In alignment with the earlier recommendation to set the lameduck duration to 30 seconds, providing ample time for the node’s iptables rules to be updated before pod termination, employing /ready instead of /health for the CoreDNS readiness probe ensures that the CoreDNS pod is fully prepared at startup to promptly respond to DNS requests.

+
+
+
+
readinessProbe:
+  httpGet:
+    path: /ready
+    port: 8181
+    scheme: HTTP
+
+
+
+

For more information about the CoreDNS Ready plugin please refer to https://coredns.io/plugins/ready/

+
+
+
+

Logging and monitoring agents

+
+

Logging and monitoring agents can add significant load to your cluster control plane because the agents query the API server to enrich logs and metrics with workload metadata. The agent on a node only has access to the local node resources to see things like container and process name. Querying the API server it can add more details such as Kubernetes deployment name and labels. This can be extremely helpful for troubleshooting but detrimental to scaling.

+
+
+

Because there are so many different options for logging and monitoring we cannot show examples for every provider. With fluentbit we recommend enabling Use_Kubelet to fetch metadata from the local kubelet instead of the Kubernetes API Server and set Kube_Meta_Cache_TTL to a number that reduces repeated calls when data can be cached (e.g. 60).

+
+
+

Scaling monitoring and logging has two general options:

+
+
+
    +
  • +

    Disable integrations

    +
  • +
  • +

    Sampling and filtering

    +
  • +
+
+
+

Disabling integrations is often not an option because you lose log metadata. This eliminates the API scaling problem, but it will introduce other issues by not having the required metadata when needed.

+
+
+

Sampling and filtering reduces the number of metrics and logs that are collected. This will lower the amount of requests to the Kubernetes API, and it will reduce the amount of storage needed for the metrics and logs that are collected. Reducing the storage costs will lower the cost for the overall system.

+
+
+

The ability to configure sampling depends on the agent software and can be implemented at different points of ingestion. It’s important to add sampling as close to the agent as possible because that is likely where the API server calls happen. Contact your provider to find out more about sampling support.

+
+
+

If you are using CloudWatch and CloudWatch Logs you can add agent filtering using patterns described in the documentation.

+
+
+

To avoid losing logs and metrics you should send your data to a system that can buffer data in case of an outage on the receiving endpoint. With fluentbit you can use Amazon Kinesis Data Firehose to temporarily keep data which can reduce the chance of overloading your final data storage location.

+
+
+
+
+
+

Workloads

+
+
+

Workloads have an impact on how large your cluster can scale. Workloads that use the Kubernetes APIs heavily will limit the total amount of workloads you can have in a single cluster, but there are some defaults you can change to help reduce the load.

+
+
+

Workloads in a Kubernetes cluster have access to features that integrate with the Kubernetes API (e.g. Secrets and ServiceAccounts), but these features are not always required and should be disabled if they’re not being used. Limiting workload access and dependence on the Kubernetes control plane will increase the number of workloads you can run in the cluster and improve the security of your clusters by removing unnecessary access to workloads and implementing least privilege practices. Please read the security best practices for more information.

+
+
+

Use IPv6 for pod networking

+
+

You cannot transition a VPC from IPv4 to IPv6 so enabling IPv6 before provisioning a cluster is important. If you enable IPv6 in a VPC it does not mean you have to use it and if your pods and services use IPv6 you can still route traffic to and from IPv4 addresses. Please see the EKS networking best practices for more information.

+
+
+

Using IPv6 in your cluster avoids some of the most common cluster and workload scaling limits. IPv6 avoids IP address exhaustion where pods and nodes cannot be created because no IP address is available. It also has per node performance improvements because pods receive IP addresses faster by reducing the number of ENI attachments per node. You can achieve similar node performance by using IPv4 prefix mode in the VPC CNI, but you still need to make sure you have enough IP addresses available in the VPC.

+
+
+
+

Limit number of services per namespace

+
+

The maximum number of services in a namespaces is 5,000 and the maximum number of services in a cluster is 10,000. To help organize workloads and services, increase performance, and to avoid cascading impact for namespace scoped resources we recommend limiting the number of services per namespace to 500.

+
+
+

The number of IP tables rules that are created per node with kube-proxy grows with the total number of services in the cluster. Generating thousands of IP tables rules and routing packets through those rules have a performance impact on the nodes and add network latency.

+
+
+

Create Kubernetes namespaces that encompass a single application environment so long as the number of services per namespace is under 500. This will keep service discovery small enough to avoid service discovery limits and can also help you avoid service naming collisions. Applications environments (e.g. dev, test, prod) should use separate EKS clusters instead of namespaces.

+
+
+
+

Understand Elastic Load Balancer Quotas

+
+

When creating your services consider what type of load balancing you will use (e.g. Network Load Balancer (NLB) or Application Load Balancer (ALB)). Each load balancer type provides different functionality and have different quotas. Some of the default quotas can be adjusted, but there are some quota maximums which cannot be changed. To view your account quotas and usage view the Service Quotas dashboard in the AWS console.

+
+
+

For example, the default ALB targets is 1000. If you have a service with more than 1000 endpoints you will need to increase the quota or split the service across multiple ALBs or use Kubernetes Ingress. The default NLB targets is 3000, but is limited to 500 targets per AZ. If your cluster runs more than 500 pods for an NLB service you will need to use multiple AZs or request a quota limit increase.

+
+
+

An alternative to using a load balancer coupled to a service is to use an ingress controller. The AWS Load Balancer controller can create ALBs for ingress resources, but you may consider running a dedicated controller in your cluster. An in-cluster ingress controller allows you to expose multiple Kubernetes services from a single load balancer by running a reverse proxy inside your cluster. Controllers have different features such as support for the Gateway API which may have benefits depending on how many and how large your workloads are.

+
+
+
+

Use Route 53, Global Accelerator, or CloudFront

+
+

To make a service using multiple load balancers available as a single endpoint you need to use Amazon CloudFront, AWS Global Accelerator, or Amazon Route 53 to expose all of the load balancers as a single, customer facing endpoint. Each options has different benefits and can be used separately or together depending on your needs.

+
+
+

Route 53 can expose multiple load balancers under a common name and can send traffic to each of them based on the weight assigned. You can read more about DNS weights in the documentation and you can read how to implement them with the Kubernetes external DNS controller in the AWS Load Balancer Controller documentation.

+
+
+

Global Accelerator can route workloads to the nearest region based on request IP address. This may be useful for workloads that are deployed to multiple regions, but it does not improve routing to a single cluster in a single region. Using Route 53 in combination with the Global Accelerator has additional benefits such as health checking and automatic failover if an AZ is not available. You can see an example of using Global Accelerator with Route 53 in this blog post.

+
+
+

CloudFront can be use with Route 53 and Global Accelerator or by itself to route traffic to multiple destinations. CloudFront caches assets being served from the origin sources which may reduce bandwidth requirements depending on what you are serving.

+
+
+
+

Use EndpointSlices instead of Endpoints

+
+

When discovering pods that match a service label you should use EndpointSlices instead of Endpoints. Endpoints were a simple way to expose services at small scales but large services that automatically scale or have updates causes a lot of traffic on the Kubernetes control plane. EndpointSlices have automatic grouping which enable things like topology aware hints.

+
+
+

Not all controllers use EndpointSlices by default. You should verify your controller settings and enable it if needed. For the AWS Load Balancer Controller you should enable the --enable-endpoint-slices optional flag to use EndpointSlices.

+
+
+
+

Use immutable and external secrets if possible

+
+

The kubelet keeps a cache of the current keys and values for the Secrets that are used in volumes for pods on that node. The kubelet sets a watch on the Secrets to detect changes. As the cluster scales, the growing number of watches can negatively impact the API server performance.

+
+
+

There are two strategies to reduce the number of watches on Secrets:

+
+
+
    +
  • +

    For applications that don’t need access to Kubernetes resources, you can disable auto-mounting service account secrets by setting automountServiceAccountToken: false

    +
  • +
  • +

    If your application’s secrets are static and will not be modified in the future, mark the secret as immutable. The kubelet does not maintain an API watch for immutable secrets.

    +
  • +
+
+
+

To disable automatically mounting a service account to pods you can use the following setting in your workload. You can override these settings if specific workloads need a service account.

+
+
+
+
apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: app
+automountServiceAccountToken: true
+
+
+
+

Monitor the number of secrets in the cluster before it exceeds the limit of 10,000. You can see a total count of secrets in a cluster with the following command. You should monitor this limit through your cluster monitoring tooling.

+
+
+
+
kubectl get secrets -A | wc -l
+
+
+
+

You should set up monitoring to alert a cluster admin before this limit is reached. Consider using external secrets management options such as AWS Key Management Service (AWS KMS) or Hashicorp Vault with the Secrets Store CSI driver.

+
+
+
+

Limit Deployment history

+
+

Pods can be slow when creating, updating, or deleting because old objects are still tracked in the cluster. You can reduce the revisionHistoryLimit of deployments to cleanup older ReplicaSets which will lower to total amount of objects tracked by the Kubernetes Controller Manager. The default history limit for Deployments in 10.

+
+
+

If your cluster creates a lot of job objects through CronJobs or other mechanisms you should use the ttlSecondsAfterFinished setting to automatically clean up old pods in the cluster. This will remove successfully executed jobs from the job history after a specified amount of time.

+
+
+
+ +
+

When a Pod runs on a Node, the kubelet adds a set of environment variables for each active Service. Linux processes have a maximum size for their environment which can be reached if you have too many services in your namespace. The number of services per namespace should not exceed 5,000. After this, the number of service environment variables outgrows shell limits, causing Pods to crash on startup.

+
+
+

There are other reasons pods should not use service environment variables for service discovery. Environment variable name clashes, leaking service names, and total environment size are a few. You should use CoreDNS for discovering service endpoints.

+
+
+
+

Limit dynamic admission webhooks per resource

+
+

Dynamic Admission Webhooks include admission webhooks and mutating webhooks. They are API endpoints not part of the Kubernetes Control Plane that are called in sequence when a resource is sent to the Kubernetes API. Each webhook has a default timeout of 10 seconds and can increase the amount of time an API request takes if you have multiple webhooks or any of them timeout.

+
+
+

Make sure your webhooks are highly available—​especially during an AZ incident—​and the failurePolicy is set properly to reject the resource or ignore the failure. Do not call webhooks when not needed by allowing --dry-run kubectl commands to bypass the webhook.

+
+
+
+
apiVersion: admission.k8s.io/v1
+kind: AdmissionReview
+request:
+  dryRun: False
+
+
+
+

Mutating webhooks can modify resources in frequent succession. If you have 5 mutating webhooks and deploy 50 resources etcd will store all versions of each resource until compaction runs—​every 5 minutes—​to remove old versions of modified resources. In this scenario when etcd removes superseded resources there will be 200 resource version removed from etcd and depending on the size of the resources may use considerable space on the etcd host until defragmentation runs every 15 minutes.

+
+
+

This defragmentation may cause pauses in etcd which could have other affects on the Kubernetes API and controllers. You should avoid frequent modification of large resources or modifying hundreds of resources in quick succession.

+
+
+
+
+
+

Kubernetes Scaling Theory

+
+
+

Nodes vs. Churn Rate

+
+

Often when we discuss the scalability of Kubernetes, we do so in terms of how many nodes there are in a single cluster. Interestingly, this is seldom the most useful metric for understanding scalability. For example, a 5,000 node cluster with a large but fixed number of pods would not put a great deal of stress on the control plane after the initial setup. However, if we took a 1,000 node cluster and tried creating 10,000 short lived jobs in less than a minute, it would put a great deal of sustained pressure on the control plane.

+
+
+

Simply using the number of nodes to understand scaling can be misleading. It’s better to think in terms of the rate of change that occurs within a specific period of time (let’s use a 5 minute interval for this discussion, as this is what Prometheus queries typically use by default). Let’s explore why framing the problem in terms of the rate of change can give us a better idea of what to tune to achieve our desired scale.

+
+
+
+

Thinking in Queries Per Second

+
+

Kubernetes has a number of protection mechanisms for each component - the Kubelet, Scheduler, Kube Controller Manager, and API server - to prevent overwhelming the next link in the Kubernetes chain. For example, the Kubelet has a flag to throttle calls to the API server at a certain rate. These protection mechanisms are generally, but not always, expressed in terms of queries allowed on a per second basis or QPS.

+
+
+

Great care must be taken when changing these QPS settings. Removing one bottleneck, such as the queries per second on a Kubelet will have an impact on other down stream components. This can and will overwhelm the system above a certain rate, so understanding and monitoring each part of the service chain is key to successfully scaling workloads on Kubernetes.

+
+
+

!!! note + The API server has a more complex system with introduction of API Priority and Fairness which we will discuss separately.

+
+
+

!!! note + Caution, some metrics seem like the right fit but are in fact measuring something else. As an example, kubelet_http_inflight_requests relates to just the metrics server in Kubelet, not the number of requests from Kubelet to apiserver requests. This could cause us to misconfigure the QPS flag on the Kubelet. A query on audit logs for a particular Kubelet would be a more reliable way to check metrics.

+
+
+
+

Scaling Distributed Components

+
+

Since EKS is a managed service, let’s split the Kubernetes components into two categories: AWS managed components which include etcd, Kube Controller Manager, and the Scheduler (on the left part of diagram), and customer configurable components such as the Kubelet, Container Runtime, and the various operators that call AWS APIs such as the Networking and Storage drivers (on the right part of diagram). We leave the API server in the middle even though it is AWS managed, as the settings for API Priority and Fairness can be configured by customers.

+
+
+
+Kubernetes components +
+
+
+
+

Upstream and Downstream Bottlenecks

+
+

As we monitor each service, it’s important to look at metrics in both directions to look for bottlenecks. Let’s learn how to do this by using Kubelet as an example. Kubelet talks both to the API server and the container runtime; how and what do we need to monitor to detect whether either component is experiencing an issue?

+
+
+

How many Pods per Node

+
+

When we look at scaling numbers, such as how many pods can run on a node, we could take the 110 pods per node that upstream supports at face value.

+
+ +
+

However, your workload is likely more complex than what was tested in a scalability test in Upstream. To ensure we can service the number of pods we want to run in production, let’s make sure that the Kubelet is “keeping up” with the Containerd runtime.

+
+
+
+Keeping up +
+
+
+

To oversimplify, the Kubelet is getting the status of the pods from the container runtime (in our case Containerd). What if we had too many pods changing status too quickly? If the rate of change is too high, requests [to the container runtime] can timeout.

+
+
+

!!! note + Kubernetes is constantly evolving, this subsystem is currently undergoing changes. https://github.com/kubernetes/enhancements/issues/3386

+
+
+

Flow +PLEG duration

+
+
+

In the graph above, we see a flat line indicating we have just hit the timeout value for the pod lifecycle event generation duration metric. If you would like to see this in your own cluster you could use the following PromQL syntax.

+
+
+
+
increase(kubelet_pleg_relist_duration_seconds_bucket{instance="$instance"}[$__rate_interval])
+
+
+
+

If we witness this timeout behavior, we know we pushed the node over the limit it was capable of. We need to fix the cause of the timeout before proceeding further. This could be achieved by reducing the number of pods per node, or looking for errors that might be causing a high volume of retries (thus effecting the churn rate). The important take-away is that metrics are the best way to understand if a node is able to handle the churn rate of the pods assigned vs. using a fixed number.

+
+
+
+
+

Scale by Metrics

+
+

While the concept of using metrics to optimize systems is an old one, it’s often overlooked as people begin their Kubernetes journey. Instead of focusing on specific numbers (i.e. 110 pods per node), we focus our efforts on finding the metrics that help us find bottlenecks in our system. Understanding the right thresholds for these metrics can give us a high degree of confidence our system is optimally configured.

+
+
+

The Impact of Changes

+
+

A common pattern that could get us into trouble is focusing on the first metric or log error that looks suspect. When we saw that the Kubelet was timing out earlier, we could try random things, such as increasing the per second rate that the Kubelet is allowed to send, etc. However, it is wise to look at the whole picture of everything downstream of the error we find first. Make each change with purpose and backed by data.

+
+
+

Downstream of the Kubelet would be the Containerd runtime (pod errors), DaemonSets such as the storage driver (CSI) and the network driver (CNI) that talk to the EC2 API, etc.

+
+
+
+Flow add-ons +
+
+
+

Let’s continue our earlier example of the Kubelet not keeping up with the runtime. There are a number of points where we could bin pack a node so densely that it triggers errors.

+
+
+
+Bottlenecks +
+
+
+

When designing the right node size for our workloads these are easy-to-overlook signals that might be putting unnecessary pressure on the system thus limiting both our scale and performance.

+
+
+
+

The Cost of Unnecessary Errors

+
+

Kubernetes controllers excel at retrying when error conditions arise, however this comes at a cost. These retries can increase the pressure on components such as the Kube Controller Manager. It is an important tenant of scale testing to monitor for such errors.

+
+
+

When fewer errors are occurring, it is easier spot issues in the system. By periodically ensuring that our clusters are error free before major operations (such as upgrades) we can simplify troubleshooting logs when unforeseen events happen.

+
+
+
Expanding Our View
+
+

In large scale clusters with 1,000’s of nodes we don’t want to look for bottlenecks individually. In PromQL we can find the highest values in a data set using a function called topk; K being a variable we place the number of items we want. Here we use three nodes to get an idea whether all of the the Kubelets in the cluster are saturated. We have been looking at latency up to this point, now let’s see if the Kubelet is discarding events.

+
+
+
+
topk(3, increase(kubelet_pleg_discard_events{}[$__rate_interval]))
+
+
+
+

Breaking this statement down.

+
+
+
    +
  • +

    We use the Grafana variable $__rate_interval to ensure it gets the four samples it needs. This bypasses a complex topic in monitoring with a simple variable.

    +
  • +
  • +

    topk give us just the top results and the number 3 limits those results to three. This is a useful function for cluster wide metrics.

    +
  • +
  • +

    {} tell us there are no filters, normally you would put the job name of whatever the scraping rule, however since these names vary we will leave it blank.

    +
  • +
+
+
+
+
Splitting the Problem in Half
+
+

To address a bottleneck in the system, we will take the approach of finding a metric that shows us there is a problem upstream or downstream as this allows us to split the problem in half. It will also be a core tenet of how we display our metrics data.

+
+
+

A good place to start with this process is the API server, as it allow us to see if there’s a problem with a client application or the Control Plane.

+
+
+
+
+
+
+
+

Control Plane Monitoring

+
+
+

API Server

+
+

When looking at our API server it’s important to remember that one of its functions is to throttle inbound requests to prevent overloading the control plane. What can seem like a bottleneck at the API server level might actually be protecting it from more serious issues. We need to factor in the pros and cons of increasing the volume of requests moving through the system. To make a determination if the API server values should be increased, here is small sampling of the things we need to be mindful of:

+
+
+
    +
  1. +

    What is the latency of requests moving through the system?

    +
  2. +
  3. +

    Is that latency the API server itself, or something “downstream” like etcd?

    +
  4. +
  5. +

    Is the API server queue depth a factor in this latency?

    +
  6. +
  7. +

    Are the API Priority and Fairness (APF) queues setup correctly for the API call patterns we want?

    +
  8. +
+
+
+
+

Where is the issue?

+
+

To start, we can use the metric for API latency to give us insight into how long it’s taking the API server to service requests. Let’s use the below PromQL and Grafana heatmap to display this data.

+
+
+
+
max(increase(apiserver_request_duration_seconds_bucket{subresource!="status",subresource!="token",subresource!="scale",subresource!="/healthz",subresource!="binding",subresource!="proxy",verb!="WATCH"}[$__rate_interval])) by (le)
+
+
+
+

!!! tip + For an in depth write up on how to monitor the API server with the API dashboard used in this article, please see the following blog

+
+
+
+API request duration heatmap +
+
+
+

These requests are all under the one second mark, which is a good indication that the control plane is handling requests in a timely fashion. But what if that was not the case?

+
+
+

The format we are using in the above API Request Duration is a heatmap. What’s nice about the heatmap format, is that it tells us the timeout value for the API by default (60 sec). However, what we really need to know is at what threshold should this value be of concern before we reach the timeout threshold. For a rough guideline of what acceptable thresholds are we can use the upstream Kubernetes SLO, which can be found here

+
+
+

!!! tip + Notice the max function on this statement? When using metrics that are aggregating multiple servers (by default two API servers on EKS) it’s important not to average those servers together.

+
+
+

Asymmetrical traffic patterns

+
+

What if one API server [pod] was lightly loaded, and the other heavily loaded? If we averaged those two numbers together we might misinterpret what was happening. For example, here we have three API servers but all of the load is on one of these API servers. As a rule anything that has multiple servers such as etcd and API servers should be broken out when investing scale and performance issues.

+
+
+
+Total inflight requests +
+
+
+

With the move to API Priority and Fairness the total number of requests on the system is only one factor to check to see if the API server is oversubscribed. Since the system now works off a series of queues, we must look to see if any of these queues are full and if the traffic for that queue is getting dropped.

+
+
+

Let’s look at these queues with the following query:

+
+
+
+
max without(instance)(apiserver_flowcontrol_request_concurrency_limit{})
+
+
+
+

!!! note + For more information on how API A&F works please see the following best practices guide

+
+
+

Here we see the seven different priority groups that come by default on the cluster

+
+
+
+Shared concurrency +
+
+
+

Next we want to see what percentage of that priority group is being used, so that we can understand if a certain priority level is being saturated. Throttling requests in the workload-low level might be desirable, however drops in a leader election level would not be.

+
+
+

The API Priority and Fairness (APF) system has a number of complex options, some of those options can have unintended consequences. A common issue we see in the field is increasing the queue depth to the point it starts adding unnecessary latency. We can monitor this problem by using the apiserver_flowcontrol_current_inqueue_request metric. We can check for drops using the apiserver_flowcontrol_rejected_requests_total. These metrics will be a non-zero value if any bucket exceeds its concurrency.

+
+
+
+Requests in use +
+
+
+

Increasing the queue depth can make the API Server a significant source of latency and should be done with care. We recommend being judicious with the number of queues created. For example, the number of shares on a EKS system is 600, if we create too many queues, this can reduce the shares in important queues that need the throughput such as the leader-election queue or system queue. Creating too many extra queues can make it more difficult to size theses queues correctly.

+
+
+

To focus on a simple impactful change you can make in APF we simply take shares from underutilized buckets and increase the size of buckets that are at their max usage. By intelligently redistributing the shares among these buckets, you can make drops less likely.

+
+
+

For more information, visit API Priority and Fairness settings in the EKS Best Practices Guide.

+
+
+
+

API vs. etcd latency

+
+

How can we use the metrics/logs of the API server to determine whether there’s a problem with API server, or a problem that’s upstream/downstream of the API server, or a combination of both. To understand this better, lets look at how API Server and etcd can be related, and how easy it can be to troubleshoot the wrong system.

+
+
+

In the below chart we see API server latency, but we also see much of this latency is correlated to the etcd server due to the bars in the graph showing most of the latency at the etcd level. If there is 15 secs of etcd latency at the same time there is 20 seconds of API server latency, then the majority of the latency is actually at the etcd level.

+
+
+

By looking at the whole flow, we see that it’s wise to not focus solely on the API Server, but also look for signals that indicate that etcd is under duress (i.e. slow apply counters increasing). Being able to quickly move to the right problem area with just a glance is what makes a dashboard powerful.

+
+ +
+
+ETCD duress +
+
+
+
+

Control plane vs. Client side issues

+
+

In this chart we are looking for the API calls that took the most time to complete for that period. In this case we see a custom resource (CRD) is calling a APPLY function that is the most latent call during the 05:40 time frame.

+
+
+
+Slowest requests +
+
+
+

Armed with this data we can use an Ad-Hoc PromQL or a CloudWatch Insights query to pull LIST requests from the audit log during that time frame to see which application this might be.

+
+
+
+

Finding the Source with CloudWatch

+
+

Metrics are best used to find the problem area we want to look at and narrow both the timeframe and the search parameters of the problem. Once we have this data we want to transition to logs for more detailed times and errors. To do this we will turn our logs into metrics using CloudWatch Logs Insights.

+
+
+

For example, to investigate the issue above, we will use the following CloudWatch Logs Insights query to pull the userAgent and requestURI so that we can pin down which application is causing this latency.

+
+
+

!!! tip + An appropriate Count needs to be used as to not pull normal List/Resync behavior on a Watch.

+
+
+
+
fields *@timestamp*, *@message*
+| filter *@logStream* like "kube-apiserver-audit"
+| filter ispresent(requestURI)
+| filter verb = "list"
+| parse requestReceivedTimestamp /\d+-\d+-(?<StartDay>\d+)T(?<StartHour>\d+):(?<StartMinute>\d+):(?<StartSec>\d+).(?<StartMsec>\d+)Z/
+| parse stageTimestamp /\d+-\d+-(?<EndDay>\d+)T(?<EndHour>\d+):(?<EndMinute>\d+):(?<EndSec>\d+).(?<EndMsec>\d+)Z/
+| fields (StartHour * 3600 + StartMinute * 60 + StartSec + StartMsec / 1000000) as StartTime, (EndHour * 3600 + EndMinute * 60 + EndSec + EndMsec / 1000000) as EndTime, (EndTime - StartTime) as DeltaTime
+| stats avg(DeltaTime) as AverageDeltaTime, count(*) as CountTime by requestURI, userAgent
+| filter CountTime >=50
+| sort AverageDeltaTime desc
+
+
+
+

Using this query we found two different agents running a large number of high latency list operations. Splunk and CloudWatch agent. Armed with the data, we can make a decision to remove, update, or replace this controller with another project.

+
+
+
+Query results +
+
+
+

!!! tip + For more details on this subject please see the following blog

+
+
+
+
+

Scheduler

+
+

Since the EKS control plane instances are run in separate AWS account we will not be able to scrape those components for metrics (The API server being the exception). However, since we have access to the audit logs for these components, we can turn those logs into metrics to see if any of the sub-systems are causing a scaling bottleneck. Let’s use CloudWatch Logs Insights to see how many unscheduled pods are in the scheduler queue.

+
+
+

Unscheduled pods in the scheduler log

+
+

If we had access to scrape the scheduler metrics directly on a self managed Kubernetes (such as Kops) we would use the following PromQL to understand the scheduler backlog.

+
+
+
+
max without(instance)(scheduler_pending_pods)
+
+
+
+

Since we do not have access to the above metric in EKS, we will use the below CloudWatch Logs Insights query to see the backlog by checking for how many pods were unable to unscheduled during a particular time frame. Then we could dive further into into the messages at the peak time frame to understand the nature of the bottleneck. For example, nodes not spinning up fast enough, or the rate limiter in the scheduler itself.

+
+
+
+
fields timestamp, pod, err, *@message*
+| filter *@logStream* like "scheduler"
+| filter *@message* like "Unable to schedule pod"
+| parse *@message*  /^.(?<date>\d{4})\s+(?<timestamp>\d+:\d+:\d+\.\d+)\s+\S*\s+\S+\]\s\"(.*?)\"\s+pod=(?<pod>\"(.*?)\")\s+err=(?<err>\"(.*?)\")/
+| count(*) as count by pod, err
+| sort count desc
+
+
+
+

Here we see the errors from the scheduler saying the pod did not deploy because the storage PVC was unavailable.

+
+
+
+CloudWatch Logs query +
+
+
+

!!! note + Audit logging must be turned on the control plane to enable this function. It is also a best practice to limit the log retention as to not drive up cost over time unnecessarily. An example for turning on all logging functions using the EKSCTL tool below.

+
+
+
+
cloudWatch:
+  clusterLogging:
+    enableTypes: ["*"]
+    logRetentionInDays: 10
+
+
+
+
+
+

Kube Controller Manager

+
+

Kube Controller Manager, like all other controllers, has limits on how many operations it can do at once. Let’s review what some of those flags are by looking at a KOPS configuration where we can set these parameters.

+
+
+
+
  kubeControllerManager:
+    concurrentEndpointSyncs: 5
+    concurrentReplicasetSyncs: 5
+    concurrentNamespaceSyncs: 10
+    concurrentServiceaccountTokenSyncs: 5
+    concurrentServiceSyncs: 5
+    concurrentResourceQuotaSyncs: 5
+    concurrentGcSyncs: 20
+    kubeAPIBurst: 20
+    kubeAPIQPS: "30"
+
+
+
+

These controllers have queues that fill up during times of high churn on a cluster. In this case we see the replicaset set controller has a large backlog in its queue.

+
+
+
+Queues +
+
+
+

We have two different ways of addressing such a situation. If running self managed we could simply increase the concurrent goroutines, however this would have an impact on etcd by processing more data in the KCM. The other option would be to reduce the number of replicaset objects using .spec.revisionHistoryLimit on the deployment to reduce the number of replicaset objects we can rollback, thus reducing the pressure on this controller.

+
+
+
+
spec:
+  revisionHistoryLimit: 2
+
+
+
+

Other Kubernetes features can be tuned or turned off to reduce pressure in high churn rate systems. For example, if the application in our pods doesn’t need to speak to the k8s API directly then turning off the projected secret into those pods would decrease the load on ServiceaccountTokenSyncs. This is the more desirable way to address such issues if possible.

+
+
+
+
kind: Pod
+spec:
+  automountServiceAccountToken: false
+
+
+
+

In systems where we can’t get access to the metrics, we can again look at the logs to detect contention. If we wanted to see the number of requests being being processed on a per controller or an aggregate level we would use the following CloudWatch Logs Insights Query.

+
+
+

Total Volume Processed by the KCM

+
+
+
# Query to count API qps coming from kube-controller-manager, split by controller type.
+# If you're seeing values close to 20/sec for any particular controller, it's most likely seeing client-side API throttling.
+fields @timestamp, @logStream, @message
+| filter @logStream like /kube-apiserver-audit/
+| filter userAgent like /kube-controller-manager/
+# Exclude lease-related calls (not counted under kcm qps)
+| filter requestURI not like "apis/coordination.k8s.io/v1/namespaces/kube-system/leases/kube-controller-manager"
+# Exclude API discovery calls (not counted under kcm qps)
+| filter requestURI not like "?timeout=32s"
+# Exclude watch calls (not counted under kcm qps)
+| filter verb != "watch"
+# If you want to get counts of API calls coming from a specific controller, uncomment the appropriate line below:
+# | filter user.username like "system:serviceaccount:kube-system:job-controller"
+# | filter user.username like "system:serviceaccount:kube-system:cronjob-controller"
+# | filter user.username like "system:serviceaccount:kube-system:deployment-controller"
+# | filter user.username like "system:serviceaccount:kube-system:replicaset-controller"
+# | filter user.username like "system:serviceaccount:kube-system:horizontal-pod-autoscaler"
+# | filter user.username like "system:serviceaccount:kube-system:persistent-volume-binder"
+# | filter user.username like "system:serviceaccount:kube-system:endpointslice-controller"
+# | filter user.username like "system:serviceaccount:kube-system:endpoint-controller"
+# | filter user.username like "system:serviceaccount:kube-system:generic-garbage-controller"
+| stats count(*) as count by user.username
+| sort count desc
+
+
+
+

The key takeaway here is when looking into scalability issues, to look at every step in the path (API, scheduler, KCM, etcd) before moving to the detailed troubleshooting phase. Often in production you will find that it takes adjustments to more than one part of Kubernetes to allow the system to work at its most performant. It’s easy to inadvertently troubleshoot what is just a symptom (such as a node timeout) of a much larger bottle neck.

+
+
+
+
+

ETCD

+
+

etcd uses a memory mapped file to store key value pairs efficiently. There is a protection mechanism to set the size of this memory space available set commonly at the 2, 4, and 8GB limits. Fewer objects in the database means less clean up etcd needs to do when objects are updated and older versions needs to be cleaned out. This process of cleaning old versions of an object out is referred to as compaction. After a number of compaction operations, there is a subsequent process that recovers usable space space called defragging that happens above a certain threshold or on a fixed schedule of time.

+
+
+

There are a couple user related items we can do to limit the number of objects in Kubernetes and thus reduce the impact of both the compaction and de-fragmentation process. For example, Helm keeps a high revisionHistoryLimit. This keeps older objects such as ReplicaSets on the system to be able to do rollbacks. By setting the history limits down to 2 we can reduce the the number of objects (like ReplicaSets) from ten to two which in turn would put less load on the system.

+
+
+
+
apiVersion: apps/v1
+kind: Deployment
+spec:
+  revisionHistoryLimit: 2
+
+
+
+

From a monitoring standpoint, if system latency spikes occur in a set pattern separated by hours, checking to see if this defragmentation process is the source can be helpful. We can see this by using CloudWatch Logs.

+
+
+

If you want to see start/end times of defrag use the following query:

+
+
+
+
fields *@timestamp*, *@message*
+| filter *@logStream* like /etcd-manager/
+| filter *@message* like /defraging|defraged/
+| sort *@timestamp* asc
+
+
+
+
+Defrag query +
+
+
+
+
+
+

Node and Workload Efficiency

+
+
+

Being efficient with our workloads and nodes reduces complexity/cost while increasing performance and scale. There are many factors to consider when planning this efficiency, and it’s easiest to think in terms of trade offs vs. one best practice setting for each feature. Let’s explore these tradeoffs in depth in the following section.

+
+
+

Node Selection

+
+

Using node sizes that are slightly larger (4-12xlarge) increases the available space that we have for running pods due to the fact it reduces the percentage of the node used for “overhead” such as DaemonSets and Reserves for system components. In the diagram below we see the difference between the usable space on a 2xlarge vs. a 8xlarge system with just a moderate number of DaemonSets.

+
+
+

!!! note + Since k8s scales horizontally as a general rule, for most applications it does not make sense to take the performance impact of NUMA sizes nodes, thus the recommendation of a range below that node size.

+
+
+
+Node size +
+
+
+

Large nodes sizes allow us to have a higher percentage of usable space per node. However, this model can be taken to to the extreme by packing the node with so many pods that it causes errors or saturates the node. Monitoring node saturation is key to successfully using larger node sizes.

+
+
+

Node selection is rarely a one-size-fits-all proposition. Often it is best to split workloads with dramatically different churn rates into different node groups. Small batch workloads with a high churn rate would be best served by the the 4xlarge family of instances, while a large scale application such as Kafka which takes 8 vCPU and has a low churn rate would be better served by the 12xlarge family.

+
+
+
+Churn rate +
+
+
+

!!! tip + Another factor to consider with very large node sizes is since CGROUPS do not hide the total number of vCPU from the containerized application. Dynamic runtimes can often spawn an unintentional number of OS threads, creating latency that is difficult to troubleshoot. For these application CPU pinning is recommend. For a deeper exploration of topic please see the following video https://www.youtube.com/watch?v=NqtfDy_KAqg

+
+
+
+

Node Bin-packing

+
+

Kubernetes vs. Linux Rules

+
+

There are two sets of rules we need to be mindful of when dealing with workloads on Kubernetes. The rules of the Kubernetes Scheduler, which uses the request value to schedule pods on a node, and then what happens after the pod is scheduled, which is the realm of Linux, not Kubernetes.

+
+
+

After Kubernetes scheduler is finished, a new set of rules takes over, the Linux Completely Fair Scheduler (CFS). The key take away is that Linux CFS doesn’t have a the concept of a core. We will discuss why thinking in cores can lead to major problems with optimizing workloads for scale.

+
+
+
+

Thinking in Cores

+
+

The confusion starts because the Kubernetes scheduler does have the concept of cores. From a Kubernetes scheduler perspective if we looked at a node with 4 NGINX pods, each with a request of one core set, the node would look like this.

+
+
+
+cores 1 +
+
+
+

However, let’s do a thought experiment on how different this looks from a Linux CFS perspective. The most important thing to remember when using the Linux CFS system is: busy containers (CGROUPS) are the only containers that count toward the share system. In this case, only the first container is busy so it is allowed to use all 4 cores on the node.

+
+
+
+cores 2 +
+
+
+

Why does this matter? Let’s say we ran our performance testing in a development cluster where an NGINX application was the only busy container on that node. When we move the app to production, the following would happen: the NGINX application wants 4 vCPU of resources however, because all the other pods on the node are busy, our app’s performance is constrained.

+
+
+
+cores 3 +
+
+
+

This situation would lead us to add more containers unnecessarily because we were not allowing our applications scale to their "`sweet spot"`. Let’s explore this important concept of a "sweet spot" in a bit more detail.

+
+
+
+

Application right sizing

+
+

Each application has a certain point where it can not take anymore traffic. Going above this point can increase processing times and even drop traffic when pushed well beyond this point. This is known as the application’s saturation point. To avoid scaling issues, we should attempt to scale the application before it reaches its saturation point. Let’s call this point the sweet spot.

+
+
+
+The sweet spot +
+
+
+

We need to test each of our applications to understand its sweet spot. There will be no universal guidance here as each application is different. During this testing we are trying to understand the best metric that shows our applications saturation point. Oftentimes, utilization metrics are used to indicate an application is saturated but this can quickly lead to scaling issues (We will explore this topic in detail in a later section). Once we have this "`sweet spot"` we can use it to efficiently scale our workloads.

+
+
+

Conversely, what would happen if we scale up well before the sweet spot and created unnecessary pods? Let’s explore that in the next section.

+
+
+
+

Pod sprawl

+
+

To see how creating unnecessary pods could quickly get out of hand, let’s look at the first example on the left. The correct vertical scale of this container takes up about two vCPUs worth of utilization when handling 100 requests a second. However, If we were to under-provision the requests value by setting requests to half a core, we would now need 4 pods for each one pods we actually needed. Exacerbating this problem further, if our HPA was set at the default of 50% CPU, those pods would scale half empty, creating an 8:1 ratio.

+
+
+
+scaling ratio +
+
+
+

Scaling this problem up we can quickly see how this can get out of hand. A deployment of ten pods whose sweet spot was set incorrectly could quickly spiral to 80 pods and the additional infrastructure needed to run them.

+
+
+
+bad sweetspot +
+
+
+

Now that we understand the impact of not allowing applications to operate in their sweet spot, let’s return to the node level and ask why this difference between the Kubernetes scheduler and Linux CFS so important?

+
+
+

When scaling up and down with HPA, we can have a scenario where we have a lot of space to allocate more pods. This would be a bad decision because the node depicted on the left is already at 100% CPU utilization. In a unrealistic but theoretically possible scenario, we could have the other extreme where our node is completely full, yet our CPU utilization is zero.

+
+
+
+hpa utilization +
+
+
+
+

Setting Requests

+
+

It would tempting to set the request at the “sweet spot” value for that application, however this would cause inefficiencies as pictured in the diagram below. Here we have set the request value to 2 vCPU, however the average utilization of these pods runs only 1 CPU most of the time. This setting would cause us to waste 50% of our CPU cycles, which would be unacceptable.

+
+
+
+requests 1 +
+
+
+

This bring us to the complex answer to problem. Container utilization cannot be thought of in a vacuum; one must take into account the other applications running on the node. In the following example containers that are bursty in nature are mixed in with two low CPU utilization containers that might be memory constrained. In this way we allow the containers to hit their sweet spot without taxing the node.

+
+
+
+requests 2 +
+
+
+

The important concept to take away from all this is that using Kubernetes scheduler concept of cores to understand Linux container performance can lead to poor decision making as they are not related.

+
+
+

!!! tip + Linux CFS has its strong points. This is especially true for I/O based workloads. However, if your application uses full cores without sidecars, and has no I/O requirements, CPU pinning can remove a great deal of complexity from this process and is encouraged with those caveats.

+
+
+
+
+

Utilization vs. Saturation

+
+

A common mistake in application scaling is only using CPU utilization for your scaling metric. In complex applications this is almost always a poor indicator that an application is actually saturated with requests. In the example on the left, we see all of our requests are actually hitting the web server, so CPU utilization is tracking well with saturation.

+
+
+

In real world applications, it’s likely that some of those requests will be getting serviced by a database layer or an authentication layer, etc. In this more common case, notice CPU is not tracking with saturation as the request is being serviced by other entities. In this case CPU is a very poor indicator for saturation.

+
+
+
+util vs saturation 1 +
+
+
+

Using the wrong metric in application performance is the number one reason for unnecessary and unpredictable scaling in Kubernetes. Great care must be taken in picking the correct saturation metric for the type of application that you’re using. It is important to note that there is not a one size fits all recommendation that can be given. Depending on the language used and the type of application in question, there is a diverse set of metrics for saturation.

+
+
+

We might think this problem is only with CPU Utilization, however other common metrics such as request per second can also fall into the exact same problem as discussed above. Notice the request can also go to DB layers, auth layers, not being directly serviced by our web server, thus it’s a poor metric for true saturation of the web server itself.

+
+
+
+util vs saturation 2 +
+
+
+

Unfortunately there are no easy answers when it comes to picking the right saturation metric. Here are some guidelines to take into consideration:

+
+
+
    +
  • +

    Understand your language runtime - languages with multiple OS threads will react differently than single threaded applications, thus impacting the node differently.

    +
  • +
  • +

    Understand the correct vertical scale - how much buffer do you want in your applications vertical scale before scaling a new pod?

    +
  • +
  • +

    What metrics truly reflect the saturation of your application - The saturation metric for a Kafka Producer would be quite different than a complex web application.

    +
  • +
  • +

    How do all the other applications on the node effect each other - Application performance is not done in a vacuum the other workloads on the node have a major impact.

    +
  • +
+
+
+

To close out this section, it would be easy to dismiss the above as overly complex and unnecessary. It can often be the case that we are experiencing an issue but we are unaware of the true nature of the problem because we are looking at the wrong metrics. In the next section we will look at how that could happen.

+
+
+

Node Saturation

+
+

Now that we have explored application saturation, let’s look at this same concept from a node point of view. Let’s take two CPUs that are 100% utilized to see the difference between utilization vs. saturation.

+
+
+

The vCPU on the left is 100% utilized, however no other tasks are waiting to run on this vCPU, so in a purely theoretical sense, this is quite efficient. Meanwhile, we have 20 single threaded applications waiting to get processed by a vCPU in the second example. All 20 applications now will experience some type of latency while they’re waiting their turn to be processed by the vCPU. In other words, the vCPU on the right is saturated.

+
+
+

Not only would we not see this problem if we where just looking at utilization, but we might attribute this latency to something unrelated such as networking which would lead us down the wrong path.

+
+
+
+node saturation +
+
+
+

It is important to view saturation metrics, not just utilization metrics when increasing the total number of pods running on a node at any given time as we can easily miss the fact we have over-saturated a node. For this task we can use pressure stall information metrics as seen in the below chart.

+
+
+

PromQL - Stalled I/O

+
+
+
+
topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100))
+
+
+
+
+stalled io +
+
+
+

!!! note + For more on Pressure stall metrics, see https://facebookmicrosites.github.io/psi/docs/overview*

+
+
+

With these metrics we can tell if threads are waiting on CPU, or even if every thread on the box is stalled waiting on resource like memory or I/O. For example, we could see what percentage every thread on the instance was stalled waiting on I/O over the period of 1 min.

+
+
+
+
topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100))
+
+
+
+

Using this metric, we can see in the above chart every thread on the box was stalled 45% of the time waiting on I/O at the high water mark, meaning we were throwing away all of those CPU cycles in that minute. Understanding that this is happening can help us reclaim a significant amount of vCPU time, thus making scaling more efficient.

+
+
+
+

HPA V2

+
+

It is recommended to use the autoscaling/v2 version of the HPA API. The older versions of the HPA API could get stuck scaling in certain edge cases. It was also limited to pods only doubling during each scaling step, which created issues for small deployments that needed to scale rapidly.

+
+
+

Autoscaling/v2 allows us more flexibility to include multiple criteria to scale on and allows us a great deal of flexibility when using custom and external metrics (non K8s metrics).

+
+
+

As an example, we can scaling on the highest of three values (see below). We scale if the average utilization of all the pods are over 50%, if custom metrics the packets per second of the ingress exceed an average of 1,000, or ingress object exceeds 10K request per second.

+
+
+

!!! note + This is just to show the flexibility of the auto-scaling API, we recommend against overly complex rules that can be difficult to troubleshoot in production.

+
+
+
+
apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+  name: php-apache
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: php-apache
+  minReplicas: 1
+  maxReplicas: 10
+  metrics:
+  - type: Resource
+    resource:
+      name: cpu
+      target:
+        type: Utilization
+        averageUtilization: 50
+  - type: Pods
+    pods:
+      metric:
+        name: packets-per-second
+      target:
+        type: AverageValue
+        averageValue: 1k
+  - type: Object
+    object:
+      metric:
+        name: requests-per-second
+      describedObject:
+        apiVersion: networking.k8s.io/v1
+        kind: Ingress
+        name: main-route
+      target:
+        type: Value
+        value: 10k
+
+
+
+

However, we learned the danger of using such metrics for complex web applications. In this case we would be better served by using custom or external metric that accurately reflects the saturation of our application vs. the utilization. HPAv2 allows for this by having the ability to scale according to any metric, however we still need to find and export that metric to Kubernetes for use.

+
+
+

For example, we can look at the active thread queue count in Apache. This often creates a “smoother” scaling profile (more on that term soon). If a thread is active, it doesn’t matter if that thread is waiting on a database layer or servicing a request locally, if all of the applications threads are being used, it’s a great indication that application is saturated.

+
+
+

We can use this thread exhaustion as a signal to create a new pod with a fully available thread pool. This also gives us control over how big a buffer we want in the application to absorb during times of heavy traffic. For example, if we had a total thread pool of 10, scaling at 4 threads used vs. 8 threads used would have a major impact on the buffer we have available when scaling the application. A setting of 4 would make sense for an application that needs to rapidly scale under heavy load, where a setting of 8 would be more efficient with our resources if we had plenty of time to scale due to the number of requests increasing slowly vs. sharply over time.

+
+
+
+thread pool +
+
+
+

What do we mean by the term “smooth” when it comes to scaling? Notice the below chart where we are using CPU as a metric. The pods in this deployment are spiking in a short period for from 50 pods, all the way up to 250 pods only to immediately scale down again. This is highly inefficient scaling is the leading cause on churn on clusters.

+
+
+
+spiky scaling +
+
+
+

Notice how after we change to a metric that reflects the correct sweet spot of our application (mid-part of chart), we are able to scale smoothly. Our scaling is now efficient, and our pods are allowed to fully scale with the headroom we provided by adjusting requests settings. Now a smaller group of pods are doing the work the hundreds of pods were doing before. Real world data shows that this is the number one factor in scalability of Kubernetes clusters.

+
+
+
+smooth scaling +
+
+
+

The key takeaway is CPU utilization is only one dimension of both application and node performance. Using CPU utilization as a sole health indicator for our nodes and applications creates problems in scaling, performance and cost which are all tightly linked concepts. The more performant the application and nodes are, the less that you need to scale, which in turn lowers your costs.

+
+
+

Finding and using the correct saturation metrics for scaling your particular application also allows you to monitor and alarm on the true bottlenecks for that application. If this critical step is skipped, reports of performance problems will be difficult, if not impossible, to understand.

+
+
+
+
+

Setting CPU Limits

+
+

To round out this section on misunderstood topics, we will cover CPU limits. In short, limits are metadata associated with the container that has a counter that resets every 100ms. This helps Linux keep track of how many CPU resources are used node-wide by a specific container in a 100ms period of time.

+
+
+
+CPU limits +
+
+
+

A common error with setting limits is assuming that the application is single threaded and only running on it’s "`assigned"` vCPU. In the above section we learned that CFS doesn’t assign cores, and in reality a container running large thread pools will schedule on all available vCPU’s on the box.

+
+
+

If 64 OS threads are running across 64 available cores (from a Linux node perspective) we will make the total bill of used CPU time in a 100ms period quite large after the time running on all of those 64 cores are added up. Since this might only occur during a garbage collection process it can be quite easy to miss something like this. This is why it is necessary to use metrics to ensure we have the correct usage over time before attempting to set a limit.

+
+
+

Fortunately, we have a way to see exactly how much vCPU is being used by all the threads in a application. We will use the metric container_cpu_usage_seconds_total for this purpose.

+
+
+

Since throttling logic happens every 100ms and this metric is a per second metric, we will PromQL to match this 100ms period. If you would like to dive deep into this PromQL statement work please see the following blog.

+
+
+

PromQL query:

+
+
+
+
topk(3, max by (pod, container)(rate(container_cpu_usage_seconds_total{image!="", instance="$instance"}[$__rate_interval]))) / 10
+
+
+
+
+cpu 1 +
+
+
+

Once we feel we have the right value, we can put the limit in production. It then becomes necessary to see if our application is being throttled due to something unexpected. We can do this by looking at container_cpu_throttled_seconds_total

+
+
+
+
topk(3, max by (pod, container)(rate(container_cpu_cfs_throttled_seconds_total{image!=``""``, instance=``"$instance"``}[$__rate_interval]))) / 10
+
+
+
+
+cpu 2 +
+
+
+

Memory

+
+

The memory allocation is another example where it is easy to confuse Kubernetes scheduling behavior for Linux CGroup behavior. This is a more nuanced topic as there have been major changes in the way that CGroup v2 handles memory in Linux and Kubernetes has changed its syntax to reflect this; read this blog for further details.

+
+
+

Unlike CPU requests, memory requests go unused after the scheduling process completes. This is because we can not compress memory in CGroup v1 the same way we can with CPU. That leaves us with just memory limits, which are designed to act as a fail safe for memory leaks by terminating the pod completely. This is an all or nothing style proposition, however we have now been given new ways to address this problem.

+
+
+

First, it is important to understand that setting the right amount of memory for containers is not a straightforward as it appears. The file system in Linux will use memory as a cache to improve performance. This cache will grow over time, and it can be hard to know how much memory is just nice to have for the cache but can be reclaimed without a significant impact to application performance. This often results in misinterpreting memory usage.

+
+
+

Having the ability to “compress” memory was one of the primary drivers behind CGroup v2. For more history on why CGroup V2 was necessary, please see Chris Down’s presentation at LISA21 where he covers why being unable to set the minimum memory correctly was one of the reasons that drove him to create CGroup v2 and pressure stall metrics.

+
+
+

Fortunately, Kubernetes now has the concept of memory.min and memory.high under requests.memory. This gives us the option of aggressive releasing this cached memory for other containers to use. Once the container hits the memory high limit, the kernel can aggressively reclaim that container’s memory up to the value set at memory.min. Thus giving us more flexibility when a node comes under memory pressure.

+
+
+

The key question becomes, what value to set memory.min to? This is where memory pressure stall metrics come into play. We can use these metrics to detect memory “thrashing” at a container level. Then we can use controllers such as fbtax to detect the correct values for memory.min by looking for this memory thrashing, and dynamically set the memory.min value to this setting.

+
+
+
+

Summary

+
+

To sum up the section, it is easy to conflate the following concepts:

+
+
+
    +
  • +

    Utilization and Saturation

    +
  • +
  • +

    Linux performance rules with Kubernetes Scheduler logic

    +
  • +
+
+
+

Great care must be taken to keep these concepts separated. Performance and scale are linked on a deep level. Unnecessary scaling creates performance problems, which in turn creates scaling problems.

+
+
+
+
+
+
+

Kubernetes Upstream SLOs

+
+
+

Amazon EKS runs the same code as the upstream Kubernetes releases and ensures that EKS clusters operate within the SLOs defined by the Kubernetes community. The Kuberneteshttps://github.com/kubernetes/community/tree/master/sig-scalability[Scalability Special Interest Group (SIG)] defines the scalability goals and investigates bottlenecks in performance through SLIs and SLOs.

+
+
+

SLIs are how we measure a system like metrics or measures that can be used to determine how “well” the system is running, e.g. request latency or count. SLOs define the values that are expected for when the system is running “well”, e.g. request latency remains less than 3 seconds. The Kubernetes SLOs and SLIs focus on the performance of the Kubernetes components and are completely independent from the Amazon EKS Service SLAs which focus on availability of the EKS cluster endpoint.

+
+
+

Kubernetes has a number of features that allow users to extend the system with custom add-ons or drivers, like CSI drivers, admission webhooks, and auto-scalers. These extensions can drastically impact the performance of a Kubernetes cluster in different ways, i.e. an admission webhook with failurePolicy=Ignore could add latency to K8s API requests if the webhook target is unavailable. The Kubernetes Scalability SIG defines scalability using a "you promise, we promise" framework:

+
+
+
+
+

If you promise to:
+ - correctly configure your cluster
+ - use extensibility features "reasonably"
+ - keep the load in the cluster within recommended limits

+
+
+

then we promise that your cluster scales, i.e.:
+ - all the SLOs are satisfied.

+
+
+
+
+

Kubernetes SLOs

+
+

The Kubernetes SLOs don’t account for all of the plugins and external limitations that could impact a cluster, such as worker node scaling or admission webhooks. These SLOs focus on Kubernetes components and ensure that Kubernetes actions and resources are operating within expectations. The SLOs help Kubernetes developers ensure that changes to Kubernetes code do not degrade performance for the entire system.

+
+
+

The Kuberntes Scalability SIG defines the following official SLO/SLIs. The Amazon EKS team regularly runs scalability tests on EKS clusters for these SLOs/SLIs to monitor for performance degradation as changes are made and new versions are released.

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + +
ObjectiveDefinitionSLO

API request latency (mutating)

Latency of processing mutating API calls for single objects for every (resource, verb) pair, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, for every (resource, verb) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day <= 1s

API request latency (read-only)

Latency of processing non-streaming read-only API calls for every (resource, scope) pair, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, for every (resource, scope) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day: (a) <= 1s if scope=resource (b) <= 30s otherwise (if scope=namespace or scope=cluster)

Pod startup latency

Startup latency of schedulable stateless pods, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, 99th percentile per cluster-day <= 5s

+
+

API Request Latency

+
+

The kube-apiserver has --request-timeout defined as 1m0s by default, which means a request can run for up to one minute (60 seconds) before being timed out and cancelled. The SLOs defined for Latency are broken out by the type of request that is being made, which can be mutating or read-only:

+
+
+
Mutating
+
+

Mutating requests in Kubernetes make changes to a resource, such as creations, deletions, or updates. These requests are expensive because those changes must be written to the etcd backend before the updated object is returned. Etcd is a distributed key-value store that is used for all Kubernetes cluster data.

+
+
+

This latency is measured as the 99th percentile over 5min for (resource, verb) pairs of Kubernetes resources, for example this would measure the latency for Create Pod requests and Update Node requests. The request latency must be <= 1 second to satisfy the SLO.

+
+
+
+
Read-only
+
+

Read-only requests retrieve a single resource (such as Get Pod X) or a collection (such as “Get all Pods from Namespace X”). The kube-apiserver maintains a cache of objects, so the requested resources may be returned from cache or they may need to be retrieved from etcd first. +These latencies are also measured by the 99th percentile over 5 minutes, however read-only requests can have separate scopes. The SLO defines two different objectives:

+
+
+
    +
  • +

    For requests made for a single resource (i.e. kubectl get pod -n mynamespace my-controller-xxx ), the request latency should remain <= 1 second.

    +
  • +
  • +

    For requests that are made for multiple resources in a namespace or a cluster (for example, kubectl get pods -A) the latency should remain <= 30 seconds

    +
  • +
+
+
+

The SLO has different target values for different request scopes because requests made for a list of Kubernetes resources expect the details of all objects in the request to be returned within the SLO. On large clusters, or large collections of resources, this can result in large response sizes which can take some time to return. For example, in a cluster running tens of thousands of Pods with each Pod being roughly 1 KiB when encoded in JSON, returning all Pods in the cluster would consist of 10MB or more. Kubernetes clients can help reduce this response size using APIListChunking to retrieve large collections of resources.

+
+
+
+
+

Pod Startup Latency

+
+

This SLO is primarily concerned with the time it takes from Pod creation to when the containers in that Pod actually begin execution. To measure this the difference from the creation timestamp recorded on the Pod, and when a WATCH on that Pod reports the containers have started is calculated (excluding time for container image pulls and init container execution). To satisfy the SLO the 99th percentile per cluster-day of this Pod Startup Latency must remain <=5 seconds.

+
+
+

Note that this SLO assumes that the worker nodes already exist in this cluster in a ready state for the Pod to be scheduled on. This SLO does not account for image pulls or init container executions, and also limits the test to “stateless pods” which don’t leverage persistent storage plugins.

+
+
+
+
+

Kubernetes SLI Metrics

+
+

Kubernetes is also improving the Observability around the SLIs by adding Prometheus metrics to Kubernetes components that track these SLIs over time. Using Prometheus Query Language (PromQL) we can build queries that display the SLI performance over time in tools like Prometheus or Grafana dashboards, below are some examples for the SLOs above.

+
+
+

API Server Request Latency

+ ++++ + + + + + + + + + + + + + + + + +
MetricDefinition

apiserver_request_sli_duration_seconds

Response latency distribution (not counting webhook duration and priority & fairness queue wait times) in seconds for each verb, group, version, resource, subresource, scope and component.

apiserver_request_duration_seconds

Response latency distribution in seconds for each verb, dry run value, group, version, resource, subresource, scope and component.

+
+

Note: The apiserver_request_sli_duration_seconds metric is available starting in Kubernetes 1.27.

+
+
+

You can use these metrics to investigate the API Server response times and if there are bottlenecks in the Kubernetes components or other plugins/components. The queries below are based on the community SLO dashboard.

+
+
+

API Request latency SLI (mutating) - this time does not include webhook execution or time waiting in queue.
+histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

+
+
+

API Request latency Total (mutating) - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and API Priority and Fairness wait times.
+histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

+
+
+

In these queries we are excluding the streaming API requests which do not return immediately, such as kubectl port-forward or kubectl exec requests (subresource!~"proxy|attach|log|exec|portforward"), and we are filtering for only the Kubernetes verbs that modify objects (verb=~"CREATE|DELETE|PATCH|POST|PUT"). We are then calculating the 99th percentile of that latency over the last 5 minutes.

+
+
+

We can use a similar query for the read only API requests, we simply modify the verbs we’re filtering for to include the Read only actions LIST and GET. There are also different SLO thresholds depending on the scope of the request, i.e. getting a single resource or listing a number of resources.

+
+
+

API Request latency SLI (read-only) - this time does not include webhook execution or time waiting in queue. +For a single resource (scope=resource, threshold=1s)
+histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

For a collection of resources in the same namespace (scope=namespace, threshold=5s)
+histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

For a collection of resources across the entire cluster (scope=cluster, threshold=30s)
+histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

API Request latency Total (read-only) - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and wait times. +For a single resource (scope=resource, threshold=1s)
+histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

For a collection of resources in the same namespace (scope=namespace, threshold=5s)
+histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

For a collection of resources across the entire cluster (scope=cluster, threshold=30s)
+histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

+
+
+

The SLI metrics provide insight into how Kubernetes components are performing by excluding the time that requests spend waiting in API Priority and Fairness queues, working through admission webhooks, or other Kubernetes extensions. The total metrics provide a more holistic view as it reflects the time your applications would be waiting for a response from the API server. Comparing these metrics can provide insight into where the delays in request processing are being introduced.

+
+
+
+

Pod Startup Latency

+ ++++ + + + + + + + + + + + + + + + + +
MetricDefinition

kubelet_pod_start_sli_duration_seconds

Duration in seconds to start a pod, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch

kubelet_pod_start_duration_seconds

Duration in seconds from kubelet seeing a pod for the first time to the pod starting to run. This does not include the time to schedule the pod or scale out worker node capacity.

+
+

Note: kubelet_pod_start_sli_duration_seconds is available starting in Kubernetes 1.27.

+
+
+

Similar to the queries above you can use these metrics to gain insight into how long node scaling, image pulls and init containers are delaying the pod launch compared to Kubelet actions.

+
+
+

Pod startup latency SLI - this is the time from the pod being created to when the application containers reported as running. This includes the time it takes for the worker node capacity to be available and the pod to be scheduled, but this does not include the time it takes to pull images or for the init containers to run.
+histogram_quantile(0.99, sum(rate(kubelet_pod_start_sli_duration_seconds_bucket[5m])) by (le))

+
+
+

Pod startup latency Total - this is the time it takes the kubelet to start the pod for the first time. This is measured from when the kubelet recieves the pod via WATCH, which does not include the time for worker node scaling or scheduling. This includes the time to pull images and init containers to run.
+histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))

+
+
+
+
+

SLOs on Your Cluster

+
+

If you are collecting the Prometheus metrics from the Kubernetes resources in your EKS cluster you can gain deeper insights into the performance of the Kubernetes control plane components.

+
+
+

The perf-tests repo includes Grafana dashboards that display the latencies and critical performance metrics for the cluster during tests. The perf-tests configuration leverages the kube-prometheus-stack, an open source project that comes configured to collect Kubernetes metrics, but you can also use Amazon Managed Prometheus and Amazon Managed Grafana.

+
+
+

If you are using the kube-prometheus-stack or similar Prometheus solution you can install the same dashboard to observe the SLOs on your cluster in real time.

+
+
+
    +
  1. +

    You will first need to install the Prometheus Rules that are used in the dashboards with kubectl apply -f prometheus-rules.yaml. You can download a copy of the rules here: https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/prometheus-rules.yaml

    +
    +
      +
    1. +

      Be sure to check the namespace in the file matches your environment

      +
    2. +
    3. +

      Verify that the labels match the prometheus.prometheusSpec.ruleSelector helm value if you are using kube-prometheus-stack

      +
    4. +
    +
    +
  2. +
  3. +

    You can then install the dashboards in Grafana. The json dashboards and python scripts to generate them are available here: https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards

    +
    +
      +
    1. +

      the slo.json dashboard displays the performance of the cluster in relation to the Kubernetes SLOs

      +
    2. +
    +
    +
  4. +
+
+
+

Consider that the SLOs are focused on the performance of the Kubernetes components in your clusters, but there are additional metrics you can review which provide different perspectives or insights in to your cluster. Kubernetes community projects like Kube-state-metrics can help you quickly analyze trends in your cluster. Most common plugins and drivers from the Kubernetes community also emit Prometheus metrics, allowing you to investigate things like autoscalers or custom schedulers.

+
+
+

The Observability Best Practices Guide has examples of other Kubernetes metrics you can use to gain further insight.

+
+
+
+
+
+

Known Limits and Service Quotas

+
+
+

Amazon EKS can be used for a variety of workloads and can interact with a wide range of AWS services, and we have seen customer workloads encounter a similar range of AWS service quotas and other issues that hamper scalability.

+
+
+

Your AWS account has default quotas (an upper limit on the number of each AWS resource your team can request). Each AWS service defines their own quota, and quotas are generally region-specific. You can request increases for some quotas (soft limits), and other quotas cannot be increased (hard limits). You should consider these values when architecting your applications. Consider reviewing these service limits periodically and incorporate them during in your application design.

+
+
+

You can review the usage in your account and open a quota increase request at the AWS Service Quotas console, or using the AWS CLI. Refer to the AWS documentation from the respective AWS Service for more details on the Service Quotas and any further restrictions or notices on their increase.

+
+
+

!!! note + Amazon EKS Service Quotas lists the service quotas and has links to request increases where available.

+
+
+

Other AWS Service Quotas

+
+

We have seen EKS customers impacted by the quotas listed below for other AWS services. Some of these may only apply to specific use cases or configurations, however you may consider if your solution will encounter any of these as it scales. The Quotas are organized by Service and each Quota has an ID in the format of L-XXXXXXXX you can use to look it up in the AWS Service Quotas console

+
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ServiceQuota (L-xxxxx)ImpactID (L-xxxxx)default

IAM

Roles per account

Can limit the number of clusters or IRSA roles in an account.

L-FE177D64

1,000

IAM

OpenId connect providers per account

Can limit the number of Clusters per account, OpenID Connect is used by IRSA

L-858F3967

100

IAM

Role trust policy length

Can limit the number of of clusters an IAM role is associated with for IRSA

L-C07B4B0D

2,048

VPC

Security groups per network interface

Can limit the control or connectivity of the networking for your cluster

L-2AFB9258

5

VPC

IPv4 CIDR blocks per VPC

Can limit the number of EKS Worker Nodes

L-83CA0A9D

5

VPC

Routes per route table

Can limit the control or connectivity of the networking for your cluster

L-93826ACB

50

VPC

Active VPC peering connections per VPC

Can limit the control or connectivity of the networking for your cluster

L-7E9ECCDB

50

VPC

Inbound or outbound rules per security group.

Can limit the control or connectivity of the networking for your cluster, some controllers in EKS create new rules

L-0EA8095F

50

VPC

VPCs per Region

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-F678F1CE

5

VPC

Internet gateways per Region

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-A4707A72

5

VPC

Network interfaces per Region

Can limit the number of EKS Worker nodes, or Impact EKS control plane scaling/update activities.

L-DF5E4CA3

5,000

VPC

Network Address Usage

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-BB24F6E5

64,000

VPC

Peered Network Address Usage

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-CD17FD4B

128,000

ELB

Listeners per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-57A373D6

50

ELB

Target Groups per Region

Can limit the control of traffic ingress to the cluster.

L-B22855CB

3,000

ELB

Targets per Application Load Balancer

Can limit the control of traffic ingress to the cluster.

L-7E6692B2

1,000

ELB

Targets per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-EEF1AD04

3,000

ELB

Targets per Availability Zone per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-B211E961

500

ELB

Targets per Target Group per Region

Can limit the control of traffic ingress to the cluster.

L-A0D0B863

1,000

ELB

Application Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-53DA6B97

50

ELB

Classic Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-E9E9831D

20

ELB

Network Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-69A177A2

50

EC2

Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances (as a maximum vCPU count)

Can limit the number of EKS Worker Nodes

L-1216C47A

5

EC2

All Standard (A, C, D, H, I, M, R, T, Z) Spot Instance Requests (as a maximum vCPU count)

Can limit the number of EKS Worker Nodes

L-34B43A08

5

EC2

EC2-VPC Elastic IPs

Can limit the number of NAT GWs (and thus VPCs), which may limit the number of clusters in a region

L-0263D0A3

5

EBS

Snapshots per Region

Can limit the backup strategy for stateful workloads

L-309BACF6

100,000

EBS

Storage for General Purpose SSD (gp3) volumes, in TiB

Can limit the number of EKS Worker Nodes, or PersistentVolume storage

L-7A658B76

50

EBS

Storage for General Purpose SSD (gp2) volumes, in TiB

Can limit the number of EKS Worker Nodes, or PersistentVolume storage

L-D18FCD1D

50

ECR

Registered repositories

Can limit the number of workloads in your clusters

L-CFEB8E8D

10,000

ECR

Images per repository

Can limit the number of workloads in your clusters

L-03A36CE1

10,000

SecretsManager

Secrets per Region

Can limit the number of workloads in your clusters

L-2F66C23C

500,000

+
+
+

AWS Request Throttling

+
+

AWS services also implement request throttling to ensure that they remain performant and available for all customers. Simliar to Service Quotas, each AWS service maintains their own request throttling thresholds. Consider reviewing the respective AWS Service documentation if your workloads will need to quickly issue a large number of API calls or if you notice request throttling errors in your application.

+
+
+

EC2 API requests around provisioning EC2 network interfaces or IP addresses can encounter request throttling in large clusters or when clusters scale drastically. The table below shows some of the API actions that we have seen customers encounter request throttling from. +You can review the EC2 rate limit defaults and the steps to request a rate limit increase in the EC2 documentation on Rate Throttling.

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Mutating ActionsRead-only Actions

AssignPrivateIpAddresses

DescribeDhcpOptions

AttachNetworkInterface

DescribeInstances

CreateNetworkInterface

DescribeNetworkInterfaces

DeleteNetworkInterface

DescribeSecurityGroups

DeleteTags

DescribeTags

DetachNetworkInterface

DescribeVpcs

ModifyNetworkInterfaceAttribute

DescribeVolumes

UnassignPrivateIpAddresses

+
+
+

Other Known Limits

+
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/latest/bpg/scalability/kcp_monitoring.adoc b/latest/bpg/scalability/kcp_monitoring.adoc new file mode 100644 index 000000000..6e5d42fb7 --- /dev/null +++ b/latest/bpg/scalability/kcp_monitoring.adoc @@ -0,0 +1,251 @@ += Control Plane Monitoring +:authors: ["Shane Corbett"] +:date: 2023-09-22 + +== API Server + +When looking at our API server it's important to remember that one of its functions is to throttle inbound requests to prevent overloading the control plane. What can seem like a bottleneck at the API server level might actually be protecting it from more serious issues. We need to factor in the pros and cons of increasing the volume of requests moving through the system. To make a determination if the API server values should be increased, here is small sampling of the things we need to be mindful of: + +. What is the latency of requests moving through the system? +. Is that latency the API server itself, or something "`downstream`" like etcd? +. Is the API server queue depth a factor in this latency? +. Are the API Priority and Fairness (APF) queues setup correctly for the API call patterns we want? + +== Where is the issue? + +To start, we can use the metric for API latency to give us insight into how long it's taking the API server to service requests. Let's use the below PromQL and Grafana heatmap to display this data. + +---- +max(increase(apiserver_request_duration_seconds_bucket{subresource!="status",subresource!="token",subresource!="scale",subresource!="/healthz",subresource!="binding",subresource!="proxy",verb!="WATCH"}[$__rate_interval])) by (le) +---- + +!!! tip + For an in depth write up on how to monitor the API server with the API dashboard used in this article, please see the following https://aws.amazon.com/blogs/containers/troubleshooting-amazon-eks-api-servers-with-prometheus/[blog] + +image::../images/api-request-duration.png[API request duration heatmap] + +These requests are all under the one second mark, which is a good indication that the control plane is handling requests in a timely fashion. But what if that was not the case? + +The format we are using in the above API Request Duration is a heatmap. What's nice about the heatmap format, is that it tells us the timeout value for the API by default (60 sec). However, what we really need to know is at what threshold should this value be of concern before we reach the timeout threshold. For a rough guideline of what acceptable thresholds are we can use the upstream Kubernetes SLO, which can be found https://github.com/kubernetes/community/blob/master/sig-scalability/slos/slos.md#steady-state-slisslos[here] + +!!! tip + Notice the max function on this statement? When using metrics that are aggregating multiple servers (by default two API servers on EKS) it's important not to average those servers together. + +=== Asymmetrical traffic patterns + +What if one API server [pod] was lightly loaded, and the other heavily loaded? If we averaged those two numbers together we might misinterpret what was happening. For example, here we have three API servers but all of the load is on one of these API servers. As a rule anything that has multiple servers such as etcd and API servers should be broken out when investing scale and performance issues. + +image::../images/inflight-requests.png[Total inflight requests] + +With the move to API Priority and Fairness the total number of requests on the system is only one factor to check to see if the API server is oversubscribed. Since the system now works off a series of queues, we must look to see if any of these queues are full and if the traffic for that queue is getting dropped. + +Let's look at these queues with the following query: + +---- +max without(instance)(apiserver_flowcontrol_request_concurrency_limit{}) +---- + +!!! note + For more information on how API A&F works please see the following https://aws.github.io/aws-eks-best-practices/scalability/docs/control-plane/#api-priority-and-fairness[best practices guide] + +Here we see the seven different priority groups that come by default on the cluster + +image::../images/shared-concurrency.png[Shared concurrency] + +Next we want to see what percentage of that priority group is being used, so that we can understand if a certain priority level is being saturated. Throttling requests in the workload-low level might be desirable, however drops in a leader election level would not be. + +The API Priority and Fairness (APF) system has a number of complex options, some of those options can have unintended consequences. A common issue we see in the field is increasing the queue depth to the point it starts adding unnecessary latency. We can monitor this problem by using the `apiserver_flowcontrol_current_inqueue_request` metric. We can check for drops using the `apiserver_flowcontrol_rejected_requests_total`. These metrics will be a non-zero value if any bucket exceeds its concurrency. + +image::../images/requests-in-use.png[Requests in use] + +Increasing the queue depth can make the API Server a significant source of latency and should be done with care. We recommend being judicious with the number of queues created. For example, the number of shares on a EKS system is 600, if we create too many queues, this can reduce the shares in important queues that need the throughput such as the leader-election queue or system queue. Creating too many extra queues can make it more difficult to size theses queues correctly. + +To focus on a simple impactful change you can make in APF we simply take shares from underutilized buckets and increase the size of buckets that are at their max usage. By intelligently redistributing the shares among these buckets, you can make drops less likely. + +For more information, visit https://aws.github.io/aws-eks-best-practices/scalability/docs/control-plane/#api-priority-and-fairness[API Priority and Fairness settings] in the EKS Best Practices Guide. + +=== API vs. etcd latency + +How can we use the metrics/logs of the API server to determine whether there's a problem with API server, or a problem that's upstream/downstream of the API server, or a combination of both. To understand this better, lets look at how API Server and etcd can be related, and how easy it can be to troubleshoot the wrong system. + +In the below chart we see API server latency, but we also see much of this latency is correlated to the etcd server due to the bars in the graph showing most of the latency at the etcd level. If there is 15 secs of etcd latency at the same time there is 20 seconds of API server latency, then the majority of the latency is actually at the etcd level. + +By looking at the whole flow, we see that it's wise to not focus solely on the API Server, but also look for signals that indicate that etcd is under duress (i.e. slow apply counters increasing). Being able to quickly move to the right problem area with just a glance is what makes a dashboard powerful. + +!!! tip + The dashboard in section can be found at https://github.com/RiskyAdventure/Troubleshooting-Dashboards/blob/main/api-troubleshooter.json + +image::../images/etcd-duress.png[ETCD duress] + +=== Control plane vs. Client side issues + +In this chart we are looking for the API calls that took the most time to complete for that period. In this case we see a custom resource (CRD) is calling a APPLY function that is the most latent call during the 05:40 time frame. + +image::../images/slowest-requests.png[Slowest requests] + +Armed with this data we can use an Ad-Hoc PromQL or a CloudWatch Insights query to pull LIST requests from the audit log during that time frame to see which application this might be. + +=== Finding the Source with CloudWatch + +Metrics are best used to find the problem area we want to look at and narrow both the timeframe and the search parameters of the problem. Once we have this data we want to transition to logs for more detailed times and errors. To do this we will turn our logs into metrics using https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html[CloudWatch Logs Insights]. + +For example, to investigate the issue above, we will use the following CloudWatch Logs Insights query to pull the userAgent and requestURI so that we can pin down which application is causing this latency. + +!!! tip + An appropriate Count needs to be used as to not pull normal List/Resync behavior on a Watch. + +---- +fields *@timestamp*, *@message* +| filter *@logStream* like "kube-apiserver-audit" +| filter ispresent(requestURI) +| filter verb = "list" +| parse requestReceivedTimestamp /\d+-\d+-(?\d+)T(?\d+):(?\d+):(?\d+).(?\d+)Z/ +| parse stageTimestamp /\d+-\d+-(?\d+)T(?\d+):(?\d+):(?\d+).(?\d+)Z/ +| fields (StartHour * 3600 + StartMinute * 60 + StartSec + StartMsec / 1000000) as StartTime, (EndHour * 3600 + EndMinute * 60 + EndSec + EndMsec / 1000000) as EndTime, (EndTime - StartTime) as DeltaTime +| stats avg(DeltaTime) as AverageDeltaTime, count(*) as CountTime by requestURI, userAgent +| filter CountTime >=50 +| sort AverageDeltaTime desc +---- + +Using this query we found two different agents running a large number of high latency list operations. Splunk and CloudWatch agent. Armed with the data, we can make a decision to remove, update, or replace this controller with another project. + +image::../images/query-results.png[Query results] + +!!! tip + For more details on this subject please see the following https://aws.amazon.com/blogs/containers/troubleshooting-amazon-eks-api-servers-with-prometheus/[blog] + +== Scheduler + +Since the EKS control plane instances are run in separate AWS account we will not be able to scrape those components for metrics (The API server being the exception). However, since we have access to the audit logs for these components, we can turn those logs into metrics to see if any of the sub-systems are causing a scaling bottleneck. Let's use CloudWatch Logs Insights to see how many unscheduled pods are in the scheduler queue. + +=== Unscheduled pods in the scheduler log + +If we had access to scrape the scheduler metrics directly on a self managed Kubernetes (such as Kops) we would use the following PromQL to understand the scheduler backlog. + +---- +max without(instance)(scheduler_pending_pods) +---- + +Since we do not have access to the above metric in EKS, we will use the below CloudWatch Logs Insights query to see the backlog by checking for how many pods were unable to unscheduled during a particular time frame. Then we could dive further into into the messages at the peak time frame to understand the nature of the bottleneck. For example, nodes not spinning up fast enough, or the rate limiter in the scheduler itself. + +---- +fields timestamp, pod, err, *@message* +| filter *@logStream* like "scheduler" +| filter *@message* like "Unable to schedule pod" +| parse *@message* /^.(?\d{4})\s+(?\d+:\d+:\d+\.\d+)\s+\S*\s+\S+\]\s\"(.*?)\"\s+pod=(?\"(.*?)\")\s+err=(?\"(.*?)\")/ +| count(*) as count by pod, err +| sort count desc +---- + +Here we see the errors from the scheduler saying the pod did not deploy because the storage PVC was unavailable. + +image::../images/cwl-query.png[CloudWatch Logs query] + +!!! note + Audit logging must be turned on the control plane to enable this function. It is also a best practice to limit the log retention as to not drive up cost over time unnecessarily. An example for turning on all logging functions using the EKSCTL tool below. + +[,yaml] +---- +cloudWatch: + clusterLogging: + enableTypes: ["*"] + logRetentionInDays: 10 +---- + +== Kube Controller Manager + +Kube Controller Manager, like all other controllers, has limits on how many operations it can do at once. Let's review what some of those flags are by looking at a KOPS configuration where we can set these parameters. + +[,yaml] +---- + kubeControllerManager: + concurrentEndpointSyncs: 5 + concurrentReplicasetSyncs: 5 + concurrentNamespaceSyncs: 10 + concurrentServiceaccountTokenSyncs: 5 + concurrentServiceSyncs: 5 + concurrentResourceQuotaSyncs: 5 + concurrentGcSyncs: 20 + kubeAPIBurst: 20 + kubeAPIQPS: "30" +---- + +These controllers have queues that fill up during times of high churn on a cluster. In this case we see the replicaset set controller has a large backlog in its queue. + +image::../images/queues.png[Queues] + +We have two different ways of addressing such a situation. If running self managed we could simply increase the concurrent goroutines, however this would have an impact on etcd by processing more data in the KCM. The other option would be to reduce the number of replicaset objects using `.spec.revisionHistoryLimit` on the deployment to reduce the number of replicaset objects we can rollback, thus reducing the pressure on this controller. + +[,yaml] +---- +spec: + revisionHistoryLimit: 2 +---- + +Other Kubernetes features can be tuned or turned off to reduce pressure in high churn rate systems. For example, if the application in our pods doesn't need to speak to the k8s API directly then turning off the projected secret into those pods would decrease the load on ServiceaccountTokenSyncs. This is the more desirable way to address such issues if possible. + +[,yaml] +---- +kind: Pod +spec: + automountServiceAccountToken: false +---- + +In systems where we can't get access to the metrics, we can again look at the logs to detect contention. If we wanted to see the number of requests being being processed on a per controller or an aggregate level we would use the following CloudWatch Logs Insights Query. + +=== Total Volume Processed by the KCM + +---- +# Query to count API qps coming from kube-controller-manager, split by controller type. +# If you're seeing values close to 20/sec for any particular controller, it's most likely seeing client-side API throttling. +fields @timestamp, @logStream, @message +| filter @logStream like /kube-apiserver-audit/ +| filter userAgent like /kube-controller-manager/ +# Exclude lease-related calls (not counted under kcm qps) +| filter requestURI not like "apis/coordination.k8s.io/v1/namespaces/kube-system/leases/kube-controller-manager" +# Exclude API discovery calls (not counted under kcm qps) +| filter requestURI not like "?timeout=32s" +# Exclude watch calls (not counted under kcm qps) +| filter verb != "watch" +# If you want to get counts of API calls coming from a specific controller, uncomment the appropriate line below: +# | filter user.username like "system:serviceaccount:kube-system:job-controller" +# | filter user.username like "system:serviceaccount:kube-system:cronjob-controller" +# | filter user.username like "system:serviceaccount:kube-system:deployment-controller" +# | filter user.username like "system:serviceaccount:kube-system:replicaset-controller" +# | filter user.username like "system:serviceaccount:kube-system:horizontal-pod-autoscaler" +# | filter user.username like "system:serviceaccount:kube-system:persistent-volume-binder" +# | filter user.username like "system:serviceaccount:kube-system:endpointslice-controller" +# | filter user.username like "system:serviceaccount:kube-system:endpoint-controller" +# | filter user.username like "system:serviceaccount:kube-system:generic-garbage-controller" +| stats count(*) as count by user.username +| sort count desc +---- + +The key takeaway here is when looking into scalability issues, to look at every step in the path (API, scheduler, KCM, etcd) before moving to the detailed troubleshooting phase. Often in production you will find that it takes adjustments to more than one part of Kubernetes to allow the system to work at its most performant. It's easy to inadvertently troubleshoot what is just a symptom (such as a node timeout) of a much larger bottle neck. + +== ETCD + +etcd uses a memory mapped file to store key value pairs efficiently. There is a protection mechanism to set the size of this memory space available set commonly at the 2, 4, and 8GB limits. Fewer objects in the database means less clean up etcd needs to do when objects are updated and older versions needs to be cleaned out. This process of cleaning old versions of an object out is referred to as compaction. After a number of compaction operations, there is a subsequent process that recovers usable space space called defragging that happens above a certain threshold or on a fixed schedule of time. + +There are a couple user related items we can do to limit the number of objects in Kubernetes and thus reduce the impact of both the compaction and de-fragmentation process. For example, Helm keeps a high `revisionHistoryLimit`. This keeps older objects such as ReplicaSets on the system to be able to do rollbacks. By setting the history limits down to 2 we can reduce the the number of objects (like ReplicaSets) from ten to two which in turn would put less load on the system. + +[,yaml] +---- +apiVersion: apps/v1 +kind: Deployment +spec: + revisionHistoryLimit: 2 +---- + +From a monitoring standpoint, if system latency spikes occur in a set pattern separated by hours, checking to see if this defragmentation process is the source can be helpful. We can see this by using CloudWatch Logs. + +If you want to see start/end times of defrag use the following query: + +---- +fields *@timestamp*, *@message* +| filter *@logStream* like /etcd-manager/ +| filter *@message* like /defraging|defraged/ +| sort *@timestamp* asc +---- + +image::../images/defrag.png[Defrag query] diff --git a/latest/bpg/scalability/kubernetes_slos.adoc b/latest/bpg/scalability/kubernetes_slos.adoc new file mode 100644 index 000000000..be831a4cb --- /dev/null +++ b/latest/bpg/scalability/kubernetes_slos.adoc @@ -0,0 +1,157 @@ += Kubernetes Upstream SLOs + +Amazon EKS runs the same code as the upstream Kubernetes releases and ensures that EKS clusters operate within the SLOs defined by the Kubernetes community. The Kuberneteshttps://github.com/kubernetes/community/tree/master/sig-scalability[Scalability Special Interest Group (SIG)] defines the scalability goals and investigates bottlenecks in performance through SLIs and SLOs. + +SLIs are how we measure a system like metrics or measures that can be used to determine how "`well`" the system is running, e.g. request latency or count. SLOs define the values that are expected for when the system is running "`well`", e.g. request latency remains less than 3 seconds. The Kubernetes SLOs and SLIs focus on the performance of the Kubernetes components and are completely independent from the Amazon EKS Service SLAs which focus on availability of the EKS cluster endpoint. + +Kubernetes has a number of features that allow users to extend the system with custom add-ons or drivers, like CSI drivers, admission webhooks, and auto-scalers. These extensions can drastically impact the performance of a Kubernetes cluster in different ways, i.e. an admission webhook with `failurePolicy=Ignore` could add latency to K8s API requests if the webhook target is unavailable. The Kubernetes Scalability SIG defines scalability using a https://github.com/kubernetes/community/blob/master/sig-scalability/slos/slos.md#how-we-define-scalability["you promise, we promise" framework]: + +____ +If you promise to: + + - correctly configure your cluster + + - use extensibility features "reasonably" + + - keep the load in the cluster within https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md[recommended limits] + +then we promise that your cluster scales, i.e.: + + - all the SLOs are satisfied. +____ + +== Kubernetes SLOs + +The Kubernetes SLOs don't account for all of the plugins and external limitations that could impact a cluster, such as worker node scaling or admission webhooks. These SLOs focus on https://kubernetes.io/docs/concepts/overview/components/[Kubernetes components] and ensure that Kubernetes actions and resources are operating within expectations. The SLOs help Kubernetes developers ensure that changes to Kubernetes code do not degrade performance for the entire system. + +The https://github.com/kubernetes/community/blob/master/sig-scalability/slos/slos.md[Kuberntes Scalability SIG defines the following official SLO/SLIs]. The Amazon EKS team regularly runs scalability tests on EKS clusters for these SLOs/SLIs to monitor for performance degradation as changes are made and new versions are released. + +|=== +| Objective | Definition | SLO + +| API request latency (mutating) +| Latency of processing mutating API calls for single objects for every (resource, verb) pair, measured as 99th percentile over last 5 minutes +| In default Kubernetes installation, for every (resource, verb) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day \<= 1s + +| API request latency (read-only) +| Latency of processing non-streaming read-only API calls for every (resource, scope) pair, measured as 99th percentile over last 5 minutes +| In default Kubernetes installation, for every (resource, scope) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day: (a) \<= 1s if `scope=resource` (b) \<= 30s otherwise (if `scope=namespace` or `scope=cluster`) + +| Pod startup latency +| Startup latency of schedulable stateless pods, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch, measured as 99th percentile over last 5 minutes +| In default Kubernetes installation, 99th percentile per cluster-day \<= 5s +|=== + +=== API Request Latency + +The `kube-apiserver` has `--request-timeout` defined as `1m0s` by default, which means a request can run for up to one minute (60 seconds) before being timed out and cancelled. The SLOs defined for Latency are broken out by the type of request that is being made, which can be mutating or read-only: + +==== Mutating + +Mutating requests in Kubernetes make changes to a resource, such as creations, deletions, or updates. These requests are expensive because those changes must be written to https://kubernetes.io/docs/concepts/overview/components/#etcd[the etcd backend] before the updated object is returned. https://etcd.io/[Etcd] is a distributed key-value store that is used for all Kubernetes cluster data. + +This latency is measured as the 99th percentile over 5min for (resource, verb) pairs of Kubernetes resources, for example this would measure the latency for Create Pod requests and Update Node requests. The request latency must be \<= 1 second to satisfy the SLO. + +==== Read-only + +Read-only requests retrieve a single resource (such as Get Pod X) or a collection (such as "`Get all Pods from Namespace X`"). The `kube-apiserver` maintains a cache of objects, so the requested resources may be returned from cache or they may need to be retrieved from etcd first. +These latencies are also measured by the 99th percentile over 5 minutes, however read-only requests can have separate scopes. The SLO defines two different objectives: + +* For requests made for a _single_ resource (i.e. `kubectl get pod -n mynamespace my-controller-xxx` ), the request latency should remain \<= 1 second. +* For requests that are made for multiple resources in a namespace or a cluster (for example, `kubectl get pods -A`) the latency should remain \<= 30 seconds + +The SLO has different target values for different request scopes because requests made for a list of Kubernetes resources expect the details of all objects in the request to be returned within the SLO. On large clusters, or large collections of resources, this can result in large response sizes which can take some time to return. For example, in a cluster running tens of thousands of Pods with each Pod being roughly 1 KiB when encoded in JSON, returning all Pods in the cluster would consist of 10MB or more. Kubernetes clients can help reduce this response size https://kubernetes.io/docs/reference/using-api/api-concepts/#retrieving-large-results-sets-in-chunks[using APIListChunking to retrieve large collections of resources]. + +=== Pod Startup Latency + +This SLO is primarily concerned with the time it takes from Pod creation to when the containers in that Pod actually begin execution. To measure this the difference from the creation timestamp recorded on the Pod, and when https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes[a WATCH on that Pod] reports the containers have started is calculated (excluding time for container image pulls and init container execution). To satisfy the SLO the 99th percentile per cluster-day of this Pod Startup Latency must remain \<=5 seconds. + +Note that this SLO assumes that the worker nodes already exist in this cluster in a ready state for the Pod to be scheduled on. This SLO does not account for image pulls or init container executions, and also limits the test to "`stateless pods`" which don't leverage persistent storage plugins. + +== Kubernetes SLI Metrics + +Kubernetes is also improving the Observability around the SLIs by adding https://prometheus.io/docs/concepts/data_model/[Prometheus metrics] to Kubernetes components that track these SLIs over time. Using https://prometheus.io/docs/prometheus/latest/querying/basics/[Prometheus Query Language (PromQL)] we can build queries that display the SLI performance over time in tools like Prometheus or Grafana dashboards, below are some examples for the SLOs above. + +=== API Server Request Latency + +|=== +| Metric | Definition + +| apiserver_request_sli_duration_seconds +| Response latency distribution (not counting webhook duration and priority & fairness queue wait times) in seconds for each verb, group, version, resource, subresource, scope and component. + +| apiserver_request_duration_seconds +| Response latency distribution in seconds for each verb, dry run value, group, version, resource, subresource, scope and component. +|=== + +_Note: The `apiserver_request_sli_duration_seconds` metric is available starting in Kubernetes 1.27._ + +You can use these metrics to investigate the API Server response times and if there are bottlenecks in the Kubernetes components or other plugins/components. The queries below are based on https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards[the community SLO dashboard]. + +*API Request latency SLI (mutating)* - this time does _not_ include webhook execution or time waiting in queue. + +`histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0` + +*API Request latency Total (mutating)* - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and API Priority and Fairness wait times. + +`histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0` + +In these queries we are excluding the streaming API requests which do not return immediately, such as `kubectl port-forward` or `kubectl exec` requests (`subresource!~"proxy|attach|log|exec|portforward"`), and we are filtering for only the Kubernetes verbs that modify objects (`verb=~"CREATE|DELETE|PATCH|POST|PUT"`). We are then calculating the 99th percentile of that latency over the last 5 minutes. + +We can use a similar query for the read only API requests, we simply modify the verbs we're filtering for to include the Read only actions `LIST` and `GET`. There are also different SLO thresholds depending on the scope of the request, i.e. getting a single resource or listing a number of resources. + +*API Request latency SLI (read-only)* - this time does _not_ include webhook execution or time waiting in queue. +For a single resource (scope=resource, threshold=1s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))` + +For a collection of resources in the same namespace (scope=namespace, threshold=5s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))` + +For a collection of resources across the entire cluster (scope=cluster, threshold=30s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))` + +*API Request latency Total (read-only)* - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and wait times. +For a single resource (scope=resource, threshold=1s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))` + +For a collection of resources in the same namespace (scope=namespace, threshold=5s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))` + +For a collection of resources across the entire cluster (scope=cluster, threshold=30s) + +`histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))` + +The SLI metrics provide insight into how Kubernetes components are performing by excluding the time that requests spend waiting in API Priority and Fairness queues, working through admission webhooks, or other Kubernetes extensions. The total metrics provide a more holistic view as it reflects the time your applications would be waiting for a response from the API server. Comparing these metrics can provide insight into where the delays in request processing are being introduced. + +=== Pod Startup Latency + +|=== +| Metric | Definition + +| kubelet_pod_start_sli_duration_seconds +| Duration in seconds to start a pod, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch + +| kubelet_pod_start_duration_seconds +| Duration in seconds from kubelet seeing a pod for the first time to the pod starting to run. This does not include the time to schedule the pod or scale out worker node capacity. +|=== + +_Note: `kubelet_pod_start_sli_duration_seconds` is available starting in Kubernetes 1.27._ + +Similar to the queries above you can use these metrics to gain insight into how long node scaling, image pulls and init containers are delaying the pod launch compared to Kubelet actions. + +*Pod startup latency SLI -* this is the time from the pod being created to when the application containers reported as running. This includes the time it takes for the worker node capacity to be available and the pod to be scheduled, but this does not include the time it takes to pull images or for the init containers to run. + +`histogram_quantile(0.99, sum(rate(kubelet_pod_start_sli_duration_seconds_bucket[5m])) by (le))` + +*Pod startup latency Total -* this is the time it takes the kubelet to start the pod for the first time. This is measured from when the kubelet recieves the pod via WATCH, which does not include the time for worker node scaling or scheduling. This includes the time to pull images and init containers to run. + +`histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))` + +== SLOs on Your Cluster + +If you are collecting the Prometheus metrics from the Kubernetes resources in your EKS cluster you can gain deeper insights into the performance of the Kubernetes control plane components. + +The https://github.com/kubernetes/perf-tests/[perf-tests repo] includes Grafana dashboards that display the latencies and critical performance metrics for the cluster during tests. The perf-tests configuration leverages the https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack[kube-prometheus-stack], an open source project that comes configured to collect Kubernetes metrics, but you can also https://aws-observability.github.io/terraform-aws-observability-accelerator/eks/[use Amazon Managed Prometheus and Amazon Managed Grafana.] + +If you are using the `kube-prometheus-stack` or similar Prometheus solution you can install the same dashboard to observe the SLOs on your cluster in real time. + +. You will first need to install the Prometheus Rules that are used in the dashboards with `kubectl apply -f prometheus-rules.yaml`. You can download a copy of the rules here: https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/prometheus-rules.yaml + .. Be sure to check the namespace in the file matches your environment + .. Verify that the labels match the `prometheus.prometheusSpec.ruleSelector` helm value if you are using `kube-prometheus-stack` +. You can then install the dashboards in Grafana. The json dashboards and python scripts to generate them are available here: https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards + .. https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/dashboards/slo.json[the `slo.json` dashboard] displays the performance of the cluster in relation to the Kubernetes SLOs + +Consider that the SLOs are focused on the performance of the Kubernetes components in your clusters, but there are additional metrics you can review which provide different perspectives or insights in to your cluster. Kubernetes community projects like https://github.com/kubernetes/kube-state-metrics/tree/main[Kube-state-metrics] can help you quickly analyze trends in your cluster. Most common plugins and drivers from the Kubernetes community also emit Prometheus metrics, allowing you to investigate things like autoscalers or custom schedulers. + +The https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/best-practices-metrics-collection/#control-plane-metrics[Observability Best Practices Guide] has examples of other Kubernetes metrics you can use to gain further insight. diff --git a/latest/bpg/scalability/node_efficiency.adoc b/latest/bpg/scalability/node_efficiency.adoc new file mode 100644 index 000000000..6ba5d1fb1 --- /dev/null +++ b/latest/bpg/scalability/node_efficiency.adoc @@ -0,0 +1,266 @@ += Node and Workload Efficiency +:authors: ["Shane Corbett"] +:date: 2023-09-22 + +Being efficient with our workloads and nodes reduces complexity/cost while increasing performance and scale. There are many factors to consider when planning this efficiency, and it's easiest to think in terms of trade offs vs. one best practice setting for each feature. Let's explore these tradeoffs in depth in the following section. + +== Node Selection + +Using node sizes that are slightly larger (4-12xlarge) increases the available space that we have for running pods due to the fact it reduces the percentage of the node used for "`overhead`" such as https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[DaemonSets] and https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/[Reserves] for system components. In the diagram below we see the difference between the usable space on a 2xlarge vs. a 8xlarge system with just a moderate number of DaemonSets. + +!!! note + Since k8s scales horizontally as a general rule, for most applications it does not make sense to take the performance impact of NUMA sizes nodes, thus the recommendation of a range below that node size. + +image::../images/node-size.png[Node size] + +Large nodes sizes allow us to have a higher percentage of usable space per node. However, this model can be taken to to the extreme by packing the node with so many pods that it causes errors or saturates the node. Monitoring node saturation is key to successfully using larger node sizes. + +Node selection is rarely a one-size-fits-all proposition. Often it is best to split workloads with dramatically different churn rates into different node groups. Small batch workloads with a high churn rate would be best served by the the 4xlarge family of instances, while a large scale application such as Kafka which takes 8 vCPU and has a low churn rate would be better served by the 12xlarge family. + +image::../images/churn-rate.png[Churn rate] + +!!! tip + Another factor to consider with very large node sizes is since CGROUPS do not hide the total number of vCPU from the containerized application. Dynamic runtimes can often spawn an unintentional number of OS threads, creating latency that is difficult to troubleshoot. For these application https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy[CPU pinning] is recommend. For a deeper exploration of topic please see the following video https://www.youtube.com/watch?v=NqtfDy_KAqg + +== Node Bin-packing + +=== Kubernetes vs. Linux Rules + +There are two sets of rules we need to be mindful of when dealing with workloads on Kubernetes. The rules of the Kubernetes Scheduler, which uses the request value to schedule pods on a node, and then what happens after the pod is scheduled, which is the realm of Linux, not Kubernetes. + +After Kubernetes scheduler is finished, a new set of rules takes over, the Linux Completely Fair Scheduler (CFS). The key take away is that Linux CFS doesn't have a the concept of a core. We will discuss why thinking in cores can lead to major problems with optimizing workloads for scale. + +=== Thinking in Cores + +The confusion starts because the Kubernetes scheduler does have the concept of cores. From a Kubernetes scheduler perspective if we looked at a node with 4 NGINX pods, each with a request of one core set, the node would look like this. + +image::../images/cores-1.png[] + +However, let's do a thought experiment on how different this looks from a Linux CFS perspective. The most important thing to remember when using the Linux CFS system is: busy containers (CGROUPS) are the only containers that count toward the share system. In this case, only the first container is busy so it is allowed to use all 4 cores on the node. + +image::../images/cores-2.png[] + +Why does this matter? Let's say we ran our performance testing in a development cluster where an NGINX application was the only busy container on that node. When we move the app to production, the following would happen: the NGINX application wants 4 vCPU of resources however, because all the other pods on the node are busy, our app's performance is constrained. + +image::../images/cores-3.png[] + +This situation would lead us to add more containers unnecessarily because we were not allowing our applications scale to their "`sweet spot"`. Let's explore this important concept of a `"sweet spot"` in a bit more detail. + +=== Application right sizing + +Each application has a certain point where it can not take anymore traffic. Going above this point can increase processing times and even drop traffic when pushed well beyond this point. This is known as the application's saturation point. To avoid scaling issues, we should attempt to scale the application *before* it reaches its saturation point. Let's call this point the sweet spot. + +image::../images/sweet-spot.png[The sweet spot] + +We need to test each of our applications to understand its sweet spot. There will be no universal guidance here as each application is different. During this testing we are trying to understand the best metric that shows our applications saturation point. Oftentimes, utilization metrics are used to indicate an application is saturated but this can quickly lead to scaling issues (We will explore this topic in detail in a later section). Once we have this "`sweet spot"` we can use it to efficiently scale our workloads. + +Conversely, what would happen if we scale up well before the sweet spot and created unnecessary pods? Let's explore that in the next section. + +=== Pod sprawl + +To see how creating unnecessary pods could quickly get out of hand, let's look at the first example on the left. The correct vertical scale of this container takes up about two vCPUs worth of utilization when handling 100 requests a second. However, If we were to under-provision the requests value by setting requests to half a core, we would now need 4 pods for each one pods we actually needed. Exacerbating this problem further, if our https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/[HPA] was set at the default of 50% CPU, those pods would scale half empty, creating an 8:1 ratio. + +image::../images/scaling-ratio.png[] + +Scaling this problem up we can quickly see how this can get out of hand. A deployment of ten pods whose sweet spot was set incorrectly could quickly spiral to 80 pods and the additional infrastructure needed to run them. + +image::../images/bad-sweetspot.png[] + +Now that we understand the impact of not allowing applications to operate in their sweet spot, let's return to the node level and ask why this difference between the Kubernetes scheduler and Linux CFS so important? + +When scaling up and down with HPA, we can have a scenario where we have a lot of space to allocate more pods. This would be a bad decision because the node depicted on the left is already at 100% CPU utilization. In a unrealistic but theoretically possible scenario, we could have the other extreme where our node is completely full, yet our CPU utilization is zero. + +image::../images/hpa-utilization.png[] + +=== Setting Requests + +It would tempting to set the request at the "`sweet spot`" value for that application, however this would cause inefficiencies as pictured in the diagram below. Here we have set the request value to 2 vCPU, however the average utilization of these pods runs only 1 CPU most of the time. This setting would cause us to waste 50% of our CPU cycles, which would be unacceptable. + +image::../images/requests-1.png[] + +This bring us to the complex answer to problem. Container utilization cannot be thought of in a vacuum; one must take into account the other applications running on the node. In the following example containers that are bursty in nature are mixed in with two low CPU utilization containers that might be memory constrained. In this way we allow the containers to hit their sweet spot without taxing the node. + +image::../images/requests-2.png[] + +The important concept to take away from all this is that using Kubernetes scheduler concept of cores to understand Linux container performance can lead to poor decision making as they are not related. + +!!! tip + Linux CFS has its strong points. This is especially true for I/O based workloads. However, if your application uses full cores without sidecars, and has no I/O requirements, CPU pinning can remove a great deal of complexity from this process and is encouraged with those caveats. + +== Utilization vs. Saturation + +A common mistake in application scaling is only using CPU utilization for your scaling metric. In complex applications this is almost always a poor indicator that an application is actually saturated with requests. In the example on the left, we see all of our requests are actually hitting the web server, so CPU utilization is tracking well with saturation. + +In real world applications, it's likely that some of those requests will be getting serviced by a database layer or an authentication layer, etc. In this more common case, notice CPU is not tracking with saturation as the request is being serviced by other entities. In this case CPU is a very poor indicator for saturation. + +image::../images/util-vs-saturation-1.png[] + +Using the wrong metric in application performance is the number one reason for unnecessary and unpredictable scaling in Kubernetes. Great care must be taken in picking the correct saturation metric for the type of application that you're using. It is important to note that there is not a one size fits all recommendation that can be given. Depending on the language used and the type of application in question, there is a diverse set of metrics for saturation. + +We might think this problem is only with CPU Utilization, however other common metrics such as request per second can also fall into the exact same problem as discussed above. Notice the request can also go to DB layers, auth layers, not being directly serviced by our web server, thus it's a poor metric for true saturation of the web server itself. + +image::../images/util-vs-saturation-2.png[] + +Unfortunately there are no easy answers when it comes to picking the right saturation metric. Here are some guidelines to take into consideration: + +* Understand your language runtime - languages with multiple OS threads will react differently than single threaded applications, thus impacting the node differently. +* Understand the correct vertical scale - how much buffer do you want in your applications vertical scale before scaling a new pod? +* What metrics truly reflect the saturation of your application - The saturation metric for a Kafka Producer would be quite different than a complex web application. +* How do all the other applications on the node effect each other - Application performance is not done in a vacuum the other workloads on the node have a major impact. + +To close out this section, it would be easy to dismiss the above as overly complex and unnecessary. It can often be the case that we are experiencing an issue but we are unaware of the true nature of the problem because we are looking at the wrong metrics. In the next section we will look at how that could happen. + +=== Node Saturation + +Now that we have explored application saturation, let's look at this same concept from a node point of view. Let's take two CPUs that are 100% utilized to see the difference between utilization vs. saturation. + +The vCPU on the left is 100% utilized, however no other tasks are waiting to run on this vCPU, so in a purely theoretical sense, this is quite efficient. Meanwhile, we have 20 single threaded applications waiting to get processed by a vCPU in the second example. All 20 applications now will experience some type of latency while they're waiting their turn to be processed by the vCPU. In other words, the vCPU on the right is saturated. + +Not only would we not see this problem if we where just looking at utilization, but we might attribute this latency to something unrelated such as networking which would lead us down the wrong path. + +image::../images/node-saturation.png[] + +It is important to view saturation metrics, not just utilization metrics when increasing the total number of pods running on a node at any given time as we can easily miss the fact we have over-saturated a node. For this task we can use pressure stall information metrics as seen in the below chart. + +PromQL - Stalled I/O + +---- +topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100)) +---- + +image::../images/stalled-io.png[] + +!!! note + For more on Pressure stall metrics, see https://facebookmicrosites.github.io/psi/docs/overview* + +With these metrics we can tell if threads are waiting on CPU, or even if every thread on the box is stalled waiting on resource like memory or I/O. For example, we could see what percentage every thread on the instance was stalled waiting on I/O over the period of 1 min. + +---- +topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100)) +---- + +Using this metric, we can see in the above chart every thread on the box was stalled 45% of the time waiting on I/O at the high water mark, meaning we were throwing away all of those CPU cycles in that minute. Understanding that this is happening can help us reclaim a significant amount of vCPU time, thus making scaling more efficient. + +=== HPA V2 + +It is recommended to use the autoscaling/v2 version of the HPA API. The older versions of the HPA API could get stuck scaling in certain edge cases. It was also limited to pods only doubling during each scaling step, which created issues for small deployments that needed to scale rapidly. + +Autoscaling/v2 allows us more flexibility to include multiple criteria to scale on and allows us a great deal of flexibility when using custom and external metrics (non K8s metrics). + +As an example, we can scaling on the highest of three values (see below). We scale if the average utilization of all the pods are over 50%, if custom metrics the packets per second of the ingress exceed an average of 1,000, or ingress object exceeds 10K request per second. + +!!! note + This is just to show the flexibility of the auto-scaling API, we recommend against overly complex rules that can be difficult to troubleshoot in production. + +[,yaml] +---- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: php-apache +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: php-apache + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 + - type: Pods + pods: + metric: + name: packets-per-second + target: + type: AverageValue + averageValue: 1k + - type: Object + object: + metric: + name: requests-per-second + describedObject: + apiVersion: networking.k8s.io/v1 + kind: Ingress + name: main-route + target: + type: Value + value: 10k +---- + +However, we learned the danger of using such metrics for complex web applications. In this case we would be better served by using custom or external metric that accurately reflects the saturation of our application vs. the utilization. HPAv2 allows for this by having the ability to scale according to any metric, however we still need to find and export that metric to Kubernetes for use. + +For example, we can look at the active thread queue count in Apache. This often creates a "`smoother`" scaling profile (more on that term soon). If a thread is active, it doesn't matter if that thread is waiting on a database layer or servicing a request locally, if all of the applications threads are being used, it's a great indication that application is saturated. + +We can use this thread exhaustion as a signal to create a new pod with a fully available thread pool. This also gives us control over how big a buffer we want in the application to absorb during times of heavy traffic. For example, if we had a total thread pool of 10, scaling at 4 threads used vs. 8 threads used would have a major impact on the buffer we have available when scaling the application. A setting of 4 would make sense for an application that needs to rapidly scale under heavy load, where a setting of 8 would be more efficient with our resources if we had plenty of time to scale due to the number of requests increasing slowly vs. sharply over time. + +image::../images/thread-pool.png[] + +What do we mean by the term "`smooth`" when it comes to scaling? Notice the below chart where we are using CPU as a metric. The pods in this deployment are spiking in a short period for from 50 pods, all the way up to 250 pods only to immediately scale down again. This is highly inefficient scaling is the leading cause on churn on clusters. + +image::../images/spiky-scaling.png[] + +Notice how after we change to a metric that reflects the correct sweet spot of our application (mid-part of chart), we are able to scale smoothly. Our scaling is now efficient, and our pods are allowed to fully scale with the headroom we provided by adjusting requests settings. Now a smaller group of pods are doing the work the hundreds of pods were doing before. Real world data shows that this is the number one factor in scalability of Kubernetes clusters. + +image::../images/smooth-scaling.png[] + +The key takeaway is CPU utilization is only one dimension of both application and node performance. Using CPU utilization as a sole health indicator for our nodes and applications creates problems in scaling, performance and cost which are all tightly linked concepts. The more performant the application and nodes are, the less that you need to scale, which in turn lowers your costs. + +Finding and using the correct saturation metrics for scaling your particular application also allows you to monitor and alarm on the true bottlenecks for that application. If this critical step is skipped, reports of performance problems will be difficult, if not impossible, to understand. + +== Setting CPU Limits + +To round out this section on misunderstood topics, we will cover CPU limits. In short, limits are metadata associated with the container that has a counter that resets every 100ms. This helps Linux keep track of how many CPU resources are used node-wide by a specific container in a 100ms period of time. + +image::../images/cpu-limits.png[CPU limits] + +A common error with setting limits is assuming that the application is single threaded and only running on it's "`assigned"` vCPU. In the above section we learned that CFS doesn't assign cores, and in reality a container running large thread pools will schedule on all available vCPU's on the box. + +If 64 OS threads are running across 64 available cores (from a Linux node perspective) we will make the total bill of used CPU time in a 100ms period quite large after the time running on all of those 64 cores are added up. Since this might only occur during a garbage collection process it can be quite easy to miss something like this. This is why it is necessary to use metrics to ensure we have the correct usage over time before attempting to set a limit. + +Fortunately, we have a way to see exactly how much vCPU is being used by all the threads in a application. We will use the metric `container_cpu_usage_seconds_total` for this purpose. + +Since throttling logic happens every 100ms and this metric is a per second metric, we will PromQL to match this 100ms period. If you would like to dive deep into this PromQL statement work please see the following https://aws.amazon.com/blogs/containers/using-prometheus-to-avoid-disasters-with-kubernetes-cpu-limits/[blog]. + +PromQL query: + +---- +topk(3, max by (pod, container)(rate(container_cpu_usage_seconds_total{image!="", instance="$instance"}[$__rate_interval]))) / 10 +---- + +image::../images/cpu-1.png[] + +Once we feel we have the right value, we can put the limit in production. It then becomes necessary to see if our application is being throttled due to something unexpected. We can do this by looking at `container_cpu_throttled_seconds_total` + +---- +topk(3, max by (pod, container)(rate(container_cpu_cfs_throttled_seconds_total{image!=``""``, instance=``"$instance"``}[$__rate_interval]))) / 10 +---- + +image::../images/cpu-2.png[] + +=== Memory + +The memory allocation is another example where it is easy to confuse Kubernetes scheduling behavior for Linux CGroup behavior. This is a more nuanced topic as there have been major changes in the way that CGroup v2 handles memory in Linux and Kubernetes has changed its syntax to reflect this; read this https://kubernetes.io/blog/2021/11/26/qos-memory-resources/[blog] for further details. + +Unlike CPU requests, memory requests go unused after the scheduling process completes. This is because we can not compress memory in CGroup v1 the same way we can with CPU. That leaves us with just memory limits, which are designed to act as a fail safe for memory leaks by terminating the pod completely. This is an all or nothing style proposition, however we have now been given new ways to address this problem. + +First, it is important to understand that setting the right amount of memory for containers is not a straightforward as it appears. The file system in Linux will use memory as a cache to improve performance. This cache will grow over time, and it can be hard to know how much memory is just nice to have for the cache but can be reclaimed without a significant impact to application performance. This often results in misinterpreting memory usage. + +Having the ability to "`compress`" memory was one of the primary drivers behind CGroup v2. For more history on why CGroup V2 was necessary, please see Chris Down's https://www.youtube.com/watch?v=kPMZYoRxtmg[presentation] at LISA21 where he covers why being unable to set the minimum memory correctly was one of the reasons that drove him to create CGroup v2 and pressure stall metrics. + +Fortunately, Kubernetes now has the concept of `memory.min` and `memory.high` under `requests.memory`. This gives us the option of aggressive releasing this cached memory for other containers to use. Once the container hits the memory high limit, the kernel can aggressively reclaim that container's memory up to the value set at `memory.min`. Thus giving us more flexibility when a node comes under memory pressure. + +The key question becomes, what value to set `memory.min` to? This is where memory pressure stall metrics come into play. We can use these metrics to detect memory "`thrashing`" at a container level. Then we can use controllers such as https://facebookmicrosites.github.io/cgroup2/docs/fbtax-results.html[fbtax] to detect the correct values for `memory.min` by looking for this memory thrashing, and dynamically set the `memory.min` value to this setting. + +=== Summary + +To sum up the section, it is easy to conflate the following concepts: + +* Utilization and Saturation +* Linux performance rules with Kubernetes Scheduler logic + +Great care must be taken to keep these concepts separated. Performance and scale are linked on a deep level. Unnecessary scaling creates performance problems, which in turn creates scaling problems. diff --git a/latest/bpg/scalability/quotas.adoc b/latest/bpg/scalability/quotas.adoc new file mode 100644 index 000000000..3ca148bfd --- /dev/null +++ b/latest/bpg/scalability/quotas.adoc @@ -0,0 +1,247 @@ += Known Limits and Service Quotas + +Amazon EKS can be used for a variety of workloads and can interact with a wide range of AWS services, and we have seen customer workloads encounter a similar range of AWS service quotas and other issues that hamper scalability. + +Your AWS account has default quotas (an upper limit on the number of each AWS resource your team can request). Each AWS service defines their own quota, and quotas are generally region-specific. You can request increases for some quotas (soft limits), and other quotas cannot be increased (hard limits). You should consider these values when architecting your applications. Consider reviewing these service limits periodically and incorporate them during in your application design. + +You can review the usage in your account and open a quota increase request at the https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-resource-limits.html#request-increase[AWS Service Quotas console], or using https://repost.aws/knowledge-center/request-service-quota-increase-cli[the AWS CLI]. Refer to the AWS documentation from the respective AWS Service for more details on the Service Quotas and any further restrictions or notices on their increase. + +!!! note + https://docs.aws.amazon.com/eks/latest/userguide/service-quotas.html[Amazon EKS Service Quotas] lists the service quotas and has links to request increases where available. + +== Other AWS Service Quotas + +We have seen EKS customers impacted by the quotas listed below for other AWS services. Some of these may only apply to specific use cases or configurations, however you may consider if your solution will encounter any of these as it scales. The Quotas are organized by Service and each Quota has an ID in the format of L-XXXXXXXX you can use to look it up in the https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-resource-limits.html#request-increase[AWS Service Quotas console] + +|=== +| Service | Quota (L-xxxxx) | *Impact* | *ID (L-xxxxx)* | default + +| IAM +| Roles per account +| Can limit the number of clusters or IRSA roles in an account. +| L-FE177D64 +| 1,000 + +| IAM +| OpenId connect providers per account +| Can limit the number of Clusters per account, OpenID Connect is used by IRSA +| L-858F3967 +| 100 + +| IAM +| Role trust policy length +| Can limit the number of of clusters an IAM role is associated with for IRSA +| L-C07B4B0D +| 2,048 + +| VPC +| Security groups per network interface +| Can limit the control or connectivity of the networking for your cluster +| L-2AFB9258 +| 5 + +| VPC +| IPv4 CIDR blocks per VPC +| Can limit the number of EKS Worker Nodes +| L-83CA0A9D +| 5 + +| VPC +| Routes per route table +| Can limit the control or connectivity of the networking for your cluster +| L-93826ACB +| 50 + +| VPC +| Active VPC peering connections per VPC +| Can limit the control or connectivity of the networking for your cluster +| L-7E9ECCDB +| 50 + +| VPC +| Inbound or outbound rules per security group. +| Can limit the control or connectivity of the networking for your cluster, some controllers in EKS create new rules +| L-0EA8095F +| 50 + +| VPC +| VPCs per Region +| Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster +| L-F678F1CE +| 5 + +| VPC +| Internet gateways per Region +| Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster +| L-A4707A72 +| 5 + +| VPC +| Network interfaces per Region +| Can limit the number of EKS Worker nodes, or Impact EKS control plane scaling/update activities. +| L-DF5E4CA3 +| 5,000 + +| VPC +| Network Address Usage +| Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster +| L-BB24F6E5 +| 64,000 + +| VPC +| Peered Network Address Usage +| Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster +| L-CD17FD4B +| 128,000 + +| ELB +| Listeners per Network Load Balancer +| Can limit the control of traffic ingress to the cluster. +| L-57A373D6 +| 50 + +| ELB +| Target Groups per Region +| Can limit the control of traffic ingress to the cluster. +| L-B22855CB +| 3,000 + +| ELB +| Targets per Application Load Balancer +| Can limit the control of traffic ingress to the cluster. +| L-7E6692B2 +| 1,000 + +| ELB +| Targets per Network Load Balancer +| Can limit the control of traffic ingress to the cluster. +| L-EEF1AD04 +| 3,000 + +| ELB +| Targets per Availability Zone per Network Load Balancer +| Can limit the control of traffic ingress to the cluster. +| L-B211E961 +| 500 + +| ELB +| Targets per Target Group per Region +| Can limit the control of traffic ingress to the cluster. +| L-A0D0B863 +| 1,000 + +| ELB +| Application Load Balancers per Region +| Can limit the control of traffic ingress to the cluster. +| L-53DA6B97 +| 50 + +| ELB +| Classic Load Balancers per Region +| Can limit the control of traffic ingress to the cluster. +| L-E9E9831D +| 20 + +| ELB +| Network Load Balancers per Region +| Can limit the control of traffic ingress to the cluster. +| L-69A177A2 +| 50 + +| EC2 +| Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances (as a maximum vCPU count) +| Can limit the number of EKS Worker Nodes +| L-1216C47A +| 5 + +| EC2 +| All Standard (A, C, D, H, I, M, R, T, Z) Spot Instance Requests (as a maximum vCPU count) +| Can limit the number of EKS Worker Nodes +| L-34B43A08 +| 5 + +| EC2 +| EC2-VPC Elastic IPs +| Can limit the number of NAT GWs (and thus VPCs), which may limit the number of clusters in a region +| L-0263D0A3 +| 5 + +| EBS +| Snapshots per Region +| Can limit the backup strategy for stateful workloads +| L-309BACF6 +| 100,000 + +| EBS +| Storage for General Purpose SSD (gp3) volumes, in TiB +| Can limit the number of EKS Worker Nodes, or PersistentVolume storage +| L-7A658B76 +| 50 + +| EBS +| Storage for General Purpose SSD (gp2) volumes, in TiB +| Can limit the number of EKS Worker Nodes, or PersistentVolume storage +| L-D18FCD1D +| 50 + +| ECR +| Registered repositories +| Can limit the number of workloads in your clusters +| L-CFEB8E8D +| 10,000 + +| ECR +| Images per repository +| Can limit the number of workloads in your clusters +| L-03A36CE1 +| 10,000 + +| SecretsManager +| Secrets per Region +| Can limit the number of workloads in your clusters +| L-2F66C23C +| 500,000 +|=== + +== AWS Request Throttling + +AWS services also implement request throttling to ensure that they remain performant and available for all customers. Simliar to Service Quotas, each AWS service maintains their own request throttling thresholds. Consider reviewing the respective AWS Service documentation if your workloads will need to quickly issue a large number of API calls or if you notice request throttling errors in your application. + +EC2 API requests around provisioning EC2 network interfaces or IP addresses can encounter request throttling in large clusters or when clusters scale drastically. The table below shows some of the API actions that we have seen customers encounter request throttling from. +You can review the EC2 rate limit defaults and the steps to request a rate limit increase in the https://docs.aws.amazon.com/AWSEC2/latest/APIReference/throttling.html[EC2 documentation on Rate Throttling]. + +|=== +| Mutating Actions | Read-only Actions + +| AssignPrivateIpAddresses +| DescribeDhcpOptions + +| AttachNetworkInterface +| DescribeInstances + +| CreateNetworkInterface +| DescribeNetworkInterfaces + +| DeleteNetworkInterface +| DescribeSecurityGroups + +| DeleteTags +| DescribeTags + +| DetachNetworkInterface +| DescribeVpcs + +| ModifyNetworkInterfaceAttribute +| DescribeVolumes + +| UnassignPrivateIpAddresses +| +|=== + +== Other Known Limits + +* Route 53 DNS resolvers are limited to https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-limits[1024 Packets per second]. This limit can be encountered when DNS traffic from a large cluster is funneled through a small number of CoreDNS Pod replicas. link:../cluster-services/#scale-coredns[Scaling CoreDNS and optimizing DNS behavior] can avoid timeouts on DNS lookups. + ** https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests[Route 53 also has a fairly low rate limit of 5 requests per second to the Route 53 API]. If you have a large number of domains to update with a project like External DNS you may see rate throttling and delays in updating domains. +* Some https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html#instance-type-volume-limits[Nitro instance types have a volume attachment limit of 28] that is shared between Amazon EBS volumes, network interfaces, and NVMe instance store volumes. If your workloads are mounting numerous EBS volumes you may encounter limits to the pod density you can achieve with these instance types +* There is a maximum number of connections that can be tracked per Ec2 instance. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html#connection-tracking-throttling[If your workloads are handling a large number of connections you may see communication failures or errors because this maximum has been hit.] You can use the `conntrack_allowance_available` and `conntrack_allowance_exceeded` https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html[network performance metrics to monitor the number of tracked connections on your EKS worker nodes]. +* In EKS environment, etcd storage limit is *8 GiB* as per https://etcd.io/docs/v3.5/dev-guide/limit/#storage-size-limit[upstream guidance]. Please monitor metric `etcd_db_total_size_in_bytes` to track etcd db size. You can refer to https://github.com/etcd-io/etcd/blob/main/contrib/mixin/mixin.libsonnet#L213-L240[alert rules] `etcdBackendQuotaLowSpace` and `etcdExcessiveDatabaseGrowth` to setup this monitoring. diff --git a/latest/bpg/scalability/scaling_theory.adoc b/latest/bpg/scalability/scaling_theory.adoc new file mode 100644 index 000000000..d166cbcb2 --- /dev/null +++ b/latest/bpg/scalability/scaling_theory.adoc @@ -0,0 +1,102 @@ += Kubernetes Scaling Theory +:authors: ["Shane Corbett"] +:date: 2023-09-22 + +== Nodes vs. Churn Rate + +Often when we discuss the scalability of Kubernetes, we do so in terms of how many nodes there are in a single cluster. Interestingly, this is seldom the most useful metric for understanding scalability. For example, a 5,000 node cluster with a large but fixed number of pods would not put a great deal of stress on the control plane after the initial setup. However, if we took a 1,000 node cluster and tried creating 10,000 short lived jobs in less than a minute, it would put a great deal of sustained pressure on the control plane. + +Simply using the number of nodes to understand scaling can be misleading. It's better to think in terms of the rate of change that occurs within a specific period of time (let's use a 5 minute interval for this discussion, as this is what Prometheus queries typically use by default). Let's explore why framing the problem in terms of the rate of change can give us a better idea of what to tune to achieve our desired scale. + +== Thinking in Queries Per Second + +Kubernetes has a number of protection mechanisms for each component - the Kubelet, Scheduler, Kube Controller Manager, and API server - to prevent overwhelming the next link in the Kubernetes chain. For example, the Kubelet has a flag to throttle calls to the API server at a certain rate. These protection mechanisms are generally, but not always, expressed in terms of queries allowed on a per second basis or QPS. + +Great care must be taken when changing these QPS settings. Removing one bottleneck, such as the queries per second on a Kubelet will have an impact on other down stream components. This can and will overwhelm the system above a certain rate, so understanding and monitoring each part of the service chain is key to successfully scaling workloads on Kubernetes. + +!!! note + The API server has a more complex system with introduction of API Priority and Fairness which we will discuss separately. + +!!! note + Caution, some metrics seem like the right fit but are in fact measuring something else. As an example, `kubelet_http_inflight_requests` relates to just the metrics server in Kubelet, not the number of requests from Kubelet to apiserver requests. This could cause us to misconfigure the QPS flag on the Kubelet. A query on audit logs for a particular Kubelet would be a more reliable way to check metrics. + +== Scaling Distributed Components + +Since EKS is a managed service, let's split the Kubernetes components into two categories: AWS managed components which include etcd, Kube Controller Manager, and the Scheduler (on the left part of diagram), and customer configurable components such as the Kubelet, Container Runtime, and the various operators that call AWS APIs such as the Networking and Storage drivers (on the right part of diagram). We leave the API server in the middle even though it is AWS managed, as the settings for API Priority and Fairness can be configured by customers. + +image::../images/k8s-components.png[Kubernetes components] + +== Upstream and Downstream Bottlenecks + +As we monitor each service, it's important to look at metrics in both directions to look for bottlenecks. Let's learn how to do this by using Kubelet as an example. Kubelet talks both to the API server and the container runtime; *how* and *what* do we need to monitor to detect whether either component is experiencing an issue? + +=== How many Pods per Node + +When we look at scaling numbers, such as how many pods can run on a node, we could take the 110 pods per node that upstream supports at face value. + +!!! note + https://kubernetes.io/docs/setup/best-practices/cluster-large/ + +However, your workload is likely more complex than what was tested in a scalability test in Upstream. To ensure we can service the number of pods we want to run in production, let's make sure that the Kubelet is "`keeping up`" with the Containerd runtime. + +image::../images/keeping-up.png[Keeping up] + +To oversimplify, the Kubelet is getting the status of the pods from the container runtime (in our case Containerd). What if we had too many pods changing status too quickly? If the rate of change is too high, requests [to the container runtime] can timeout. + +!!! note + Kubernetes is constantly evolving, this subsystem is currently undergoing changes. https://github.com/kubernetes/enhancements/issues/3386 + +image:../images/flow.png[Flow] +image:../images/PLEG-duration.png[PLEG duration] + +In the graph above, we see a flat line indicating we have just hit the timeout value for the pod lifecycle event generation duration metric. If you would like to see this in your own cluster you could use the following PromQL syntax. + +---- +increase(kubelet_pleg_relist_duration_seconds_bucket{instance="$instance"}[$__rate_interval]) +---- + +If we witness this timeout behavior, we know we pushed the node over the limit it was capable of. We need to fix the cause of the timeout before proceeding further. This could be achieved by reducing the number of pods per node, or looking for errors that might be causing a high volume of retries (thus effecting the churn rate). The important take-away is that metrics are the best way to understand if a node is able to handle the churn rate of the pods assigned vs. using a fixed number. + +== Scale by Metrics + +While the concept of using metrics to optimize systems is an old one, it's often overlooked as people begin their Kubernetes journey. Instead of focusing on specific numbers (i.e. 110 pods per node), we focus our efforts on finding the metrics that help us find bottlenecks in our system. Understanding the right thresholds for these metrics can give us a high degree of confidence our system is optimally configured. + +=== The Impact of Changes + +A common pattern that could get us into trouble is focusing on the first metric or log error that looks suspect. When we saw that the Kubelet was timing out earlier, we could try random things, such as increasing the per second rate that the Kubelet is allowed to send, etc. However, it is wise to look at the whole picture of everything downstream of the error we find first. _Make each change with purpose and backed by data_. + +Downstream of the Kubelet would be the Containerd runtime (pod errors), DaemonSets such as the storage driver (CSI) and the network driver (CNI) that talk to the EC2 API, etc. + +image::../images/flow-addons.png[Flow add-ons] + +Let's continue our earlier example of the Kubelet not keeping up with the runtime. There are a number of points where we could bin pack a node so densely that it triggers errors. + +image::../images/bottlenecks.png[Bottlenecks] + +When designing the right node size for our workloads these are easy-to-overlook signals that might be putting unnecessary pressure on the system thus limiting both our scale and performance. + +=== The Cost of Unnecessary Errors + +Kubernetes controllers excel at retrying when error conditions arise, however this comes at a cost. These retries can increase the pressure on components such as the Kube Controller Manager. It is an important tenant of scale testing to monitor for such errors. + +When fewer errors are occurring, it is easier spot issues in the system. By periodically ensuring that our clusters are error free before major operations (such as upgrades) we can simplify troubleshooting logs when unforeseen events happen. + +==== Expanding Our View + +In large scale clusters with 1,000's of nodes we don't want to look for bottlenecks individually. In PromQL we can find the highest values in a data set using a function called topk; K being a variable we place the number of items we want. Here we use three nodes to get an idea whether all of the the Kubelets in the cluster are saturated. We have been looking at latency up to this point, now let's see if the Kubelet is discarding events. + +---- +topk(3, increase(kubelet_pleg_discard_events{}[$__rate_interval])) +---- + +Breaking this statement down. + +* We use the Grafana variable `$__rate_interval` to ensure it gets the four samples it needs. This bypasses a complex topic in monitoring with a simple variable. +* `topk` give us just the top results and the number 3 limits those results to three. This is a useful function for cluster wide metrics. +* `{}` tell us there are no filters, normally you would put the job name of whatever the scraping rule, however since these names vary we will leave it blank. + +==== Splitting the Problem in Half + +To address a bottleneck in the system, we will take the approach of finding a metric that shows us there is a problem upstream or downstream as this allows us to split the problem in half. It will also be a core tenet of how we display our metrics data. + +A good place to start with this process is the API server, as it allow us to see if there's a problem with a client application or the Control Plane. diff --git a/latest/bpg/scalability/workloads.adoc b/latest/bpg/scalability/workloads.adoc new file mode 100644 index 000000000..e577f8db4 --- /dev/null +++ b/latest/bpg/scalability/workloads.adoc @@ -0,0 +1,99 @@ += Workloads + +Workloads have an impact on how large your cluster can scale. Workloads that use the Kubernetes APIs heavily will limit the total amount of workloads you can have in a single cluster, but there are some defaults you can change to help reduce the load. + +Workloads in a Kubernetes cluster have access to features that integrate with the Kubernetes API (e.g. Secrets and ServiceAccounts), but these features are not always required and should be disabled if they're not being used. Limiting workload access and dependence on the Kubernetes control plane will increase the number of workloads you can run in the cluster and improve the security of your clusters by removing unnecessary access to workloads and implementing least privilege practices. Please read the https://aws.github.io/aws-eks-best-practices/security/docs/[security best practices] for more information. + +== Use IPv6 for pod networking + +You cannot transition a VPC from IPv4 to IPv6 so enabling IPv6 before provisioning a cluster is important. If you enable IPv6 in a VPC it does not mean you have to use it and if your pods and services use IPv6 you can still route traffic to and from IPv4 addresses. Please see the https://aws.github.io/aws-eks-best-practices/networking/index/[EKS networking best practices] for more information. + +Using https://docs.aws.amazon.com/eks/latest/userguide/cni-ipv6.html[IPv6 in your cluster] avoids some of the most common cluster and workload scaling limits. IPv6 avoids IP address exhaustion where pods and nodes cannot be created because no IP address is available. It also has per node performance improvements because pods receive IP addresses faster by reducing the number of ENI attachments per node. You can achieve similar node performance by using https://aws.github.io/aws-eks-best-practices/networking/prefix-mode/[IPv4 prefix mode in the VPC CNI], but you still need to make sure you have enough IP addresses available in the VPC. + +== Limit number of services per namespace + +The maximum number of https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md[services in a namespaces is 5,000 and the maximum number of services in a cluster is 10,000]. To help organize workloads and services, increase performance, and to avoid cascading impact for namespace scoped resources we recommend limiting the number of services per namespace to 500. + +The number of IP tables rules that are created per node with kube-proxy grows with the total number of services in the cluster. Generating thousands of IP tables rules and routing packets through those rules have a performance impact on the nodes and add network latency. + +Create Kubernetes namespaces that encompass a single application environment so long as the number of services per namespace is under 500. This will keep service discovery small enough to avoid service discovery limits and can also help you avoid service naming collisions. Applications environments (e.g. dev, test, prod) should use separate EKS clusters instead of namespaces. + +== Understand Elastic Load Balancer Quotas + +When creating your services consider what type of load balancing you will use (e.g. Network Load Balancer (NLB) or Application Load Balancer (ALB)). Each load balancer type provides different functionality and have https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-limits.html[different quotas]. Some of the default quotas can be adjusted, but there are some quota maximums which cannot be changed. To view your account quotas and usage view the http://console.aws.amazon.com/servicequotas[Service Quotas dashboard] in the AWS console. + +For example, the default ALB targets is 1000. If you have a service with more than 1000 endpoints you will need to increase the quota or split the service across multiple ALBs or use Kubernetes Ingress. The default NLB targets is 3000, but is limited to 500 targets per AZ. If your cluster runs more than 500 pods for an NLB service you will need to use multiple AZs or request a quota limit increase. + +An alternative to using a load balancer coupled to a service is to use an https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/[ingress controller]. The AWS Load Balancer controller can create ALBs for ingress resources, but you may consider running a dedicated controller in your cluster. An in-cluster ingress controller allows you to expose multiple Kubernetes services from a single load balancer by running a reverse proxy inside your cluster. Controllers have different features such as support for the https://gateway-api.sigs.k8s.io/[Gateway API] which may have benefits depending on how many and how large your workloads are. + +== Use Route 53, Global Accelerator, or CloudFront + +To make a service using multiple load balancers available as a single endpoint you need to use https://aws.amazon.com/cloudfront/[Amazon CloudFront], https://aws.amazon.com/global-accelerator/[AWS Global Accelerator], or https://aws.amazon.com/route53/[Amazon Route 53] to expose all of the load balancers as a single, customer facing endpoint. Each options has different benefits and can be used separately or together depending on your needs. + +Route 53 can expose multiple load balancers under a common name and can send traffic to each of them based on the weight assigned. You can read more about https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-weighted.html#rrsets-values-weighted-weight[DNS weights in the documentation] and you can read how to implement them with the https://github.com/kubernetes-sigs/external-dns[Kubernetes external DNS controller] in the https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/integrations/external_dns/#usage[AWS Load Balancer Controller documentation]. + +Global Accelerator can route workloads to the nearest region based on request IP address. This may be useful for workloads that are deployed to multiple regions, but it does not improve routing to a single cluster in a single region. Using Route 53 in combination with the Global Accelerator has additional benefits such as health checking and automatic failover if an AZ is not available. You can see an example of using Global Accelerator with Route 53 in https://aws.amazon.com/blogs/containers/operating-a-multi-regional-stateless-application-using-amazon-eks/[this blog post]. + +CloudFront can be use with Route 53 and Global Accelerator or by itself to route traffic to multiple destinations. CloudFront caches assets being served from the origin sources which may reduce bandwidth requirements depending on what you are serving. + +== Use EndpointSlices instead of Endpoints + +When discovering pods that match a service label you should use https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/[EndpointSlices] instead of Endpoints. Endpoints were a simple way to expose services at small scales but large services that automatically scale or have updates causes a lot of traffic on the Kubernetes control plane. EndpointSlices have automatic grouping which enable things like topology aware hints. + +Not all controllers use EndpointSlices by default. You should verify your controller settings and enable it if needed. For the https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/configurations/#controller-command-line-flags[AWS Load Balancer Controller] you should enable the `--enable-endpoint-slices` optional flag to use EndpointSlices. + +== Use immutable and external secrets if possible + +The kubelet keeps a cache of the current keys and values for the Secrets that are used in volumes for pods on that node. The kubelet sets a watch on the Secrets to detect changes. As the cluster scales, the growing number of watches can negatively impact the API server performance. + +There are two strategies to reduce the number of watches on Secrets: + +* For applications that don't need access to Kubernetes resources, you can disable auto-mounting service account secrets by setting automountServiceAccountToken: false +* If your application's secrets are static and will not be modified in the future, mark the https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable[secret as immutable]. The kubelet does not maintain an API watch for immutable secrets. + +To disable automatically mounting a service account to pods you can use the following setting in your workload. You can override these settings if specific workloads need a service account. + +---- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: app +automountServiceAccountToken: true +---- + +Monitor the number of secrets in the cluster before it exceeds the limit of 10,000. You can see a total count of secrets in a cluster with the following command. You should monitor this limit through your cluster monitoring tooling. + +---- +kubectl get secrets -A | wc -l +---- + +You should set up monitoring to alert a cluster admin before this limit is reached. Consider using external secrets management options such as https://aws.amazon.com/kms/[AWS Key Management Service (AWS KMS)] or https://www.vaultproject.io/[Hashicorp Vault] with the https://secrets-store-csi-driver.sigs.k8s.io/[Secrets Store CSI driver]. + +== Limit Deployment history + +Pods can be slow when creating, updating, or deleting because old objects are still tracked in the cluster. You can reduce the `revisionHistoryLimit` of https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy[deployments] to cleanup older ReplicaSets which will lower to total amount of objects tracked by the Kubernetes Controller Manager. The default history limit for Deployments in 10. + +If your cluster creates a lot of job objects through CronJobs or other mechanisms you should use the https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/[`ttlSecondsAfterFinished` setting] to automatically clean up old pods in the cluster. This will remove successfully executed jobs from the job history after a specified amount of time. + +== Disable enableServiceLinks by default + +When a Pod runs on a Node, the kubelet adds a set of environment variables for each active Service. Linux processes have a maximum size for their environment which can be reached if you have too many services in your namespace. The number of services per namespace should not exceed 5,000. After this, the number of service environment variables outgrows shell limits, causing Pods to crash on startup. + +There are other reasons pods should not use service environment variables for service discovery. Environment variable name clashes, leaking service names, and total environment size are a few. You should use CoreDNS for discovering service endpoints. + +== Limit dynamic admission webhooks per resource + +https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/[Dynamic Admission Webhooks] include admission webhooks and mutating webhooks. They are API endpoints not part of the Kubernetes Control Plane that are called in sequence when a resource is sent to the Kubernetes API. Each webhook has a default timeout of 10 seconds and can increase the amount of time an API request takes if you have multiple webhooks or any of them timeout. + +Make sure your webhooks are highly available--especially during an AZ incident--and the https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy[failurePolicy] is set properly to reject the resource or ignore the failure. Do not call webhooks when not needed by allowing --dry-run kubectl commands to bypass the webhook. + +---- +apiVersion: admission.k8s.io/v1 +kind: AdmissionReview +request: + dryRun: False +---- + +Mutating webhooks can modify resources in frequent succession. If you have 5 mutating webhooks and deploy 50 resources etcd will store all versions of each resource until compaction runs--every 5 minutes--to remove old versions of modified resources. In this scenario when etcd removes superseded resources there will be 200 resource version removed from etcd and depending on the size of the resources may use considerable space on the etcd host until defragmentation runs every 15 minutes. + +This defragmentation may cause pauses in etcd which could have other affects on the Kubernetes API and controllers. You should avoid frequent modification of large resources or modifying hundreds of resources in quick succession. diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index 248970c4f..f648f16e9 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -1,6 +1,6 @@ //!!NODE_ROOT
[."topic"] -[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] +[[protecting-the-infrastructure,protecting-the-infrastructure.title]] = Protecting the infrastructure (hosts) :info_doctype: section :info_title: Protecting the infrastructure (hosts) @@ -8,7 +8,7 @@ :info_titleabbrev: Protecting the infrastructure (hosts) :imagesdir: images/ -Inasmuch as it’s important to secure your container images, it’s equally +Inasmuch as it's important to secure your container images, it's equally important to safeguard the infrastructure that runs them. This section explores different ways to mitigate risks from attacks launched directly against the host. These guidelines should be used in conjunction with @@ -210,138 +210,138 @@ Fargate pods. == Alternatives -// [[iam-se-linux,iam-se-linux.title]] -// === Run SELinux - -// !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, -// Bottlerocket, and Amazon Linux 2023 - -// SELinux provides an additional layer of security to keep containers -// isolated from each other and from the host. SELinux allows -// administrators to enforce mandatory access controls (MAC) for every -// user, application, process, and file. Think of it as a backstop that -// restricts the operations that can be performed against to specific -// resources based on a set of labels. On EKS, SELinux can be used to -// prevent containers from accessing each other’s resources. - -// Container SELinux policies are defined in the -// https://github.com/containers/container-selinux[container-selinux] -// package. Docker CE requires this package (along with its dependencies) -// so that the processes and files created by Docker (or other container -// runtimes) run with limited system access. Containers leverage the -// `container_t` label which is an alias to `svirt_lxc_net_t`. These -// policies effectively prevent containers from accessing certain features -// of the host. - -// When you configure SELinux for Docker, Docker automatically labels -// workloads `container_t` as a type and gives each container a unique -// MCS level. This will isolate containers from one another. If you need -// looser restrictions, you can create your own profile in SElinux which -// grants a container permissions to specific areas of the file system. -// This is similar to PSPs in that you can create different profiles for -// different containers/pods. For example, you can have a profile for -// general workloads with a set of restrictive controls and another for -// things that require privileged access. - -// SELinux for Containers has a set of options that can be configured to -// modify the default restrictions. The following SELinux Booleans can be -// enabled or disabled based on your needs: - -// [width="100%",cols="30%,^40%,30%",options="header",] -// |=== -// |Boolean |Default |Description -// |`container_connect_any` |`off` |Allow containers to access -// privileged ports on the host. For example, if you have a container that -// needs to map ports to 443 or 80 on the host. - -// |`container_manage_cgroup` |`off` |Allow containers to manage cgroup -// configuration. For example, a container running systemd will need this -// to be enabled. - -// |`container_use_cephfs` |`off` |Allow containers to use a ceph file -// system. -// |=== - -// By default, containers are allowed to read/execute under `/usr` and -// read most content from `/etc`. The files under `/var/lib/docker` and -// `/var/lib/containers` have the label `container_var_lib_t`. To view -// a full list of default, labels see the -// https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] -// file. - -// [source,bash] -// ---- -// docker container run -it \ -// -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ -// centos:7 cat /host/repositories.json -// # cat: /host/repositories.json: Permission denied - -// docker container run -it \ -// -v /etc/passwd:/host/etc/passwd \ -// centos:7 cat /host/etc/passwd -// # cat: /host/etc/passwd: Permission denied -// ---- - -// Files labeled with `container_file_t` are the only files that are -// writable by containers. If you want a volume mount to be writeable, you -// will needed to specify `:z` or `:Z` at the end. - -// * `:z` will re-label the files so that the container can read/write -// * `:Z` will re-label the files so that *only* the container can -// read/write - -// [source,bash] -// ---- -// ls -Z /var/lib/misc -// # -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp - -// docker container run -it \ -// -v /var/lib/misc:/host/var/lib/misc:z \ -// centos:7 echo "Relabeled!" - -// ls -Z /var/lib/misc -// #-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp -// ---- - -// [source,bash] -// ---- -// docker container run -it \ -// -v /var/log:/host/var/log:Z \ -// fluentbit:latest -// ---- - -// In Kubernetes, relabeling is slightly different. Rather than having -// Docker automatically relabel the files, you can specify a custom MCS -// label to run the pod. Volumes that support relabeling will automatically -// be relabeled so that they are accessible. Pods with a matching MCS label -// will be able to access the volume. If you need strict isolation, set a -// different MCS label for each pod. - -// [source,yaml] -// ---- -// securityContext: -// seLinuxOptions: -// # Provide a unique MCS label per container -// # You can specify user, role, and type also -// # enforcement based on type and level (svert) -// level: s0:c144:c154 -// ---- - -// In this example `s0:c144:c154` corresponds to an MCS label assigned to -// a file that the container is allowed to access. - -// On EKS you could create policies that allow for privileged containers to -// run, like FluentD and create an SELinux policy to allow it to read from -// /var/log on the host without needing to relabel the host directory. Pods -// with the same label will be able to access the same host volumes. - -// We have implemented -// https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for -// Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These -// AMIs were developed to demonstrate sample implementations that meet -// requirements of highly regulated customers, such as STIG, CJIS, and C2S. - -// !!! caution SELinux will ignore containers where the type is unconfined. +[[iam-se-linux,iam-se-linux.title]] +=== Run SELinux + +!!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, +Bottlerocket, and Amazon Linux 2023 + +SELinux provides an additional layer of security to keep containers +isolated from each other and from the host. SELinux allows +administrators to enforce mandatory access controls (MAC) for every +user, application, process, and file. Think of it as a backstop that +restricts the operations that can be performed against to specific +resources based on a set of labels. On EKS, SELinux can be used to +prevent containers from accessing each other's resources. + +Container SELinux policies are defined in the +https://github.com/containers/container-selinux[container-selinux] +package. Docker CE requires this package (along with its dependencies) +so that the processes and files created by Docker (or other container +runtimes) run with limited system access. Containers leverage the +`container_t` label which is an alias to `svirt_lxc_net_t`. These +policies effectively prevent containers from accessing certain features +of the host. + +When you configure SELinux for Docker, Docker automatically labels +workloads `container_t` as a type and gives each container a unique +MCS level. This will isolate containers from one another. If you need +looser restrictions, you can create your own profile in SElinux which +grants a container permissions to specific areas of the file system. +This is similar to PSPs in that you can create different profiles for +different containers/pods. For example, you can have a profile for +general workloads with a set of restrictive controls and another for +things that require privileged access. + +SELinux for Containers has a set of options that can be configured to +modify the default restrictions. The following SELinux Booleans can be +enabled or disabled based on your needs: + +[width="100%",cols="30%,^40%,30%",options="header",] +|=== +|Boolean |Default |Description +|`container_connect_any` |`off` |Allow containers to access +privileged ports on the host. For example, if you have a container that +needs to map ports to 443 or 80 on the host. + +|`container_manage_cgroup` |`off` |Allow containers to manage cgroup +configuration. For example, a container running systemd will need this +to be enabled. + +|`container_use_cephfs` |`off` |Allow containers to use a ceph file +system. +|=== + +By default, containers are allowed to read/execute under `/usr` and +read most content from `/etc`. The files under `/var/lib/docker` and +`/var/lib/containers` have the label `container_var_lib_t`. To view +a full list of default, labels see the +https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] +file. + +[source,bash] +---- +docker container run -it \ + -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ + centos:7 cat /host/repositories.json +# cat: /host/repositories.json: Permission denied + +docker container run -it \ + -v /etc/passwd:/host/etc/passwd \ + centos:7 cat /host/etc/passwd +# cat: /host/etc/passwd: Permission denied +---- + +Files labeled with `container_file_t` are the only files that are +writable by containers. If you want a volume mount to be writeable, you +will needed to specify `:z` or `:Z` at the end. + +* `:z` will re-label the files so that the container can read/write +* `:Z` will re-label the files so that *only* the container can +read/write + +[source,bash] +---- +ls -Z /var/lib/misc +# -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp + +docker container run -it \ + -v /var/lib/misc:/host/var/lib/misc:z \ + centos:7 echo "Relabeled!" + +ls -Z /var/lib/misc +#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp +---- + +[source,bash] +---- +docker container run -it \ + -v /var/log:/host/var/log:Z \ + fluentbit:latest +---- + +In Kubernetes, relabeling is slightly different. Rather than having +Docker automatically relabel the files, you can specify a custom MCS +label to run the pod. Volumes that support relabeling will automatically +be relabeled so that they are accessible. Pods with a matching MCS label +will be able to access the volume. If you need strict isolation, set a +different MCS label for each pod. + +[source,yaml] +---- +securityContext: + seLinuxOptions: + # Provide a unique MCS label per container + # You can specify user, role, and type also + # enforcement based on type and level (svert) + level: s0:c144:c154 +---- + +In this example `s0:c144:c154` corresponds to an MCS label assigned to +a file that the container is allowed to access. + +On EKS you could create policies that allow for privileged containers to +run, like FluentD and create an SELinux policy to allow it to read from +/var/log on the host without needing to relabel the host directory. Pods +with the same label will be able to access the same host volumes. + +We have implemented +https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for +Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These +AMIs were developed to demonstrate sample implementations that meet +requirements of highly regulated customers, such as STIG, CJIS, and C2S. + +!!! caution SELinux will ignore containers where the type is unconfined. == Tools and resources diff --git a/latest/bpg/security/index.adoc b/latest/bpg/security/index.adoc index dfd8f6db5..26f7e6c30 100644 --- a/latest/bpg/security/index.adoc +++ b/latest/bpg/security/index.adoc @@ -155,7 +155,7 @@ include::data.adoc[leveloffset=+1] include::runtime.adoc[leveloffset=+1] -// include::hosts.adoc[leveloffset=+1] +include::hosts.adoc[leveloffset=+1] include::compliance.adoc[leveloffset=+1] From 6a93a5d76e7e5fa4b56ccad40673ba70377a8537 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 28 Aug 2024 03:49:59 +0000 Subject: [PATCH 29/56] fixup --- latest/bpg/book.adoc | 3 + latest/bpg/reliability/application.adoc | 2 - latest/bpg/reliability/dataplane.adoc | 2 - latest/bpg/reliability/index.adoc | 5 - latest/bpg/scalability/cluster-services.adoc | 2 + latest/bpg/scalability/control-plane.adoc | 7 +- latest/bpg/scalability/data-plane.adoc | 3 +- latest/bpg/scalability/index.adoc | 8 +- latest/bpg/scalability/index.html | 3073 ------------------ latest/bpg/scalability/quotas.adoc | 2 +- latest/bpg/scalability/workloads.adoc | 1 + latest/bpg/security/hosts.adoc | 4 +- latest/bpg/security/hosts.adoc.backup | 366 --- latest/bpg/security/iam.adoc | 8 - 14 files changed, 21 insertions(+), 3465 deletions(-) delete mode 100644 latest/bpg/scalability/index.html delete mode 100644 latest/bpg/security/hosts.adoc.backup diff --git a/latest/bpg/book.adoc b/latest/bpg/book.adoc index 386965246..2e77d6cc8 100644 --- a/latest/bpg/book.adoc +++ b/latest/bpg/book.adoc @@ -42,4 +42,7 @@ include::security/index.adoc[leveloffset=+1] include::cost/cfm_framework.adoc[leveloffset=+1] +include::scalability/index.adoc[leveloffset=+1] + + diff --git a/latest/bpg/reliability/application.adoc b/latest/bpg/reliability/application.adoc index 05e2607f7..c90c5860b 100644 --- a/latest/bpg/reliability/application.adoc +++ b/latest/bpg/reliability/application.adoc @@ -612,11 +612,9 @@ different nodes and avoid PDB related delays during node upgrades. === Practice chaos engineering -____ Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the system’s capability to withstand turbulent conditions in production. -____ In his blog, Dominik Tornow explains that https://medium.com/@dominik.tornow/the-mechanics-of-kubernetes-ac8112eaa302[Kubernetes diff --git a/latest/bpg/reliability/dataplane.adoc b/latest/bpg/reliability/dataplane.adoc index a9d56093b..87a6dde1b 100644 --- a/latest/bpg/reliability/dataplane.adoc +++ b/latest/bpg/reliability/dataplane.adoc @@ -396,11 +396,9 @@ may be consumed by resources in that project. You can limit the total sum of storage and/or compute (CPU and memory) resources that can be requested in a given namespace. -____ If resource quota is enabled for a namespace for compute resources like CPU and memory, users must specify requests or limits for each container in that namespace. -____ Consider configuring quotas for each namespace. Consider using `+LimitRanges+` to automatically apply preconfigured limits to diff --git a/latest/bpg/reliability/index.adoc b/latest/bpg/reliability/index.adoc index 6ff54bbb0..d0d029e88 100644 --- a/latest/bpg/reliability/index.adoc +++ b/latest/bpg/reliability/index.adoc @@ -16,9 +16,6 @@ :imagesdir: images/ - -:imagesdir: images/ - This section provides guidance about making workloads running on EKS resilient and highly-available @@ -80,13 +77,11 @@ Availability Zones; you control this through the subnets you provide when creating managed nodes. EKS also automatically tags managed nodes so they can be used with Cluster Autoscaler. -____ Amazon EKS follows the shared responsibility model for CVEs and security patches on managed node groups. Because managed nodes run the Amazon EKS-optimized AMIs, Amazon EKS is responsible for building patched versions of these AMIs when bug fixes. However, you are responsible for deploying these patched AMI versions to your managed node groups. -____ EKS also https://docs.aws.amazon.com/eks/latest/userguide/update-managed-node-group.html[manages diff --git a/latest/bpg/scalability/cluster-services.adoc b/latest/bpg/scalability/cluster-services.adoc index d6ed1a2ed..25b11b2df 100644 --- a/latest/bpg/scalability/cluster-services.adoc +++ b/latest/bpg/scalability/cluster-services.adoc @@ -1,9 +1,11 @@ +[#cluster-services] = Cluster Services Cluster services run inside an EKS cluster, but they are not user workloads. If you have a Linux server you often need to run services like NTP, syslog, and a container runtime to support your workloads. Cluster services are similar, supporting services that help you automate and operate your cluster. In Kubernetes these are usually run in the kube-system namespace and some are run as https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[DaemonSets]. Cluster services are expected to have a high up-time and are often critical during outages and for troubleshooting. If a core cluster service is not available you may lose access to data that can help recover or prevent an outage (e.g. high disk utilization). They should run on dedicated compute instances such as a separate node group or AWS Fargate. This will ensure that the cluster services are not impacted on shared instances by workloads that may be scaling up or using more resources. +[#scale-coredns] == Scale CoreDNS Scaling CoreDNS has two primary mechanisms. Reducing the number of calls to the CoreDNS service and increasing the number of replicas. diff --git a/latest/bpg/scalability/control-plane.adoc b/latest/bpg/scalability/control-plane.adoc index 1256b93bb..01405d5fd 100644 --- a/latest/bpg/scalability/control-plane.adoc +++ b/latest/bpg/scalability/control-plane.adoc @@ -1,3 +1,4 @@ +[#control-plane] = Kubernetes Control Plane The Kubernetes control plane consists of the Kubernetes API Server, Kubernetes Controller Manager, Scheduler and other components that are required for Kubernetes to function. Scalability limits of these components are different depending on what you're running in the cluster, but the areas with the biggest impact to scaling include the Kubernetes version, utilization, and individual Node scaling. @@ -98,7 +99,11 @@ autoscalingGroups: image::../images/APF.jpg[] -=== Overview++++++ +=== Overview + + +// TODO: youtube video +// ++++++ To protect itself from being overloaded during periods of increased requests, the API Server limits the number of inflight requests it can have outstanding at a given time. Once this limit is exceeded, the API Server will start rejecting requests and return a 429 HTTP response code for "Too Many Requests" back to clients. The server dropping requests and having clients try again later is preferable to having no server-side limits on the number of requests and overloading the control plane, which could result in degraded performance or unavailability. diff --git a/latest/bpg/scalability/data-plane.adoc b/latest/bpg/scalability/data-plane.adoc index b98ce19b7..f3a0bcfc8 100644 --- a/latest/bpg/scalability/data-plane.adoc +++ b/latest/bpg/scalability/data-plane.adoc @@ -1,6 +1,7 @@ +[#data-plane] = Kubernetes Data Plane -The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped xref:./cluster-services.adoc[cluster services] in a separate page and load balancer scaling can be found in the xref:./workloads.adoc[workloads section]. This section will focus on scaling compute resources. +// The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped xref:cluster-services[cluster services] in a separate page and load balancer scaling can be found in the xref:workloads[workloads section]. This section will focus on scaling compute resources. Selecting EC2 instance types is possibly one of the hardest decisions customers face because in clusters with multiple workloads. There is no one-size-fits all solution. Here are some tips to help you avoid common pitfalls with scaling compute. diff --git a/latest/bpg/scalability/index.adoc b/latest/bpg/scalability/index.adoc index 18ea20a97..8d8334482 100644 --- a/latest/bpg/scalability/index.adoc +++ b/latest/bpg/scalability/index.adoc @@ -14,10 +14,10 @@ Scalability is different from performance and https://aws.github.io/aws-eks-best Scaling in Kubernetes is multi-dimensional and there are no specific settings or recommendations that work in every situation. The main areas areas where we can provide guidance for scaling include: -* link:control-plane[Kubernetes Control Plane] -* link:data-plane[Kubernetes Data Plane] -* link:cluster-services[Cluster Services] -* link:workloads[Workloads] +// * xref:control-plane[Kubernetes Control Plane] +// * xref:data-plane[Kubernetes Data Plane] +// * xref:cluster-services[Cluster Services] +// * xref:workloads[Workloads] *Kubernetes Control Plane* in an EKS cluster includes all of the services AWS runs and scales for you automatically (e.g. Kubernetes API server). Scaling the Control Plane is AWS's responsibility, but using the Control Plane responsibly is your responsibility. diff --git a/latest/bpg/scalability/index.html b/latest/bpg/scalability/index.html deleted file mode 100644 index ba88ef9f4..000000000 --- a/latest/bpg/scalability/index.html +++ /dev/null @@ -1,3073 +0,0 @@ - - - - - - - -EKS Scalability best practices - - - - - -
-
-
-
-

This guide provides advice for scaling EKS clusters. The goal of scaling an EKS cluster is to maximize the amount of work a single cluster can perform. Using a single, large EKS cluster can reduce operational load compared to using multiple clusters, but it has trade-offs for things like multi-region deployments, tenant isolation, and cluster upgrades. In this document we will focus on how to achieve maximum scalability with a single cluster.

-
-
-
-
-

How to use this guide

-
-
-

This guide is meant for developers and administrators responsible for creating and managing EKS clusters in AWS. It focuses on some generic Kubernetes scaling practices, but it does not have specifics for self-managed Kubernetes clusters or clusters that run outside of an AWS region with EKS Anywhere.

-
-
-

Each topic has a brief overview, followed by recommendations and best practices for operating EKS clusters at scale. Topics do not need to be read in a particular order and recommendations should not be applied without testing and verifying they work in your clusters.

-
-
-
-
-

Understanding scaling dimensions

-
-
-

Scalability is different from performance and reliability, and all three should be considered when planning your cluster and workload needs. As clusters scale, they need to be monitored, but this guide will not cover monitoring best practices. EKS can scale to large sizes, but you will need to plan how you are going to scale a cluster beyond 300 nodes or 5000 pods. These are not absolute numbers, but they come from collaborating this guide with multiple users, engineers, and support professionals.

-
-
-

Scaling in Kubernetes is multi-dimensional and there are no specific settings or recommendations that work in every situation. The main areas areas where we can provide guidance for scaling include:

-
- -
-

Kubernetes Control Plane in an EKS cluster includes all of the services AWS runs and scales for you automatically (e.g. Kubernetes API server). Scaling the Control Plane is AWS’s responsibility, but using the Control Plane responsibly is your responsibility.

-
-
-

Kubernetes Data Plane scaling deals with AWS resources that are required for your cluster and workloads, but they are outside of the EKS Control Plane. Resources including EC2 instances, kubelet, and storage all need to be scaled as your cluster scales.

-
-
-

Cluster services are Kubernetes controllers and applications that run inside the cluster and provide functionality for your cluster and workloads. These can be EKS Add-ons and also other services or Helm charts you install for compliance and integrations. These services are often depended on by workloads and as your workloads scale your cluster services will need to scale with them.

-
-
-

Workloads are the reason you have a cluster and should scale horizontally with the cluster. There are integrations and settings that workloads have in Kubernetes that can help the cluster scale. There are also architectural considerations with Kubernetes abstractions such as namespaces and services.

-
-
-
-
-

Extra large scaling

-
-
-

If you are scaling a single cluster beyond 1000 nodes or 50,000 pods we would love to talk to you. We recommend reaching out to your support team or technical account manager to get in touch with specialists who can help you plan and scale beyond the information provided in this guide.

-
-
-
-
-

Kubernetes Control Plane

-
-
-

The Kubernetes control plane consists of the Kubernetes API Server, Kubernetes Controller Manager, Scheduler and other components that are required for Kubernetes to function. Scalability limits of these components are different depending on what you’re running in the cluster, but the areas with the biggest impact to scaling include the Kubernetes version, utilization, and individual Node scaling.

-
-
-

Use EKS 1.24 or above

-
-

EKS 1.24 introduced a number of changes and switches the container runtime to containerd instead of docker. Containerd helps clusters scale by increasing individual node performance by limiting container runtime features to closely align with Kubernetes’ needs. Containerd is available in every supported version of EKS and if you would like to switch to containerd in versions prior to 1.24 please use the --container-runtime bootstrap flag.

-
-
-
-

Limit workload and node bursting

-
-

!!! Attention - To avoid reaching API limits on the control plane you should limit scaling spikes that increase cluster size by double digit percentages at a time (e.g. 1000 nodes to 1100 nodes or 4000 to 4500 pods at once).

-
-
-

The EKS control plane will automatically scale as your cluster grows, but there are limits on how fast it will scale. When you first create an EKS cluster the Control Plane will not immediately be able to scale to hundreds of nodes or thousands of pods. To read more about how EKS has made scaling improvements see this blog post.

-
-
-

Scaling large applications requires infrastructure to adapt to become fully ready (e.g. warming load balancers). To control the speed of scaling make sure you are scaling based on the right metrics for your application. CPU and memory scaling may not accurately predict your application constraints and using custom metrics (e.g. requests per second) in Kubernetes Horizontal Pod Autoscaler (HPA) may be a better scaling option.

-
-
-

To use a custom metric see the examples in the Kubernetes documentation. If you have more advanced scaling needs or need to scale based on external sources (e.g. AWS SQS queue) then use KEDA for event based workload scaling.

-
-
-
-

Scale nodes and pods down safely

-
-

Replace long running instances

-
-

Replacing nodes regularly keeps your cluster healthy by avoiding configuration drift and issues that only happen after extended uptime (e.g. slow memory leaks). Automated replacement will give you good process and practices for node upgrades and security patching. If every node in your cluster is replaced regularly then there is less toil required to maintain separate processes for ongoing maintenance.

-
-
-

Use Karpenter’s time to live (TTL) settings to replace instances after they’ve been running for a specified amount of time. Self managed node groups can use the max-instance-lifetime setting to cycle nodes automatically. Managed node groups do not currently have this feature but you can track the request here on GitHub.

-
-
-
-

Remove underutilized nodes

-
-

You can remove nodes when they have no running workloads using the scale down threshold in the Kubernetes Cluster Autoscaler with the --scale-down-utilization-threshold or in Karpenter you can use the ttlSecondsAfterEmpty provisioner setting.

-
-
-
-

Use pod disruption budgets and safe node shutdown

-
-

Removing pods and nodes from a Kubernetes cluster requires controllers to make updates to multiple resources (e.g. EndpointSlices). Doing this frequently or too quickly can cause API server throttling and application outages as changes propogate to controllers. Pod Disruption Budgets are a best practice to slow down churn to protect workload availability as nodes are removed or rescheduled in a cluster.

-
-
-
-
-

Use Client-Side Cache when running Kubectl

-
-

Using the kubectl command inefficiently can add additional load to the Kubernetes API Server. You should avoid running scripts or automation that uses kubectl repeatedly (e.g. in a for loop) or running commands without a local cache.

-
-
-

kubectl has a client-side cache that caches discovery information from the cluster to reduce the amount of API calls required. The cache is enabled by default and is refreshed every 10 minutes.

-
-
-

If you run kubectl from a container or without a client-side cache you may run into API throttling issues. It is recommended to retain your cluster cache by mounting the --cache-dir to avoid making uncessesary API calls.

-
-
-
-

Disable kubectl Compression

-
-

Disabling kubectl compression in your kubeconfig file can reduce API and client CPU usage. By default the server will compress data sent to the client to optimize network bandwidth. This adds CPU load on the client and server for every request and disabling compression can reduce the overhead and latency if you have adequate bandwidth. To disable compression you can use the --disable-compression=true flag or set disable-compression: true in your kubeconfig file.

-
-
-
-
apiVersion: v1
-clusters:
-- cluster:
-    server: serverURL
-    disable-compression: true
-  name: cluster
-
-
-
-
-

Shard Cluster Autoscaler

-
-

The Kubernetes Cluster Autoscaler has been tested to scale up to 1000 nodes. On a large cluster with more than 1000 nodes, it is recommended to run multiple instances of the Cluster Autoscaler in shard mode. Each Cluster Autoscaler instance is configured to scale a set of node groups. The following example shows 2 cluster autoscaling configurations that are configured to each scale 4 node groups.

-
-
-

ClusterAutoscaler-1

-
-
-
-
autoscalingGroups:
-- name: eks-core-node-grp-20220823190924690000000011-80c1660e-030d-476d-cb0d-d04d585a8fcb
-  maxSize: 50
-  minSize: 2
-- name: eks-data_m1-20220824130553925600000011-5ec167fa-ca93-8ca4-53a5-003e1ed8d306
-  maxSize: 450
-  minSize: 2
-- name: eks-data_m2-20220824130733258600000015-aac167fb-8bf7-429d-d032-e195af4e25f5
-  maxSize: 450
-  minSize: 2
-- name: eks-data_m3-20220824130553914900000003-18c167fa-ca7f-23c9-0fea-f9edefbda002
-  maxSize: 450
-  minSize: 2
-
-
-
-

ClusterAutoscaler-2

-
-
-
-
autoscalingGroups:
-- name: eks-data_m4-2022082413055392550000000f-5ec167fa-ca86-6b83-ae9d-1e07ade3e7c4
-  maxSize: 450
-  minSize: 2
-- name: eks-data_m5-20220824130744542100000017-02c167fb-a1f7-3d9e-a583-43b4975c050c
-  maxSize: 450
-  minSize: 2
-- name: eks-data_m6-2022082413055392430000000d-9cc167fa-ca94-132a-04ad-e43166cef41f
-  maxSize: 450
-  minSize: 2
-- name: eks-data_m7-20220824130553921000000009-96c167fa-ca91-d767-0427-91c879ddf5af
-  maxSize: 450
-  minSize: 2
-
-
-
-
-

API Priority and Fairness

-
-
-APF -
-
-
-

Overview

-
-

To protect itself from being overloaded during periods of increased requests, the API Server limits the number of inflight requests it can have outstanding at a given time. Once this limit is exceeded, the API Server will start rejecting requests and return a 429 HTTP response code for "Too Many Requests" back to clients. The server dropping requests and having clients try again later is preferable to having no server-side limits on the number of requests and overloading the control plane, which could result in degraded performance or unavailability.

-
-
-

The mechanism used by Kubernetes to configure how these inflights requests are divided among different request types is called API Priority and Fairness. The API Server configures the total number of inflight requests it can accept by summing together the values specified by the --max-requests-inflight and --max-mutating-requests-inflight flags. EKS uses the default values of 400 and 200 requests for these flags, allowing a total of 600 requests to be dispatched at a given time. However, as it scales the control-plane to larger sizes in response to increased utilization and workload churn, it correspondingly increases the inflight request quota all the way till 2000 (subject to change). APF specifies how these inflight request quota is further sub-divided among different request types. Note that EKS control planes are highly available with at least 2 API Servers registered to each cluster. This means the total number of inflight requests your cluster can handle is twice (or higher if horizontally scaled out further) the inflight quota set per kube-apiserver. This amounts to several thousands of requests/second on the largest EKS clusters.

-
-
-

Two kinds of Kubernetes objects, called PriorityLevelConfigurations and FlowSchemas, configure how the total number of requests is divided between different request types. These objects are maintained by the API Server automatically and EKS uses the default configuration of these objects for the given Kubernetes minor version. PriorityLevelConfigurations represent a fraction of the total number of allowed requests. For example, the workload-high PriorityLevelConfiguration is allocated 98 out of the total of 600 requests. The sum of requests allocated to all PriorityLevelConfigurations will equal 600 (or slightly above 600 because the API Server will round up if a given level is granted a fraction of a request). To check the PriorityLevelConfigurations in your cluster and the number of requests allocated to each, you can run the following command. These are the defaults on EKS 1.24:

-
-
-
-
$ kubectl get --raw /metrics | grep apiserver_flowcontrol_request_concurrency_limit
-apiserver_flowcontrol_request_concurrency_limit{priority_level="catch-all"} 13
-apiserver_flowcontrol_request_concurrency_limit{priority_level="global-default"} 49
-apiserver_flowcontrol_request_concurrency_limit{priority_level="leader-election"} 25
-apiserver_flowcontrol_request_concurrency_limit{priority_level="node-high"} 98
-apiserver_flowcontrol_request_concurrency_limit{priority_level="system"} 74
-apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-high"} 98
-apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245
-
-
-
-

The second type of object are FlowSchemas. API Server requests with a given set of properties are classified under the same FlowSchema. These properties include either the authenticated user or attributes of the request, such as the API group, namespace, or resource. A FlowSchema also specifies which PriorityLevelConfiguration this type of request should map to. The two objects together say, "I want this type of request to count towards this share of inflight requests." When a request hits the API Server, it will check each of its FlowSchemas until it finds one that matches all the required properties. If multiple FlowSchemas match a request, the API Server will choose the FlowSchema with the smallest matching precedence which is specified as a property in the object.

-
-
-

The mapping of FlowSchemas to PriorityLevelConfigurations can be viewed using this command:

-
-
-
-
$ kubectl get flowschemas
-NAME                           PRIORITYLEVEL     MATCHINGPRECEDENCE   DISTINGUISHERMETHOD   AGE     MISSINGPL
-exempt                         exempt            1                    <none>                7h19m   False
-eks-exempt                     exempt            2                    <none>                7h19m   False
-probes                         exempt            2                    <none>                7h19m   False
-system-leader-election         leader-election   100                  ByUser                7h19m   False
-endpoint-controller            workload-high     150                  ByUser                7h19m   False
-workload-leader-election       leader-election   200                  ByUser                7h19m   False
-system-node-high               node-high         400                  ByUser                7h19m   False
-system-nodes                   system            500                  ByUser                7h19m   False
-kube-controller-manager        workload-high     800                  ByNamespace           7h19m   False
-kube-scheduler                 workload-high     800                  ByNamespace           7h19m   False
-kube-system-service-accounts   workload-high     900                  ByNamespace           7h19m   False
-eks-workload-high              workload-high     1000                 ByUser                7h14m   False
-service-accounts               workload-low      9000                 ByUser                7h19m   False
-global-default                 global-default    9900                 ByUser                7h19m   False
-catch-all                      catch-all         10000                ByUser                7h19m   False
-
-
-
-

PriorityLevelConfigurations can have a type of Queue, Reject, or Exempt. For types Queue and Reject, a limit is enforced on the maximum number of inflight requests for that priority level, however, the behavior differs when that limit is reached. For example, the workload-high PriorityLevelConfiguration uses type Queue and has 98 requests available for use by the controller-manager, endpoint-controller, scheduler,eks related controllers and from pods running in the kube-system namespace. Since type Queue is used, the API Server will attempt to keep requests in memory and hope that the number of inflight requests drops below 98 before these requests time out. If a given request times out in the queue or if too many requests are already queued, the API Server has no choice but to drop the request and return the client a 429. Note that queuing may prevent a request from receiving a 429, but it comes with the tradeoff of increased end-to-end latency on the request.

-
-
-

Now consider the catch-all FlowSchema that maps to the catch-all PriorityLevelConfiguration with type Reject. If clients reach the limit of 13 inflight requests, the API Server will not exercise queuing and will drop the requests instantly with a 429 response code. Finally, requests mapping to a PriorityLevelConfiguration with type Exempt will never receive a 429 and always be dispatched immediately. This is used for high-priority requests such as healthz requests or requests coming from the system:masters group.

-
-
-
-

Monitoring APF and Dropped Requests

-
-

To confirm if any requests are being dropped due to APF, the API Server metrics for apiserver_flowcontrol_rejected_requests_total can be monitored to check the impacted FlowSchemas and PriorityLevelConfigurations. For example, this metric shows that 100 requests from the service-accounts FlowSchema were dropped due to requests timing out in workload-low queues:

-
-
-
-
% kubectl get --raw /metrics | grep apiserver_flowcontrol_rejected_requests_total
-apiserver_flowcontrol_rejected_requests_total{flow_schema="service-accounts",priority_level="workload-low",reason="time-out"} 100
-
-
-
-

To check how close a given PriorityLevelConfiguration is to receiving 429s or experiencing increased latency due to queuing, you can compare the difference between the concurrency limit and the concurrency in use. In this example, we have a buffer of 100 requests.

-
-
-
-
% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_limit.*workload-low'
-apiserver_flowcontrol_request_concurrency_limit{priority_level="workload-low"} 245
-
-% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_request_concurrency_in_use.*workload-low'
-apiserver_flowcontrol_request_concurrency_in_use{flow_schema="service-accounts",priority_level="workload-low"} 145
-
-
-
-

To check if a given PriorityLevelConfiguration is experiencing queuing but not necessarily dropped requests, the metric for apiserver_flowcontrol_current_inqueue_requests can be referenced:

-
-
-
-
% kubectl get --raw /metrics | grep 'apiserver_flowcontrol_current_inqueue_requests.*workload-low'
-apiserver_flowcontrol_current_inqueue_requests{flow_schema="service-accounts",priority_level="workload-low"} 10
-
-
-
-

Other useful Prometheus metrics include:

-
-
-
    -
  • -

    apiserver_flowcontrol_dispatched_requests_total

    -
  • -
  • -

    apiserver_flowcontrol_request_execution_seconds

    -
  • -
  • -

    apiserver_flowcontrol_request_wait_duration_seconds

    -
  • -
-
-
-

See the upstream documentation for a complete list of APF metrics.

-
-
-
-

Preventing Dropped Requests

-
-
Prevent 429s by changing your workload
-
-

When APF is dropping requests due to a given PriorityLevelConfiguration exceeding its maximum number of allowed inflight requests, clients in the affected FlowSchemas can decrease the number of requests executing at a given time. This can be accomplished by reducing the total number of requests made over the period where 429s are occurring. Note that long-running requests such as expensive list calls are especially problematic because they count as an inflight request for the entire duration they are executing. Reducing the number of these expensive requests or optimizing the latency of these list calls (for example, by reducing the number of objects fetched per request or switching to using a watch request) can help reduce the total concurrency required by the given workload.

-
-
-
-
Prevent 429s by changing your APF settings
-
-

!!! Warning - Only change default APF settings if you know what you are doing. Misconfigured APF settings can result in dropped API Server requests and significant workload disruptions.

-
-
-

One other approach for preventing dropped requests is changing the default FlowSchemas or PriorityLevelConfigurations installed on EKS clusters. EKS installs the upstream default settings for FlowSchemas and PriorityLevelConfigurations for the given Kubernetes minor version. The API Server will automatically reconcile these objects back to their defaults if modified unless the following annotation on the objects is set to false:

-
-
-
-
  metadata:
-    annotations:
-      apf.kubernetes.io/autoupdate-spec: "false"
-
-
-
-

At a high-level, APF settings can be modified to either:

-
-
-
    -
  • -

    Allocate more inflight capacity to requests you care about.

    -
  • -
  • -

    Isolate non-essential or expensive requests that can starve capacity for other request types.

    -
  • -
-
-
-

This can be accomplished by either changing the default FlowSchemas and PriorityLevelConfigurations or by creating new objects of these types. Operators can increase the values for assuredConcurrencyShares for the relevant PriorityLevelConfigurations objects to increase the fraction of inflight requests they are allocated. Additionally, the number of requests that can be queued at a given time can also be increased if the application can handle the additional latency caused by requests being queued before they are dispatched.

-
-
-

Alternatively, new FlowSchema and PriorityLevelConfigurations objects can be created that are specific to the customer’s workload. Be aware that allocating more assuredConcurrencyShares to either existing PriorityLevelConfigurations or to new PriorityLevelConfigurations will cause the number of requests that can be handled by other buckets to be reduced as the overall limit will stay as 600 inflight per API Server.

-
-
-

When making changes to APF defaults, these metrics should be monitored on a non-production cluster to ensure changing the settings do not cause unintended 429s:

-
-
-
    -
  1. -

    The metric for apiserver_flowcontrol_rejected_requests_total should be monitored for all FlowSchemas to ensure that no buckets start to drop requests.

    -
  2. -
  3. -

    The values for apiserver_flowcontrol_request_concurrency_limit and apiserver_flowcontrol_request_concurrency_in_use should be compared to ensure that the concurrency in use is not at risk for breaching the limit for that priority level.

    -
  4. -
-
-
-

One common use-case for defining a new FlowSchema and PriorityLevelConfiguration is for isolation. Suppose we want to isolate long-running list event calls from pods to their own share of requests. This will prevent important requests from pods using the existing service-accounts FlowSchema from receiving 429s and being starved of request capacity. Recall that the total number of inflight requests is finite, however, this example shows APF settings can be modified to better divide request capacity for the given workload:

-
-
-

Example FlowSchema object to isolate list event requests:

-
-
-
-
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
-kind: FlowSchema
-metadata:
-  name: list-events-default-service-accounts
-spec:
-  distinguisherMethod:
-    type: ByUser
-  matchingPrecedence: 8000
-  priorityLevelConfiguration:
-    name: catch-all
-  rules:
-  - resourceRules:
-    - apiGroups:
-      - '*'
-      namespaces:
-      - default
-      resources:
-      - events
-      verbs:
-      - list
-    subjects:
-    - kind: ServiceAccount
-      serviceAccount:
-        name: default
-        namespace: default
-
-
-
-
    -
  • -

    This FlowSchema captures all list event calls made by service accounts in the default namespace.

    -
  • -
  • -

    The matching precedence 8000 is lower than the value of 9000 used by the existing service-accounts FlowSchema so these list event calls will match list-events-default-service-accounts rather than service-accounts.

    -
  • -
  • -

    We’re using the catch-all PriorityLevelConfiguration to isolate these requests. This bucket only allows 13 inflight requests to be used by these long-running list event calls. Pods will start to receive 429s as soon they try to issue more than 13 of these requests concurrently.

    -
  • -
-
-
-
-
-
-

Retrieving resources in the API server

-
-

Getting information from the API server is an expected behavior for clusters of any size. As you scale the number of resources in the cluster the frequency of requests and volume of data can quickly become a bottleneck for the control plane and will lead to API latency and slowness. Depending on the severity of the latency it cause unexpected downtime if you are not careful.

-
-
-

Being aware of what you are requesting and how often are the first steps to avoiding these types of problems. Here is guidance to limit the volume of queries based on the scaling best practices. Suggestions in this section are provided in order starting with the options that are known to scale the best.

-
-
-

Use Shared Informers

-
-

When building controllers and automation that integrate with the Kubernetes API you will often need to get information from Kubernetes resources. If you poll for these resources regularly it can cause a significant load on the API server.

-
-
-

Using an informer from the client-go library will give you benefits of watching for changes to the resources based on events instead of polling for changes. Informers further reduce the load by using shared cache for the events and changes so multiple controllers watching the same resources do not add additional load.

-
-
-

Controllers should avoid polling cluster wide resources without labels and field selectors especially in large clusters. Each un-filtered poll requires a lot of unnecessary data to be sent from etcd through the API server to be filtered by the client. By filtering based on labels and namespaces you can reduce the amount of work the API server needs to perform to fullfil the request and data sent to the client.

-
-
-
-

Optimize Kubernetes API usage

-
-

When calling the Kubernetes API with custom controllers or automation it’s important that you limit the calls to only the resources you need. Without limits you can cause unneeded load on the API server and etcd.

-
-
-

It is recommended that you use the watch argument whenever possible. With no arguments the default behavior is to list objects. To use watch instead of list you can append ?watch=true to the end of your API request. For example, to get all pods in the default namespace with a watch use:

-
-
-
-
/api/v1/namespaces/default/pods?watch=true
-
-
-
-

If you are listing objects you should limit the scope of what you are listing and the amount of data returned. You can limit the returned data by adding limit=500 argument to requests. The fieldSelector argument and /namespace/ path can be useful to make sure your lists are as narrowly scoped as needed. For example, to list only running pods in the default namespace use the following API path and arguments.

-
-
-
-
/api/v1/namespaces/default/pods?fieldSelector=status.phase=Running&limit=500
-
-
-
-

Or list all pods that are running with:

-
-
-
-
/api/v1/pods?fieldSelector=status.phase=Running&limit=500
-
-
-
-

Another option to limit watch calls or listed objects is to use resourceVersions which you can read about in the Kubernetes documentation. Without a resourceVersion argument you will receive the most recent version available which requires an etcd quorum read which is the most expensive and slowest read for the database. The resourceVersion depends on what resources you are trying to query and can be found in the metadata.resourseVersion field. This is also recommended in case of using watch calls and not just list calls

-
-
-

There is a special resourceVersion=0 available that will return results from the API server cache. This can reduce etcd load but it does not support pagination.

-
-
-
-
/api/v1/namespaces/default/pods?resourceVersion=0
-
-
-
-

It’s recommended to use watch with a resourceVersion set to be the most recent known value received from its preceding list or watch. This is handled automatically in client-go. But it’s suggested to double check it if you are using a k8s client in other languages.

-
-
-
-
/api/v1/namespaces/default/pods?watch=true&resourceVersion=362812295
-
-
-
-

If you call the API without any arguments it will be the most resource intensive for the API server and etcd. This call will get all pods in all namespaces without pagination or limiting the scope and require a quorum read from etcd.

-
-
-
-
/api/v1/pods
-
-
-
-
-
-
-
-

Kubernetes Data Plane

-
-
-

The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped cluster services in a separate page and load balancer scaling can be found in the workloads section. This section will focus on scaling compute resources.

-
-
-

Selecting EC2 instance types is possibly one of the hardest decisions customers face because in clusters with multiple workloads. There is no one-size-fits all solution. Here are some tips to help you avoid common pitfalls with scaling compute.

-
-
-

Automatic node autoscaling

-
-

We recommend you use node autoscaling that reduces toil and integrates deeply with Kubernetes. Managed node groups and Karpenter are recommended for large scale clusters.

-
-
-

Managed node groups will give you the flexibility of Amazon EC2 Auto Scaling groups with added benefits for managed upgrades and configuration. It can be scaled with the Kubernetes Cluster Autoscaler and is a common option for clusters that have a variety of compute needs.

-
-
-

Karpenter is an open source, workload-native node autoscaler created by AWS. It scales nodes in a cluster based on the workload requirements for resources (e.g. GPU) and taints and tolerations (e.g. zone spread) without managing node groups. Nodes are created directly from EC2 which avoids default node group quotas—​450 nodes per group—​and provides greater instance selection flexibility with less operational overhead. We recommend customers use Karpenter when possible.

-
-
-
-

Use many different EC2 instance types

-
-

Each AWS region has a limited number of available instances per instance type. If you create a cluster that uses only one instance type and scale the number of nodes beyond the capacity of the region you will receive an error that no instances are available. To avoid this issue you should not arbitrarily limit the type of instances that can be use in your cluster.

-
-
-

Karpenter will use a broad set of compatible instance types by default and will pick an instance at provisioning time based on pending workload requirements, availability, and cost. You can broaden the list of instance types used in the karpenter.k8s.aws/instance-category key of NodePools.

-
-
-

The Kubernetes Cluster Autoscaler requires node groups to be similarly sized so they can be consistently scaled. You should create multiple groups based on CPU and memory size and scale them independently. Use the ec2-instance-selector to identify instances that are similarly sized for your node groups.

-
-
-
-
ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16
-a1.2xlarge
-a1.4xlarge
-a1.metal
-c4.4xlarge
-c4.8xlarge
-c5.12xlarge
-c5.18xlarge
-c5.24xlarge
-c5.2xlarge
-c5.4xlarge
-c5.9xlarge
-c5.metal
-
-
-
-
-

Prefer larger nodes to reduce API server load

-
-

When deciding what instance types to use, fewer, large nodes will put less load on the Kubernetes Control Plane because there will be fewer kubelets and DaemonSets running. However, large nodes may not be utilized fully like smaller nodes. Node sizes should be evaluated based on your workload availability and scale requirements.

-
-
-

A cluster with three u-24tb1.metal instances (24 TB memory and 448 cores) has 3 kubelets, and would be limited to 110 pods per node by default. If your pods use 4 cores each then this might be expected (4 cores x 110 = 440 cores/node). With a 3 node cluster your ability to handle an instance incident would be low because 1 instance outage could impact 1/3 of the cluster. You should specify node requirements and pod spread in your workloads so the Kubernetes scheduler can place workloads properly.

-
-
-

Workloads should define the resources they need and the availability required via taints, tolerations, and PodTopologySpread. They should prefer the largest nodes that can be fully utilized and meet availability goals to reduce control plane load, lower operations, and reduce cost.

-
-
-

The Kubernetes Scheduler will automatically try to spread workloads across availability zones and hosts if resources are available. If no capacity is available the Kubernetes Cluster Autoscaler will attempt to add nodes in each Availability Zone evenly. Karpenter will attempt to add nodes as quickly and cheaply as possible unless the workload specifies other requirements.

-
-
-

To force workloads to spread with the scheduler and new nodes to be created across availability zones you should use topologySpreadConstraints:

-
-
-
-
spec:
-  topologySpreadConstraints:
-    - maxSkew: 3
-      topologyKey: "topology.kubernetes.io/zone"
-      whenUnsatisfiable: ScheduleAnyway
-      labelSelector:
-        matchLabels:
-          dev: my-deployment
-    - maxSkew: 2
-      topologyKey: "kubernetes.io/hostname"
-      whenUnsatisfiable: ScheduleAnyway
-      labelSelector:
-        matchLabels:
-          dev: my-deployment
-
-
-
-
-

Use similar node sizes for consistent workload performance

-
-

Workloads should define what size nodes they need to be run on to allow consistent performance and predictable scaling. A workload requesting 500m CPU will perform differently on an instance with 4 cores vs one with 16 cores. Avoid instance types that use burstable CPUs like T series instances.

-
-
-

To make sure your workloads get consistent performance a workload can use the supported Karpenter labels to target specific instances sizes.

-
-
-
-
kind: deployment
-...
-spec:
-  template:
-    spec:
-    containers:
-    nodeSelector:
-      karpenter.k8s.aws/instance-size: 8xlarge
-
-
-
-

Workloads being scheduled in a cluster with the Kubernetes Cluster Autoscaler should match a node selector to node groups based on label matching.

-
-
-
-
spec:
-  affinity:
-    nodeAffinity:
-      requiredDuringSchedulingIgnoredDuringExecution:
-        nodeSelectorTerms:
-        - matchExpressions:
-          - key: eks.amazonaws.com/nodegroup
-            operator: In
-            values:
-            - 8-core-node-group    # match your node group name
-
-
-
-
-

Use compute resources efficiently

-
-

Compute resources include EC2 instances and availability zones. Using compute resources effectively will increase your scalability, availability, performance, and reduce your total cost. Efficient resource usage is extremely difficult to predict in an autoscaling environment with multiple applications. Karpenter was created to provision instances on-demand based on the workload needs to maximize utilization and flexibility.

-
-
-

Karpenter allows workloads to declare the type of compute resources it needs without first creating node groups or configuring label taints for specific nodes. See the Karpenter best practices for more information. Consider enabling consolidation in your Karpenter provisioner to replace nodes that are under utilized.

-
-
-
-

Automate Amazon Machine Image (AMI) updates

-
-

Keeping worker node components up to date will make sure you have the latest security patches and compatible features with the Kubernetes API. Updating the kubelet is the most important component for Kubernetes functionality, but automating OS, kernel, and locally installed application patches will reduce maintenance as you scale.

-
-
-

It is recommended that you use the latest Amazon EKS optimized Amazon Linux 2 or Amazon EKS optimized Bottlerocket AMI for your node image. Karpenter will automatically use the latest available AMI to provision new nodes in the cluster. Managed node groups will update the AMI during a node group update but will not update the AMI ID at node provisioning time.

-
-
-

For Managed Node Groups you need to update the Auto Scaling Group (ASG) launch template with new AMI IDs when they are available for patch releases. AMI minor versions (e.g. 1.23.5 to 1.24.3) will be available in the EKS console and API as upgrades for the node group. Patch release versions (e.g. 1.23.5 to 1.23.6) will not be presented as upgrades for the node groups. If you want to keep your node group up to date with AMI patch releases you need to create new launch template version and let the node group replace instances with the new AMI release.

-
-
-

You can find the latest available AMI from this page or use the AWS CLI.

-
-
-
-
aws ssm get-parameter \
-  --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \
-  --query "Parameter.Value" \
-  --output text
-
-
-
-
-

Use multiple EBS volumes for containers

-
-

EBS volumes have input/output (I/O) quota based on the type of volume (e.g. gp3) and the size of the disk. If your applications share a single EBS root volume with the host this can exhaust the disk quota for the entire host and cause other applications to wait for available capacity. Applications write to disk if they write files to their overlay partition, mount a local volume from the host, and also when they log to standard out (STDOUT) depending on the logging agent used.

-
-
-

To avoid disk I/O exhaustion you should mount a second volume to the container state folder (e.g. /run/containerd), use separate EBS volumes for workload storage, and disable unnecessary local logging.

-
-
-

To mount a second volume to your EC2 instances using eksctl you can use a node group with this configuration:

-
-
-
-
managedNodeGroups:
-  - name: al2-workers
-    amiFamily: AmazonLinux2
-    desiredCapacity: 2
-    volumeSize: 80
-    additionalVolumes:
-      - volumeName: '/dev/sdz'
-        volumeSize: 100
-    preBootstrapCommands:
-    - |
-      "systemctl stop containerd"
-      "mkfs -t ext4 /dev/nvme1n1"
-      "rm -rf /var/lib/containerd/*"
-      "mount /dev/nvme1n1 /var/lib/containerd/"
-      "systemctl start containerd"
-
-
-
-

If you are using terraform to provision your node groups please see examples in EKS Blueprints for terraform. If you are using Karpenter to provision nodes you can use blockDeviceMappings with node user-data to add additional volumes.

-
-
-

To mount an EBS volume directly to your pod you should use the AWS EBS CSI driver and consume a volume with a storage class.

-
-
-
-
---
-apiVersion: storage.k8s.io/v1
-kind: StorageClass
-metadata:
-  name: ebs-sc
-provisioner: ebs.csi.aws.com
-volumeBindingMode: WaitForFirstConsumer
----
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
-  name: ebs-claim
-spec:
-  accessModes:
-    - ReadWriteOnce
-  storageClassName: ebs-sc
-  resources:
-    requests:
-      storage: 4Gi
----
-apiVersion: v1
-kind: Pod
-metadata:
-  name: app
-spec:
-  containers:
-  - name: app
-    image: public.ecr.aws/docker/library/nginx
-    volumeMounts:
-    - name: persistent-storage
-      mountPath: /data
-  volumes:
-  - name: persistent-storage
-    persistentVolumeClaim:
-      claimName: ebs-claim
-
-
-
-
-

Avoid instances with low EBS attach limits if workloads use EBS volumes

-
-

EBS is one of the easiest ways for workloads to have persistent storage, but it also comes with scalability limitations. Each instance type has a maximum number of EBS volumes that can be attached. Workloads need to declare what instance types they should run on and limit the number of replicas on a single instance with Kubernetes taints.

-
-
-
-

Disable unnecessary logging to disk

-
-

Avoid unnecessary local logging by not running your applications with debug logging in production and disabling logging that reads and writes to disk frequently. Journald is the local logging service that keeps a log buffer in memory and flushes to disk periodically. Journald is preferred over syslog which logs every line immediately to disk. Disabling syslog also lowers the total amount of storage you need and avoids needing complicated log rotation rules. To disable syslog you can add the following snippet to your cloud-init configuration:

-
-
-
-
runcmd:
-  - [ systemctl, disable, --now, syslog.service ]
-
-
-
-
-

Patch instances in place when OS update speed is a necessity

-
-

!!! Attention - Patching instances in place should only be done when required. Amazon recommends treating infrastructure as immutable and thoroughly testing updates that are promoted through lower environments the same way applications are. This section applies when that is not possible.

-
-
-

It takes seconds to install a package on an existing Linux host without disrupting containerized workloads. The package can be installed and validated without cordoning, draining, or replacing the instance.

-
-
-

To replace an instance you first need to create, validate, and distribute new AMIs. The instance needs to have a replacement created, and the old instance needs to be cordoned and drained. Then workloads need to be created on the new instance, verified, and repeated for all instances that need to be patched. It takes hours, days, or weeks to replace instances safely without disrupting workloads.

-
-
-

Amazon recommends using immutable infrastructure that is built, tested, and promoted from an automated, declarative system, but if you have a requirement to patch systems quickly then you will need to patch systems in place and replace them as new AMIs are made available. Because of the large time differential between patching and replacing systems we recommend using AWS Systems Manager Patch Manager to automate patching nodes when required to do so.

-
-
-

Patching nodes will allow you to quickly roll out security updates and replace the instances on a regular schedule after your AMI has been updated. If you are using an operating system with a read-only root file system like Flatcar Container Linux or Bottlerocket OS we recommend using the update operators that work with those operating systems. The Flatcar Linux update operator and Bottlerocket update operator will reboot instances to keep nodes up to date automatically.

-
-
-
-
-
-

Cluster Services

-
-
-

Cluster services run inside an EKS cluster, but they are not user workloads. If you have a Linux server you often need to run services like NTP, syslog, and a container runtime to support your workloads. Cluster services are similar, supporting services that help you automate and operate your cluster. In Kubernetes these are usually run in the kube-system namespace and some are run as DaemonSets.

-
-
-

Cluster services are expected to have a high up-time and are often critical during outages and for troubleshooting. If a core cluster service is not available you may lose access to data that can help recover or prevent an outage (e.g. high disk utilization). They should run on dedicated compute instances such as a separate node group or AWS Fargate. This will ensure that the cluster services are not impacted on shared instances by workloads that may be scaling up or using more resources.

-
-
-

Scale CoreDNS

-
-

Scaling CoreDNS has two primary mechanisms. Reducing the number of calls to the CoreDNS service and increasing the number of replicas.

-
-
-

Reduce external queries by lowering ndots

-
-

The ndots setting specifies how many periods (a.k.a. "dots") in a domain name are considered enough to avoid querying DNS. If your application has an ndots setting of 5 (default) and you request resources from an external domain such as api.example.com (2 dots) then CoreDNS will be queried for each search domain defined in /etc/resolv.conf for a more specific domain. By default the following domains will be searched before making an external request.

-
-
-
-
api.example.<namespace>.svc.cluster.local
-api.example.svc.cluster.local
-api.example.cluster.local
-api.example.<region>.compute.internal
-
-
-
-

The namespace and region values will be replaced with your workloads namespace and your compute region. You may have additional search domains based on your cluster settings.

-
-
-

You can reduce the number of requests to CoreDNS by lowering the ndots option of your workload or fully qualifying your domain requests by including a trailing . (e.g. api.example.com. ). If your workload connects to external services via DNS we recommend setting ndots to 2 so workloads do not make unnecessary, cluster DNS queries inside the cluster. You can set a different DNS server and search domain if the workload doesn’t require access to services inside the cluster.

-
-
-
-
spec:
-  dnsPolicy: "None"
-  dnsConfig:
-    options:
-      - name: ndots
-        value: "2"
-      - name: edns0
-
-
-
-

If you lower ndots to a value that is too low or the domains you are connecting to do not include enough specificity (including trailing .) then it is possible DNS lookups will fail. Make sure you test how this setting will impact your workloads.

-
-
-
-

Scale CoreDNS Horizontally

-
-

CoreDNS instances can scale by adding additional replicas to the deployment. It’s recommended you use NodeLocal DNS or the cluster proportional autoscaler to scale CoreDNS.

-
-
-

NodeLocal DNS will require run one instance per node—​as a DaemonSet—​which requires more compute resources in the cluster, but it will avoid failed DNS requests and decrease the response time for DNS queries in the cluster. The cluster proportional autoscaler will scale CoreDNS based on the number of nodes or cores in the cluster. This isn’t a direct correlation to request queries, but can be useful depending on your workloads and cluster size. The default proportional scale is to add an additional replica for every 256 cores or 16 nodes in the cluster—​whichever happens first.

-
-
-
-
-

Scale Kubernetes Metrics Server Vertically

-
-

The Kubernetes Metrics Server supports horizontal and vertical scaling. By horizontally scaling the Metrics Server it will be highly available, but it will not scale horizontally to handle more cluster metrics. You will need to vertically scale the Metrics Server based on their recommendations as nodes and collected metrics are added to the cluster.

-
-
-

The Metrics Server keeps the data it collects, aggregates, and serves in memory. As a cluster grows, the amount of data the Metrics Server stores increases. In large clusters the Metrics Server will require more compute resources than the memory and CPU reservation specified in the default installation. You can use the Vertical Pod Autoscaler (VPA) or Addon Resizer to scale the Metrics Server. The Addon Resizer scales vertically in proportion to worker nodes and VPA scales based on CPU and memory usage.

-
-
-
-

CoreDNS lameduck duration

-
-

Pods use the kube-dns Service for name resolution. Kubernetes uses destination NAT (DNAT) to redirect kube-dns traffic from nodes to CoreDNS backend pods. As you scale the CoreDNS Deployment, kube-proxy updates iptables rules and chains on nodes to redirect DNS traffic to CoreDNS pods. Propagating new endpoints when you scale up and deleting rules when you scale down CoreDNS can take between 1 to 10 seconds depending on the size of the cluster.

-
-
-

This propagation delay can cause DNS lookup failures when a CoreDNS pod gets terminated yet the node’s iptables rules haven’t been updated. In this scenario, the node may continue to send DNS queries to a terminated CoreDNS Pod.

-
-
-

You can reduce DNS lookup failures by setting a lameduck duration in your CoreDNS pods. While in lameduck mode, CoreDNS will continue to respond to in-flight requests. Setting a lameduck duration will delay the CoreDNS shutdown process, allowing nodes the time they need to update their iptables rules and chains.

-
-
-

We recommend setting CoreDNS lameduck duration to 30 seconds.

-
-
-
-

CoreDNS readiness probe

-
-

We recommend using /ready instead of /health for CoreDNS’s readiness probe.

-
-
-

In alignment with the earlier recommendation to set the lameduck duration to 30 seconds, providing ample time for the node’s iptables rules to be updated before pod termination, employing /ready instead of /health for the CoreDNS readiness probe ensures that the CoreDNS pod is fully prepared at startup to promptly respond to DNS requests.

-
-
-
-
readinessProbe:
-  httpGet:
-    path: /ready
-    port: 8181
-    scheme: HTTP
-
-
-
-

For more information about the CoreDNS Ready plugin please refer to https://coredns.io/plugins/ready/

-
-
-
-

Logging and monitoring agents

-
-

Logging and monitoring agents can add significant load to your cluster control plane because the agents query the API server to enrich logs and metrics with workload metadata. The agent on a node only has access to the local node resources to see things like container and process name. Querying the API server it can add more details such as Kubernetes deployment name and labels. This can be extremely helpful for troubleshooting but detrimental to scaling.

-
-
-

Because there are so many different options for logging and monitoring we cannot show examples for every provider. With fluentbit we recommend enabling Use_Kubelet to fetch metadata from the local kubelet instead of the Kubernetes API Server and set Kube_Meta_Cache_TTL to a number that reduces repeated calls when data can be cached (e.g. 60).

-
-
-

Scaling monitoring and logging has two general options:

-
-
-
    -
  • -

    Disable integrations

    -
  • -
  • -

    Sampling and filtering

    -
  • -
-
-
-

Disabling integrations is often not an option because you lose log metadata. This eliminates the API scaling problem, but it will introduce other issues by not having the required metadata when needed.

-
-
-

Sampling and filtering reduces the number of metrics and logs that are collected. This will lower the amount of requests to the Kubernetes API, and it will reduce the amount of storage needed for the metrics and logs that are collected. Reducing the storage costs will lower the cost for the overall system.

-
-
-

The ability to configure sampling depends on the agent software and can be implemented at different points of ingestion. It’s important to add sampling as close to the agent as possible because that is likely where the API server calls happen. Contact your provider to find out more about sampling support.

-
-
-

If you are using CloudWatch and CloudWatch Logs you can add agent filtering using patterns described in the documentation.

-
-
-

To avoid losing logs and metrics you should send your data to a system that can buffer data in case of an outage on the receiving endpoint. With fluentbit you can use Amazon Kinesis Data Firehose to temporarily keep data which can reduce the chance of overloading your final data storage location.

-
-
-
-
-
-

Workloads

-
-
-

Workloads have an impact on how large your cluster can scale. Workloads that use the Kubernetes APIs heavily will limit the total amount of workloads you can have in a single cluster, but there are some defaults you can change to help reduce the load.

-
-
-

Workloads in a Kubernetes cluster have access to features that integrate with the Kubernetes API (e.g. Secrets and ServiceAccounts), but these features are not always required and should be disabled if they’re not being used. Limiting workload access and dependence on the Kubernetes control plane will increase the number of workloads you can run in the cluster and improve the security of your clusters by removing unnecessary access to workloads and implementing least privilege practices. Please read the security best practices for more information.

-
-
-

Use IPv6 for pod networking

-
-

You cannot transition a VPC from IPv4 to IPv6 so enabling IPv6 before provisioning a cluster is important. If you enable IPv6 in a VPC it does not mean you have to use it and if your pods and services use IPv6 you can still route traffic to and from IPv4 addresses. Please see the EKS networking best practices for more information.

-
-
-

Using IPv6 in your cluster avoids some of the most common cluster and workload scaling limits. IPv6 avoids IP address exhaustion where pods and nodes cannot be created because no IP address is available. It also has per node performance improvements because pods receive IP addresses faster by reducing the number of ENI attachments per node. You can achieve similar node performance by using IPv4 prefix mode in the VPC CNI, but you still need to make sure you have enough IP addresses available in the VPC.

-
-
-
-

Limit number of services per namespace

-
-

The maximum number of services in a namespaces is 5,000 and the maximum number of services in a cluster is 10,000. To help organize workloads and services, increase performance, and to avoid cascading impact for namespace scoped resources we recommend limiting the number of services per namespace to 500.

-
-
-

The number of IP tables rules that are created per node with kube-proxy grows with the total number of services in the cluster. Generating thousands of IP tables rules and routing packets through those rules have a performance impact on the nodes and add network latency.

-
-
-

Create Kubernetes namespaces that encompass a single application environment so long as the number of services per namespace is under 500. This will keep service discovery small enough to avoid service discovery limits and can also help you avoid service naming collisions. Applications environments (e.g. dev, test, prod) should use separate EKS clusters instead of namespaces.

-
-
-
-

Understand Elastic Load Balancer Quotas

-
-

When creating your services consider what type of load balancing you will use (e.g. Network Load Balancer (NLB) or Application Load Balancer (ALB)). Each load balancer type provides different functionality and have different quotas. Some of the default quotas can be adjusted, but there are some quota maximums which cannot be changed. To view your account quotas and usage view the Service Quotas dashboard in the AWS console.

-
-
-

For example, the default ALB targets is 1000. If you have a service with more than 1000 endpoints you will need to increase the quota or split the service across multiple ALBs or use Kubernetes Ingress. The default NLB targets is 3000, but is limited to 500 targets per AZ. If your cluster runs more than 500 pods for an NLB service you will need to use multiple AZs or request a quota limit increase.

-
-
-

An alternative to using a load balancer coupled to a service is to use an ingress controller. The AWS Load Balancer controller can create ALBs for ingress resources, but you may consider running a dedicated controller in your cluster. An in-cluster ingress controller allows you to expose multiple Kubernetes services from a single load balancer by running a reverse proxy inside your cluster. Controllers have different features such as support for the Gateway API which may have benefits depending on how many and how large your workloads are.

-
-
-
-

Use Route 53, Global Accelerator, or CloudFront

-
-

To make a service using multiple load balancers available as a single endpoint you need to use Amazon CloudFront, AWS Global Accelerator, or Amazon Route 53 to expose all of the load balancers as a single, customer facing endpoint. Each options has different benefits and can be used separately or together depending on your needs.

-
-
-

Route 53 can expose multiple load balancers under a common name and can send traffic to each of them based on the weight assigned. You can read more about DNS weights in the documentation and you can read how to implement them with the Kubernetes external DNS controller in the AWS Load Balancer Controller documentation.

-
-
-

Global Accelerator can route workloads to the nearest region based on request IP address. This may be useful for workloads that are deployed to multiple regions, but it does not improve routing to a single cluster in a single region. Using Route 53 in combination with the Global Accelerator has additional benefits such as health checking and automatic failover if an AZ is not available. You can see an example of using Global Accelerator with Route 53 in this blog post.

-
-
-

CloudFront can be use with Route 53 and Global Accelerator or by itself to route traffic to multiple destinations. CloudFront caches assets being served from the origin sources which may reduce bandwidth requirements depending on what you are serving.

-
-
-
-

Use EndpointSlices instead of Endpoints

-
-

When discovering pods that match a service label you should use EndpointSlices instead of Endpoints. Endpoints were a simple way to expose services at small scales but large services that automatically scale or have updates causes a lot of traffic on the Kubernetes control plane. EndpointSlices have automatic grouping which enable things like topology aware hints.

-
-
-

Not all controllers use EndpointSlices by default. You should verify your controller settings and enable it if needed. For the AWS Load Balancer Controller you should enable the --enable-endpoint-slices optional flag to use EndpointSlices.

-
-
-
-

Use immutable and external secrets if possible

-
-

The kubelet keeps a cache of the current keys and values for the Secrets that are used in volumes for pods on that node. The kubelet sets a watch on the Secrets to detect changes. As the cluster scales, the growing number of watches can negatively impact the API server performance.

-
-
-

There are two strategies to reduce the number of watches on Secrets:

-
-
-
    -
  • -

    For applications that don’t need access to Kubernetes resources, you can disable auto-mounting service account secrets by setting automountServiceAccountToken: false

    -
  • -
  • -

    If your application’s secrets are static and will not be modified in the future, mark the secret as immutable. The kubelet does not maintain an API watch for immutable secrets.

    -
  • -
-
-
-

To disable automatically mounting a service account to pods you can use the following setting in your workload. You can override these settings if specific workloads need a service account.

-
-
-
-
apiVersion: v1
-kind: ServiceAccount
-metadata:
-  name: app
-automountServiceAccountToken: true
-
-
-
-

Monitor the number of secrets in the cluster before it exceeds the limit of 10,000. You can see a total count of secrets in a cluster with the following command. You should monitor this limit through your cluster monitoring tooling.

-
-
-
-
kubectl get secrets -A | wc -l
-
-
-
-

You should set up monitoring to alert a cluster admin before this limit is reached. Consider using external secrets management options such as AWS Key Management Service (AWS KMS) or Hashicorp Vault with the Secrets Store CSI driver.

-
-
-
-

Limit Deployment history

-
-

Pods can be slow when creating, updating, or deleting because old objects are still tracked in the cluster. You can reduce the revisionHistoryLimit of deployments to cleanup older ReplicaSets which will lower to total amount of objects tracked by the Kubernetes Controller Manager. The default history limit for Deployments in 10.

-
-
-

If your cluster creates a lot of job objects through CronJobs or other mechanisms you should use the ttlSecondsAfterFinished setting to automatically clean up old pods in the cluster. This will remove successfully executed jobs from the job history after a specified amount of time.

-
-
-
- -
-

When a Pod runs on a Node, the kubelet adds a set of environment variables for each active Service. Linux processes have a maximum size for their environment which can be reached if you have too many services in your namespace. The number of services per namespace should not exceed 5,000. After this, the number of service environment variables outgrows shell limits, causing Pods to crash on startup.

-
-
-

There are other reasons pods should not use service environment variables for service discovery. Environment variable name clashes, leaking service names, and total environment size are a few. You should use CoreDNS for discovering service endpoints.

-
-
-
-

Limit dynamic admission webhooks per resource

-
-

Dynamic Admission Webhooks include admission webhooks and mutating webhooks. They are API endpoints not part of the Kubernetes Control Plane that are called in sequence when a resource is sent to the Kubernetes API. Each webhook has a default timeout of 10 seconds and can increase the amount of time an API request takes if you have multiple webhooks or any of them timeout.

-
-
-

Make sure your webhooks are highly available—​especially during an AZ incident—​and the failurePolicy is set properly to reject the resource or ignore the failure. Do not call webhooks when not needed by allowing --dry-run kubectl commands to bypass the webhook.

-
-
-
-
apiVersion: admission.k8s.io/v1
-kind: AdmissionReview
-request:
-  dryRun: False
-
-
-
-

Mutating webhooks can modify resources in frequent succession. If you have 5 mutating webhooks and deploy 50 resources etcd will store all versions of each resource until compaction runs—​every 5 minutes—​to remove old versions of modified resources. In this scenario when etcd removes superseded resources there will be 200 resource version removed from etcd and depending on the size of the resources may use considerable space on the etcd host until defragmentation runs every 15 minutes.

-
-
-

This defragmentation may cause pauses in etcd which could have other affects on the Kubernetes API and controllers. You should avoid frequent modification of large resources or modifying hundreds of resources in quick succession.

-
-
-
-
-
-

Kubernetes Scaling Theory

-
-
-

Nodes vs. Churn Rate

-
-

Often when we discuss the scalability of Kubernetes, we do so in terms of how many nodes there are in a single cluster. Interestingly, this is seldom the most useful metric for understanding scalability. For example, a 5,000 node cluster with a large but fixed number of pods would not put a great deal of stress on the control plane after the initial setup. However, if we took a 1,000 node cluster and tried creating 10,000 short lived jobs in less than a minute, it would put a great deal of sustained pressure on the control plane.

-
-
-

Simply using the number of nodes to understand scaling can be misleading. It’s better to think in terms of the rate of change that occurs within a specific period of time (let’s use a 5 minute interval for this discussion, as this is what Prometheus queries typically use by default). Let’s explore why framing the problem in terms of the rate of change can give us a better idea of what to tune to achieve our desired scale.

-
-
-
-

Thinking in Queries Per Second

-
-

Kubernetes has a number of protection mechanisms for each component - the Kubelet, Scheduler, Kube Controller Manager, and API server - to prevent overwhelming the next link in the Kubernetes chain. For example, the Kubelet has a flag to throttle calls to the API server at a certain rate. These protection mechanisms are generally, but not always, expressed in terms of queries allowed on a per second basis or QPS.

-
-
-

Great care must be taken when changing these QPS settings. Removing one bottleneck, such as the queries per second on a Kubelet will have an impact on other down stream components. This can and will overwhelm the system above a certain rate, so understanding and monitoring each part of the service chain is key to successfully scaling workloads on Kubernetes.

-
-
-

!!! note - The API server has a more complex system with introduction of API Priority and Fairness which we will discuss separately.

-
-
-

!!! note - Caution, some metrics seem like the right fit but are in fact measuring something else. As an example, kubelet_http_inflight_requests relates to just the metrics server in Kubelet, not the number of requests from Kubelet to apiserver requests. This could cause us to misconfigure the QPS flag on the Kubelet. A query on audit logs for a particular Kubelet would be a more reliable way to check metrics.

-
-
-
-

Scaling Distributed Components

-
-

Since EKS is a managed service, let’s split the Kubernetes components into two categories: AWS managed components which include etcd, Kube Controller Manager, and the Scheduler (on the left part of diagram), and customer configurable components such as the Kubelet, Container Runtime, and the various operators that call AWS APIs such as the Networking and Storage drivers (on the right part of diagram). We leave the API server in the middle even though it is AWS managed, as the settings for API Priority and Fairness can be configured by customers.

-
-
-
-Kubernetes components -
-
-
-
-

Upstream and Downstream Bottlenecks

-
-

As we monitor each service, it’s important to look at metrics in both directions to look for bottlenecks. Let’s learn how to do this by using Kubelet as an example. Kubelet talks both to the API server and the container runtime; how and what do we need to monitor to detect whether either component is experiencing an issue?

-
-
-

How many Pods per Node

-
-

When we look at scaling numbers, such as how many pods can run on a node, we could take the 110 pods per node that upstream supports at face value.

-
- -
-

However, your workload is likely more complex than what was tested in a scalability test in Upstream. To ensure we can service the number of pods we want to run in production, let’s make sure that the Kubelet is “keeping up” with the Containerd runtime.

-
-
-
-Keeping up -
-
-
-

To oversimplify, the Kubelet is getting the status of the pods from the container runtime (in our case Containerd). What if we had too many pods changing status too quickly? If the rate of change is too high, requests [to the container runtime] can timeout.

-
-
-

!!! note - Kubernetes is constantly evolving, this subsystem is currently undergoing changes. https://github.com/kubernetes/enhancements/issues/3386

-
-
-

Flow -PLEG duration

-
-
-

In the graph above, we see a flat line indicating we have just hit the timeout value for the pod lifecycle event generation duration metric. If you would like to see this in your own cluster you could use the following PromQL syntax.

-
-
-
-
increase(kubelet_pleg_relist_duration_seconds_bucket{instance="$instance"}[$__rate_interval])
-
-
-
-

If we witness this timeout behavior, we know we pushed the node over the limit it was capable of. We need to fix the cause of the timeout before proceeding further. This could be achieved by reducing the number of pods per node, or looking for errors that might be causing a high volume of retries (thus effecting the churn rate). The important take-away is that metrics are the best way to understand if a node is able to handle the churn rate of the pods assigned vs. using a fixed number.

-
-
-
-
-

Scale by Metrics

-
-

While the concept of using metrics to optimize systems is an old one, it’s often overlooked as people begin their Kubernetes journey. Instead of focusing on specific numbers (i.e. 110 pods per node), we focus our efforts on finding the metrics that help us find bottlenecks in our system. Understanding the right thresholds for these metrics can give us a high degree of confidence our system is optimally configured.

-
-
-

The Impact of Changes

-
-

A common pattern that could get us into trouble is focusing on the first metric or log error that looks suspect. When we saw that the Kubelet was timing out earlier, we could try random things, such as increasing the per second rate that the Kubelet is allowed to send, etc. However, it is wise to look at the whole picture of everything downstream of the error we find first. Make each change with purpose and backed by data.

-
-
-

Downstream of the Kubelet would be the Containerd runtime (pod errors), DaemonSets such as the storage driver (CSI) and the network driver (CNI) that talk to the EC2 API, etc.

-
-
-
-Flow add-ons -
-
-
-

Let’s continue our earlier example of the Kubelet not keeping up with the runtime. There are a number of points where we could bin pack a node so densely that it triggers errors.

-
-
-
-Bottlenecks -
-
-
-

When designing the right node size for our workloads these are easy-to-overlook signals that might be putting unnecessary pressure on the system thus limiting both our scale and performance.

-
-
-
-

The Cost of Unnecessary Errors

-
-

Kubernetes controllers excel at retrying when error conditions arise, however this comes at a cost. These retries can increase the pressure on components such as the Kube Controller Manager. It is an important tenant of scale testing to monitor for such errors.

-
-
-

When fewer errors are occurring, it is easier spot issues in the system. By periodically ensuring that our clusters are error free before major operations (such as upgrades) we can simplify troubleshooting logs when unforeseen events happen.

-
-
-
Expanding Our View
-
-

In large scale clusters with 1,000’s of nodes we don’t want to look for bottlenecks individually. In PromQL we can find the highest values in a data set using a function called topk; K being a variable we place the number of items we want. Here we use three nodes to get an idea whether all of the the Kubelets in the cluster are saturated. We have been looking at latency up to this point, now let’s see if the Kubelet is discarding events.

-
-
-
-
topk(3, increase(kubelet_pleg_discard_events{}[$__rate_interval]))
-
-
-
-

Breaking this statement down.

-
-
-
    -
  • -

    We use the Grafana variable $__rate_interval to ensure it gets the four samples it needs. This bypasses a complex topic in monitoring with a simple variable.

    -
  • -
  • -

    topk give us just the top results and the number 3 limits those results to three. This is a useful function for cluster wide metrics.

    -
  • -
  • -

    {} tell us there are no filters, normally you would put the job name of whatever the scraping rule, however since these names vary we will leave it blank.

    -
  • -
-
-
-
-
Splitting the Problem in Half
-
-

To address a bottleneck in the system, we will take the approach of finding a metric that shows us there is a problem upstream or downstream as this allows us to split the problem in half. It will also be a core tenet of how we display our metrics data.

-
-
-

A good place to start with this process is the API server, as it allow us to see if there’s a problem with a client application or the Control Plane.

-
-
-
-
-
-
-
-

Control Plane Monitoring

-
-
-

API Server

-
-

When looking at our API server it’s important to remember that one of its functions is to throttle inbound requests to prevent overloading the control plane. What can seem like a bottleneck at the API server level might actually be protecting it from more serious issues. We need to factor in the pros and cons of increasing the volume of requests moving through the system. To make a determination if the API server values should be increased, here is small sampling of the things we need to be mindful of:

-
-
-
    -
  1. -

    What is the latency of requests moving through the system?

    -
  2. -
  3. -

    Is that latency the API server itself, or something “downstream” like etcd?

    -
  4. -
  5. -

    Is the API server queue depth a factor in this latency?

    -
  6. -
  7. -

    Are the API Priority and Fairness (APF) queues setup correctly for the API call patterns we want?

    -
  8. -
-
-
-
-

Where is the issue?

-
-

To start, we can use the metric for API latency to give us insight into how long it’s taking the API server to service requests. Let’s use the below PromQL and Grafana heatmap to display this data.

-
-
-
-
max(increase(apiserver_request_duration_seconds_bucket{subresource!="status",subresource!="token",subresource!="scale",subresource!="/healthz",subresource!="binding",subresource!="proxy",verb!="WATCH"}[$__rate_interval])) by (le)
-
-
-
-

!!! tip - For an in depth write up on how to monitor the API server with the API dashboard used in this article, please see the following blog

-
-
-
-API request duration heatmap -
-
-
-

These requests are all under the one second mark, which is a good indication that the control plane is handling requests in a timely fashion. But what if that was not the case?

-
-
-

The format we are using in the above API Request Duration is a heatmap. What’s nice about the heatmap format, is that it tells us the timeout value for the API by default (60 sec). However, what we really need to know is at what threshold should this value be of concern before we reach the timeout threshold. For a rough guideline of what acceptable thresholds are we can use the upstream Kubernetes SLO, which can be found here

-
-
-

!!! tip - Notice the max function on this statement? When using metrics that are aggregating multiple servers (by default two API servers on EKS) it’s important not to average those servers together.

-
-
-

Asymmetrical traffic patterns

-
-

What if one API server [pod] was lightly loaded, and the other heavily loaded? If we averaged those two numbers together we might misinterpret what was happening. For example, here we have three API servers but all of the load is on one of these API servers. As a rule anything that has multiple servers such as etcd and API servers should be broken out when investing scale and performance issues.

-
-
-
-Total inflight requests -
-
-
-

With the move to API Priority and Fairness the total number of requests on the system is only one factor to check to see if the API server is oversubscribed. Since the system now works off a series of queues, we must look to see if any of these queues are full and if the traffic for that queue is getting dropped.

-
-
-

Let’s look at these queues with the following query:

-
-
-
-
max without(instance)(apiserver_flowcontrol_request_concurrency_limit{})
-
-
-
-

!!! note - For more information on how API A&F works please see the following best practices guide

-
-
-

Here we see the seven different priority groups that come by default on the cluster

-
-
-
-Shared concurrency -
-
-
-

Next we want to see what percentage of that priority group is being used, so that we can understand if a certain priority level is being saturated. Throttling requests in the workload-low level might be desirable, however drops in a leader election level would not be.

-
-
-

The API Priority and Fairness (APF) system has a number of complex options, some of those options can have unintended consequences. A common issue we see in the field is increasing the queue depth to the point it starts adding unnecessary latency. We can monitor this problem by using the apiserver_flowcontrol_current_inqueue_request metric. We can check for drops using the apiserver_flowcontrol_rejected_requests_total. These metrics will be a non-zero value if any bucket exceeds its concurrency.

-
-
-
-Requests in use -
-
-
-

Increasing the queue depth can make the API Server a significant source of latency and should be done with care. We recommend being judicious with the number of queues created. For example, the number of shares on a EKS system is 600, if we create too many queues, this can reduce the shares in important queues that need the throughput such as the leader-election queue or system queue. Creating too many extra queues can make it more difficult to size theses queues correctly.

-
-
-

To focus on a simple impactful change you can make in APF we simply take shares from underutilized buckets and increase the size of buckets that are at their max usage. By intelligently redistributing the shares among these buckets, you can make drops less likely.

-
-
-

For more information, visit API Priority and Fairness settings in the EKS Best Practices Guide.

-
-
-
-

API vs. etcd latency

-
-

How can we use the metrics/logs of the API server to determine whether there’s a problem with API server, or a problem that’s upstream/downstream of the API server, or a combination of both. To understand this better, lets look at how API Server and etcd can be related, and how easy it can be to troubleshoot the wrong system.

-
-
-

In the below chart we see API server latency, but we also see much of this latency is correlated to the etcd server due to the bars in the graph showing most of the latency at the etcd level. If there is 15 secs of etcd latency at the same time there is 20 seconds of API server latency, then the majority of the latency is actually at the etcd level.

-
-
-

By looking at the whole flow, we see that it’s wise to not focus solely on the API Server, but also look for signals that indicate that etcd is under duress (i.e. slow apply counters increasing). Being able to quickly move to the right problem area with just a glance is what makes a dashboard powerful.

-
- -
-
-ETCD duress -
-
-
-
-

Control plane vs. Client side issues

-
-

In this chart we are looking for the API calls that took the most time to complete for that period. In this case we see a custom resource (CRD) is calling a APPLY function that is the most latent call during the 05:40 time frame.

-
-
-
-Slowest requests -
-
-
-

Armed with this data we can use an Ad-Hoc PromQL or a CloudWatch Insights query to pull LIST requests from the audit log during that time frame to see which application this might be.

-
-
-
-

Finding the Source with CloudWatch

-
-

Metrics are best used to find the problem area we want to look at and narrow both the timeframe and the search parameters of the problem. Once we have this data we want to transition to logs for more detailed times and errors. To do this we will turn our logs into metrics using CloudWatch Logs Insights.

-
-
-

For example, to investigate the issue above, we will use the following CloudWatch Logs Insights query to pull the userAgent and requestURI so that we can pin down which application is causing this latency.

-
-
-

!!! tip - An appropriate Count needs to be used as to not pull normal List/Resync behavior on a Watch.

-
-
-
-
fields *@timestamp*, *@message*
-| filter *@logStream* like "kube-apiserver-audit"
-| filter ispresent(requestURI)
-| filter verb = "list"
-| parse requestReceivedTimestamp /\d+-\d+-(?<StartDay>\d+)T(?<StartHour>\d+):(?<StartMinute>\d+):(?<StartSec>\d+).(?<StartMsec>\d+)Z/
-| parse stageTimestamp /\d+-\d+-(?<EndDay>\d+)T(?<EndHour>\d+):(?<EndMinute>\d+):(?<EndSec>\d+).(?<EndMsec>\d+)Z/
-| fields (StartHour * 3600 + StartMinute * 60 + StartSec + StartMsec / 1000000) as StartTime, (EndHour * 3600 + EndMinute * 60 + EndSec + EndMsec / 1000000) as EndTime, (EndTime - StartTime) as DeltaTime
-| stats avg(DeltaTime) as AverageDeltaTime, count(*) as CountTime by requestURI, userAgent
-| filter CountTime >=50
-| sort AverageDeltaTime desc
-
-
-
-

Using this query we found two different agents running a large number of high latency list operations. Splunk and CloudWatch agent. Armed with the data, we can make a decision to remove, update, or replace this controller with another project.

-
-
-
-Query results -
-
-
-

!!! tip - For more details on this subject please see the following blog

-
-
-
-
-

Scheduler

-
-

Since the EKS control plane instances are run in separate AWS account we will not be able to scrape those components for metrics (The API server being the exception). However, since we have access to the audit logs for these components, we can turn those logs into metrics to see if any of the sub-systems are causing a scaling bottleneck. Let’s use CloudWatch Logs Insights to see how many unscheduled pods are in the scheduler queue.

-
-
-

Unscheduled pods in the scheduler log

-
-

If we had access to scrape the scheduler metrics directly on a self managed Kubernetes (such as Kops) we would use the following PromQL to understand the scheduler backlog.

-
-
-
-
max without(instance)(scheduler_pending_pods)
-
-
-
-

Since we do not have access to the above metric in EKS, we will use the below CloudWatch Logs Insights query to see the backlog by checking for how many pods were unable to unscheduled during a particular time frame. Then we could dive further into into the messages at the peak time frame to understand the nature of the bottleneck. For example, nodes not spinning up fast enough, or the rate limiter in the scheduler itself.

-
-
-
-
fields timestamp, pod, err, *@message*
-| filter *@logStream* like "scheduler"
-| filter *@message* like "Unable to schedule pod"
-| parse *@message*  /^.(?<date>\d{4})\s+(?<timestamp>\d+:\d+:\d+\.\d+)\s+\S*\s+\S+\]\s\"(.*?)\"\s+pod=(?<pod>\"(.*?)\")\s+err=(?<err>\"(.*?)\")/
-| count(*) as count by pod, err
-| sort count desc
-
-
-
-

Here we see the errors from the scheduler saying the pod did not deploy because the storage PVC was unavailable.

-
-
-
-CloudWatch Logs query -
-
-
-

!!! note - Audit logging must be turned on the control plane to enable this function. It is also a best practice to limit the log retention as to not drive up cost over time unnecessarily. An example for turning on all logging functions using the EKSCTL tool below.

-
-
-
-
cloudWatch:
-  clusterLogging:
-    enableTypes: ["*"]
-    logRetentionInDays: 10
-
-
-
-
-
-

Kube Controller Manager

-
-

Kube Controller Manager, like all other controllers, has limits on how many operations it can do at once. Let’s review what some of those flags are by looking at a KOPS configuration where we can set these parameters.

-
-
-
-
  kubeControllerManager:
-    concurrentEndpointSyncs: 5
-    concurrentReplicasetSyncs: 5
-    concurrentNamespaceSyncs: 10
-    concurrentServiceaccountTokenSyncs: 5
-    concurrentServiceSyncs: 5
-    concurrentResourceQuotaSyncs: 5
-    concurrentGcSyncs: 20
-    kubeAPIBurst: 20
-    kubeAPIQPS: "30"
-
-
-
-

These controllers have queues that fill up during times of high churn on a cluster. In this case we see the replicaset set controller has a large backlog in its queue.

-
-
-
-Queues -
-
-
-

We have two different ways of addressing such a situation. If running self managed we could simply increase the concurrent goroutines, however this would have an impact on etcd by processing more data in the KCM. The other option would be to reduce the number of replicaset objects using .spec.revisionHistoryLimit on the deployment to reduce the number of replicaset objects we can rollback, thus reducing the pressure on this controller.

-
-
-
-
spec:
-  revisionHistoryLimit: 2
-
-
-
-

Other Kubernetes features can be tuned or turned off to reduce pressure in high churn rate systems. For example, if the application in our pods doesn’t need to speak to the k8s API directly then turning off the projected secret into those pods would decrease the load on ServiceaccountTokenSyncs. This is the more desirable way to address such issues if possible.

-
-
-
-
kind: Pod
-spec:
-  automountServiceAccountToken: false
-
-
-
-

In systems where we can’t get access to the metrics, we can again look at the logs to detect contention. If we wanted to see the number of requests being being processed on a per controller or an aggregate level we would use the following CloudWatch Logs Insights Query.

-
-
-

Total Volume Processed by the KCM

-
-
-
# Query to count API qps coming from kube-controller-manager, split by controller type.
-# If you're seeing values close to 20/sec for any particular controller, it's most likely seeing client-side API throttling.
-fields @timestamp, @logStream, @message
-| filter @logStream like /kube-apiserver-audit/
-| filter userAgent like /kube-controller-manager/
-# Exclude lease-related calls (not counted under kcm qps)
-| filter requestURI not like "apis/coordination.k8s.io/v1/namespaces/kube-system/leases/kube-controller-manager"
-# Exclude API discovery calls (not counted under kcm qps)
-| filter requestURI not like "?timeout=32s"
-# Exclude watch calls (not counted under kcm qps)
-| filter verb != "watch"
-# If you want to get counts of API calls coming from a specific controller, uncomment the appropriate line below:
-# | filter user.username like "system:serviceaccount:kube-system:job-controller"
-# | filter user.username like "system:serviceaccount:kube-system:cronjob-controller"
-# | filter user.username like "system:serviceaccount:kube-system:deployment-controller"
-# | filter user.username like "system:serviceaccount:kube-system:replicaset-controller"
-# | filter user.username like "system:serviceaccount:kube-system:horizontal-pod-autoscaler"
-# | filter user.username like "system:serviceaccount:kube-system:persistent-volume-binder"
-# | filter user.username like "system:serviceaccount:kube-system:endpointslice-controller"
-# | filter user.username like "system:serviceaccount:kube-system:endpoint-controller"
-# | filter user.username like "system:serviceaccount:kube-system:generic-garbage-controller"
-| stats count(*) as count by user.username
-| sort count desc
-
-
-
-

The key takeaway here is when looking into scalability issues, to look at every step in the path (API, scheduler, KCM, etcd) before moving to the detailed troubleshooting phase. Often in production you will find that it takes adjustments to more than one part of Kubernetes to allow the system to work at its most performant. It’s easy to inadvertently troubleshoot what is just a symptom (such as a node timeout) of a much larger bottle neck.

-
-
-
-
-

ETCD

-
-

etcd uses a memory mapped file to store key value pairs efficiently. There is a protection mechanism to set the size of this memory space available set commonly at the 2, 4, and 8GB limits. Fewer objects in the database means less clean up etcd needs to do when objects are updated and older versions needs to be cleaned out. This process of cleaning old versions of an object out is referred to as compaction. After a number of compaction operations, there is a subsequent process that recovers usable space space called defragging that happens above a certain threshold or on a fixed schedule of time.

-
-
-

There are a couple user related items we can do to limit the number of objects in Kubernetes and thus reduce the impact of both the compaction and de-fragmentation process. For example, Helm keeps a high revisionHistoryLimit. This keeps older objects such as ReplicaSets on the system to be able to do rollbacks. By setting the history limits down to 2 we can reduce the the number of objects (like ReplicaSets) from ten to two which in turn would put less load on the system.

-
-
-
-
apiVersion: apps/v1
-kind: Deployment
-spec:
-  revisionHistoryLimit: 2
-
-
-
-

From a monitoring standpoint, if system latency spikes occur in a set pattern separated by hours, checking to see if this defragmentation process is the source can be helpful. We can see this by using CloudWatch Logs.

-
-
-

If you want to see start/end times of defrag use the following query:

-
-
-
-
fields *@timestamp*, *@message*
-| filter *@logStream* like /etcd-manager/
-| filter *@message* like /defraging|defraged/
-| sort *@timestamp* asc
-
-
-
-
-Defrag query -
-
-
-
-
-
-

Node and Workload Efficiency

-
-
-

Being efficient with our workloads and nodes reduces complexity/cost while increasing performance and scale. There are many factors to consider when planning this efficiency, and it’s easiest to think in terms of trade offs vs. one best practice setting for each feature. Let’s explore these tradeoffs in depth in the following section.

-
-
-

Node Selection

-
-

Using node sizes that are slightly larger (4-12xlarge) increases the available space that we have for running pods due to the fact it reduces the percentage of the node used for “overhead” such as DaemonSets and Reserves for system components. In the diagram below we see the difference between the usable space on a 2xlarge vs. a 8xlarge system with just a moderate number of DaemonSets.

-
-
-

!!! note - Since k8s scales horizontally as a general rule, for most applications it does not make sense to take the performance impact of NUMA sizes nodes, thus the recommendation of a range below that node size.

-
-
-
-Node size -
-
-
-

Large nodes sizes allow us to have a higher percentage of usable space per node. However, this model can be taken to to the extreme by packing the node with so many pods that it causes errors or saturates the node. Monitoring node saturation is key to successfully using larger node sizes.

-
-
-

Node selection is rarely a one-size-fits-all proposition. Often it is best to split workloads with dramatically different churn rates into different node groups. Small batch workloads with a high churn rate would be best served by the the 4xlarge family of instances, while a large scale application such as Kafka which takes 8 vCPU and has a low churn rate would be better served by the 12xlarge family.

-
-
-
-Churn rate -
-
-
-

!!! tip - Another factor to consider with very large node sizes is since CGROUPS do not hide the total number of vCPU from the containerized application. Dynamic runtimes can often spawn an unintentional number of OS threads, creating latency that is difficult to troubleshoot. For these application CPU pinning is recommend. For a deeper exploration of topic please see the following video https://www.youtube.com/watch?v=NqtfDy_KAqg

-
-
-
-

Node Bin-packing

-
-

Kubernetes vs. Linux Rules

-
-

There are two sets of rules we need to be mindful of when dealing with workloads on Kubernetes. The rules of the Kubernetes Scheduler, which uses the request value to schedule pods on a node, and then what happens after the pod is scheduled, which is the realm of Linux, not Kubernetes.

-
-
-

After Kubernetes scheduler is finished, a new set of rules takes over, the Linux Completely Fair Scheduler (CFS). The key take away is that Linux CFS doesn’t have a the concept of a core. We will discuss why thinking in cores can lead to major problems with optimizing workloads for scale.

-
-
-
-

Thinking in Cores

-
-

The confusion starts because the Kubernetes scheduler does have the concept of cores. From a Kubernetes scheduler perspective if we looked at a node with 4 NGINX pods, each with a request of one core set, the node would look like this.

-
-
-
-cores 1 -
-
-
-

However, let’s do a thought experiment on how different this looks from a Linux CFS perspective. The most important thing to remember when using the Linux CFS system is: busy containers (CGROUPS) are the only containers that count toward the share system. In this case, only the first container is busy so it is allowed to use all 4 cores on the node.

-
-
-
-cores 2 -
-
-
-

Why does this matter? Let’s say we ran our performance testing in a development cluster where an NGINX application was the only busy container on that node. When we move the app to production, the following would happen: the NGINX application wants 4 vCPU of resources however, because all the other pods on the node are busy, our app’s performance is constrained.

-
-
-
-cores 3 -
-
-
-

This situation would lead us to add more containers unnecessarily because we were not allowing our applications scale to their "`sweet spot"`. Let’s explore this important concept of a "sweet spot" in a bit more detail.

-
-
-
-

Application right sizing

-
-

Each application has a certain point where it can not take anymore traffic. Going above this point can increase processing times and even drop traffic when pushed well beyond this point. This is known as the application’s saturation point. To avoid scaling issues, we should attempt to scale the application before it reaches its saturation point. Let’s call this point the sweet spot.

-
-
-
-The sweet spot -
-
-
-

We need to test each of our applications to understand its sweet spot. There will be no universal guidance here as each application is different. During this testing we are trying to understand the best metric that shows our applications saturation point. Oftentimes, utilization metrics are used to indicate an application is saturated but this can quickly lead to scaling issues (We will explore this topic in detail in a later section). Once we have this "`sweet spot"` we can use it to efficiently scale our workloads.

-
-
-

Conversely, what would happen if we scale up well before the sweet spot and created unnecessary pods? Let’s explore that in the next section.

-
-
-
-

Pod sprawl

-
-

To see how creating unnecessary pods could quickly get out of hand, let’s look at the first example on the left. The correct vertical scale of this container takes up about two vCPUs worth of utilization when handling 100 requests a second. However, If we were to under-provision the requests value by setting requests to half a core, we would now need 4 pods for each one pods we actually needed. Exacerbating this problem further, if our HPA was set at the default of 50% CPU, those pods would scale half empty, creating an 8:1 ratio.

-
-
-
-scaling ratio -
-
-
-

Scaling this problem up we can quickly see how this can get out of hand. A deployment of ten pods whose sweet spot was set incorrectly could quickly spiral to 80 pods and the additional infrastructure needed to run them.

-
-
-
-bad sweetspot -
-
-
-

Now that we understand the impact of not allowing applications to operate in their sweet spot, let’s return to the node level and ask why this difference between the Kubernetes scheduler and Linux CFS so important?

-
-
-

When scaling up and down with HPA, we can have a scenario where we have a lot of space to allocate more pods. This would be a bad decision because the node depicted on the left is already at 100% CPU utilization. In a unrealistic but theoretically possible scenario, we could have the other extreme where our node is completely full, yet our CPU utilization is zero.

-
-
-
-hpa utilization -
-
-
-
-

Setting Requests

-
-

It would tempting to set the request at the “sweet spot” value for that application, however this would cause inefficiencies as pictured in the diagram below. Here we have set the request value to 2 vCPU, however the average utilization of these pods runs only 1 CPU most of the time. This setting would cause us to waste 50% of our CPU cycles, which would be unacceptable.

-
-
-
-requests 1 -
-
-
-

This bring us to the complex answer to problem. Container utilization cannot be thought of in a vacuum; one must take into account the other applications running on the node. In the following example containers that are bursty in nature are mixed in with two low CPU utilization containers that might be memory constrained. In this way we allow the containers to hit their sweet spot without taxing the node.

-
-
-
-requests 2 -
-
-
-

The important concept to take away from all this is that using Kubernetes scheduler concept of cores to understand Linux container performance can lead to poor decision making as they are not related.

-
-
-

!!! tip - Linux CFS has its strong points. This is especially true for I/O based workloads. However, if your application uses full cores without sidecars, and has no I/O requirements, CPU pinning can remove a great deal of complexity from this process and is encouraged with those caveats.

-
-
-
-
-

Utilization vs. Saturation

-
-

A common mistake in application scaling is only using CPU utilization for your scaling metric. In complex applications this is almost always a poor indicator that an application is actually saturated with requests. In the example on the left, we see all of our requests are actually hitting the web server, so CPU utilization is tracking well with saturation.

-
-
-

In real world applications, it’s likely that some of those requests will be getting serviced by a database layer or an authentication layer, etc. In this more common case, notice CPU is not tracking with saturation as the request is being serviced by other entities. In this case CPU is a very poor indicator for saturation.

-
-
-
-util vs saturation 1 -
-
-
-

Using the wrong metric in application performance is the number one reason for unnecessary and unpredictable scaling in Kubernetes. Great care must be taken in picking the correct saturation metric for the type of application that you’re using. It is important to note that there is not a one size fits all recommendation that can be given. Depending on the language used and the type of application in question, there is a diverse set of metrics for saturation.

-
-
-

We might think this problem is only with CPU Utilization, however other common metrics such as request per second can also fall into the exact same problem as discussed above. Notice the request can also go to DB layers, auth layers, not being directly serviced by our web server, thus it’s a poor metric for true saturation of the web server itself.

-
-
-
-util vs saturation 2 -
-
-
-

Unfortunately there are no easy answers when it comes to picking the right saturation metric. Here are some guidelines to take into consideration:

-
-
-
    -
  • -

    Understand your language runtime - languages with multiple OS threads will react differently than single threaded applications, thus impacting the node differently.

    -
  • -
  • -

    Understand the correct vertical scale - how much buffer do you want in your applications vertical scale before scaling a new pod?

    -
  • -
  • -

    What metrics truly reflect the saturation of your application - The saturation metric for a Kafka Producer would be quite different than a complex web application.

    -
  • -
  • -

    How do all the other applications on the node effect each other - Application performance is not done in a vacuum the other workloads on the node have a major impact.

    -
  • -
-
-
-

To close out this section, it would be easy to dismiss the above as overly complex and unnecessary. It can often be the case that we are experiencing an issue but we are unaware of the true nature of the problem because we are looking at the wrong metrics. In the next section we will look at how that could happen.

-
-
-

Node Saturation

-
-

Now that we have explored application saturation, let’s look at this same concept from a node point of view. Let’s take two CPUs that are 100% utilized to see the difference between utilization vs. saturation.

-
-
-

The vCPU on the left is 100% utilized, however no other tasks are waiting to run on this vCPU, so in a purely theoretical sense, this is quite efficient. Meanwhile, we have 20 single threaded applications waiting to get processed by a vCPU in the second example. All 20 applications now will experience some type of latency while they’re waiting their turn to be processed by the vCPU. In other words, the vCPU on the right is saturated.

-
-
-

Not only would we not see this problem if we where just looking at utilization, but we might attribute this latency to something unrelated such as networking which would lead us down the wrong path.

-
-
-
-node saturation -
-
-
-

It is important to view saturation metrics, not just utilization metrics when increasing the total number of pods running on a node at any given time as we can easily miss the fact we have over-saturated a node. For this task we can use pressure stall information metrics as seen in the below chart.

-
-
-

PromQL - Stalled I/O

-
-
-
-
topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100))
-
-
-
-
-stalled io -
-
-
-

!!! note - For more on Pressure stall metrics, see https://facebookmicrosites.github.io/psi/docs/overview*

-
-
-

With these metrics we can tell if threads are waiting on CPU, or even if every thread on the box is stalled waiting on resource like memory or I/O. For example, we could see what percentage every thread on the instance was stalled waiting on I/O over the period of 1 min.

-
-
-
-
topk(3, ((irate(node_pressure_io_stalled_seconds_total[1m])) * 100))
-
-
-
-

Using this metric, we can see in the above chart every thread on the box was stalled 45% of the time waiting on I/O at the high water mark, meaning we were throwing away all of those CPU cycles in that minute. Understanding that this is happening can help us reclaim a significant amount of vCPU time, thus making scaling more efficient.

-
-
-
-

HPA V2

-
-

It is recommended to use the autoscaling/v2 version of the HPA API. The older versions of the HPA API could get stuck scaling in certain edge cases. It was also limited to pods only doubling during each scaling step, which created issues for small deployments that needed to scale rapidly.

-
-
-

Autoscaling/v2 allows us more flexibility to include multiple criteria to scale on and allows us a great deal of flexibility when using custom and external metrics (non K8s metrics).

-
-
-

As an example, we can scaling on the highest of three values (see below). We scale if the average utilization of all the pods are over 50%, if custom metrics the packets per second of the ingress exceed an average of 1,000, or ingress object exceeds 10K request per second.

-
-
-

!!! note - This is just to show the flexibility of the auto-scaling API, we recommend against overly complex rules that can be difficult to troubleshoot in production.

-
-
-
-
apiVersion: autoscaling/v2
-kind: HorizontalPodAutoscaler
-metadata:
-  name: php-apache
-spec:
-  scaleTargetRef:
-    apiVersion: apps/v1
-    kind: Deployment
-    name: php-apache
-  minReplicas: 1
-  maxReplicas: 10
-  metrics:
-  - type: Resource
-    resource:
-      name: cpu
-      target:
-        type: Utilization
-        averageUtilization: 50
-  - type: Pods
-    pods:
-      metric:
-        name: packets-per-second
-      target:
-        type: AverageValue
-        averageValue: 1k
-  - type: Object
-    object:
-      metric:
-        name: requests-per-second
-      describedObject:
-        apiVersion: networking.k8s.io/v1
-        kind: Ingress
-        name: main-route
-      target:
-        type: Value
-        value: 10k
-
-
-
-

However, we learned the danger of using such metrics for complex web applications. In this case we would be better served by using custom or external metric that accurately reflects the saturation of our application vs. the utilization. HPAv2 allows for this by having the ability to scale according to any metric, however we still need to find and export that metric to Kubernetes for use.

-
-
-

For example, we can look at the active thread queue count in Apache. This often creates a “smoother” scaling profile (more on that term soon). If a thread is active, it doesn’t matter if that thread is waiting on a database layer or servicing a request locally, if all of the applications threads are being used, it’s a great indication that application is saturated.

-
-
-

We can use this thread exhaustion as a signal to create a new pod with a fully available thread pool. This also gives us control over how big a buffer we want in the application to absorb during times of heavy traffic. For example, if we had a total thread pool of 10, scaling at 4 threads used vs. 8 threads used would have a major impact on the buffer we have available when scaling the application. A setting of 4 would make sense for an application that needs to rapidly scale under heavy load, where a setting of 8 would be more efficient with our resources if we had plenty of time to scale due to the number of requests increasing slowly vs. sharply over time.

-
-
-
-thread pool -
-
-
-

What do we mean by the term “smooth” when it comes to scaling? Notice the below chart where we are using CPU as a metric. The pods in this deployment are spiking in a short period for from 50 pods, all the way up to 250 pods only to immediately scale down again. This is highly inefficient scaling is the leading cause on churn on clusters.

-
-
-
-spiky scaling -
-
-
-

Notice how after we change to a metric that reflects the correct sweet spot of our application (mid-part of chart), we are able to scale smoothly. Our scaling is now efficient, and our pods are allowed to fully scale with the headroom we provided by adjusting requests settings. Now a smaller group of pods are doing the work the hundreds of pods were doing before. Real world data shows that this is the number one factor in scalability of Kubernetes clusters.

-
-
-
-smooth scaling -
-
-
-

The key takeaway is CPU utilization is only one dimension of both application and node performance. Using CPU utilization as a sole health indicator for our nodes and applications creates problems in scaling, performance and cost which are all tightly linked concepts. The more performant the application and nodes are, the less that you need to scale, which in turn lowers your costs.

-
-
-

Finding and using the correct saturation metrics for scaling your particular application also allows you to monitor and alarm on the true bottlenecks for that application. If this critical step is skipped, reports of performance problems will be difficult, if not impossible, to understand.

-
-
-
-
-

Setting CPU Limits

-
-

To round out this section on misunderstood topics, we will cover CPU limits. In short, limits are metadata associated with the container that has a counter that resets every 100ms. This helps Linux keep track of how many CPU resources are used node-wide by a specific container in a 100ms period of time.

-
-
-
-CPU limits -
-
-
-

A common error with setting limits is assuming that the application is single threaded and only running on it’s "`assigned"` vCPU. In the above section we learned that CFS doesn’t assign cores, and in reality a container running large thread pools will schedule on all available vCPU’s on the box.

-
-
-

If 64 OS threads are running across 64 available cores (from a Linux node perspective) we will make the total bill of used CPU time in a 100ms period quite large after the time running on all of those 64 cores are added up. Since this might only occur during a garbage collection process it can be quite easy to miss something like this. This is why it is necessary to use metrics to ensure we have the correct usage over time before attempting to set a limit.

-
-
-

Fortunately, we have a way to see exactly how much vCPU is being used by all the threads in a application. We will use the metric container_cpu_usage_seconds_total for this purpose.

-
-
-

Since throttling logic happens every 100ms and this metric is a per second metric, we will PromQL to match this 100ms period. If you would like to dive deep into this PromQL statement work please see the following blog.

-
-
-

PromQL query:

-
-
-
-
topk(3, max by (pod, container)(rate(container_cpu_usage_seconds_total{image!="", instance="$instance"}[$__rate_interval]))) / 10
-
-
-
-
-cpu 1 -
-
-
-

Once we feel we have the right value, we can put the limit in production. It then becomes necessary to see if our application is being throttled due to something unexpected. We can do this by looking at container_cpu_throttled_seconds_total

-
-
-
-
topk(3, max by (pod, container)(rate(container_cpu_cfs_throttled_seconds_total{image!=``""``, instance=``"$instance"``}[$__rate_interval]))) / 10
-
-
-
-
-cpu 2 -
-
-
-

Memory

-
-

The memory allocation is another example where it is easy to confuse Kubernetes scheduling behavior for Linux CGroup behavior. This is a more nuanced topic as there have been major changes in the way that CGroup v2 handles memory in Linux and Kubernetes has changed its syntax to reflect this; read this blog for further details.

-
-
-

Unlike CPU requests, memory requests go unused after the scheduling process completes. This is because we can not compress memory in CGroup v1 the same way we can with CPU. That leaves us with just memory limits, which are designed to act as a fail safe for memory leaks by terminating the pod completely. This is an all or nothing style proposition, however we have now been given new ways to address this problem.

-
-
-

First, it is important to understand that setting the right amount of memory for containers is not a straightforward as it appears. The file system in Linux will use memory as a cache to improve performance. This cache will grow over time, and it can be hard to know how much memory is just nice to have for the cache but can be reclaimed without a significant impact to application performance. This often results in misinterpreting memory usage.

-
-
-

Having the ability to “compress” memory was one of the primary drivers behind CGroup v2. For more history on why CGroup V2 was necessary, please see Chris Down’s presentation at LISA21 where he covers why being unable to set the minimum memory correctly was one of the reasons that drove him to create CGroup v2 and pressure stall metrics.

-
-
-

Fortunately, Kubernetes now has the concept of memory.min and memory.high under requests.memory. This gives us the option of aggressive releasing this cached memory for other containers to use. Once the container hits the memory high limit, the kernel can aggressively reclaim that container’s memory up to the value set at memory.min. Thus giving us more flexibility when a node comes under memory pressure.

-
-
-

The key question becomes, what value to set memory.min to? This is where memory pressure stall metrics come into play. We can use these metrics to detect memory “thrashing” at a container level. Then we can use controllers such as fbtax to detect the correct values for memory.min by looking for this memory thrashing, and dynamically set the memory.min value to this setting.

-
-
-
-

Summary

-
-

To sum up the section, it is easy to conflate the following concepts:

-
-
-
    -
  • -

    Utilization and Saturation

    -
  • -
  • -

    Linux performance rules with Kubernetes Scheduler logic

    -
  • -
-
-
-

Great care must be taken to keep these concepts separated. Performance and scale are linked on a deep level. Unnecessary scaling creates performance problems, which in turn creates scaling problems.

-
-
-
-
-
-
-

Kubernetes Upstream SLOs

-
-
-

Amazon EKS runs the same code as the upstream Kubernetes releases and ensures that EKS clusters operate within the SLOs defined by the Kubernetes community. The Kuberneteshttps://github.com/kubernetes/community/tree/master/sig-scalability[Scalability Special Interest Group (SIG)] defines the scalability goals and investigates bottlenecks in performance through SLIs and SLOs.

-
-
-

SLIs are how we measure a system like metrics or measures that can be used to determine how “well” the system is running, e.g. request latency or count. SLOs define the values that are expected for when the system is running “well”, e.g. request latency remains less than 3 seconds. The Kubernetes SLOs and SLIs focus on the performance of the Kubernetes components and are completely independent from the Amazon EKS Service SLAs which focus on availability of the EKS cluster endpoint.

-
-
-

Kubernetes has a number of features that allow users to extend the system with custom add-ons or drivers, like CSI drivers, admission webhooks, and auto-scalers. These extensions can drastically impact the performance of a Kubernetes cluster in different ways, i.e. an admission webhook with failurePolicy=Ignore could add latency to K8s API requests if the webhook target is unavailable. The Kubernetes Scalability SIG defines scalability using a "you promise, we promise" framework:

-
-
-
-
-

If you promise to:
- - correctly configure your cluster
- - use extensibility features "reasonably"
- - keep the load in the cluster within recommended limits

-
-
-

then we promise that your cluster scales, i.e.:
- - all the SLOs are satisfied.

-
-
-
-
-

Kubernetes SLOs

-
-

The Kubernetes SLOs don’t account for all of the plugins and external limitations that could impact a cluster, such as worker node scaling or admission webhooks. These SLOs focus on Kubernetes components and ensure that Kubernetes actions and resources are operating within expectations. The SLOs help Kubernetes developers ensure that changes to Kubernetes code do not degrade performance for the entire system.

-
-
-

The Kuberntes Scalability SIG defines the following official SLO/SLIs. The Amazon EKS team regularly runs scalability tests on EKS clusters for these SLOs/SLIs to monitor for performance degradation as changes are made and new versions are released.

-
- ----- - - - - - - - - - - - - - - - - - - - - - - - - -
ObjectiveDefinitionSLO

API request latency (mutating)

Latency of processing mutating API calls for single objects for every (resource, verb) pair, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, for every (resource, verb) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day <= 1s

API request latency (read-only)

Latency of processing non-streaming read-only API calls for every (resource, scope) pair, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, for every (resource, scope) pair, excluding virtual and aggregated resources and Custom Resource Definitions, 99th percentile per cluster-day: (a) <= 1s if scope=resource (b) <= 30s otherwise (if scope=namespace or scope=cluster)

Pod startup latency

Startup latency of schedulable stateless pods, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch, measured as 99th percentile over last 5 minutes

In default Kubernetes installation, 99th percentile per cluster-day <= 5s

-
-

API Request Latency

-
-

The kube-apiserver has --request-timeout defined as 1m0s by default, which means a request can run for up to one minute (60 seconds) before being timed out and cancelled. The SLOs defined for Latency are broken out by the type of request that is being made, which can be mutating or read-only:

-
-
-
Mutating
-
-

Mutating requests in Kubernetes make changes to a resource, such as creations, deletions, or updates. These requests are expensive because those changes must be written to the etcd backend before the updated object is returned. Etcd is a distributed key-value store that is used for all Kubernetes cluster data.

-
-
-

This latency is measured as the 99th percentile over 5min for (resource, verb) pairs of Kubernetes resources, for example this would measure the latency for Create Pod requests and Update Node requests. The request latency must be <= 1 second to satisfy the SLO.

-
-
-
-
Read-only
-
-

Read-only requests retrieve a single resource (such as Get Pod X) or a collection (such as “Get all Pods from Namespace X”). The kube-apiserver maintains a cache of objects, so the requested resources may be returned from cache or they may need to be retrieved from etcd first. -These latencies are also measured by the 99th percentile over 5 minutes, however read-only requests can have separate scopes. The SLO defines two different objectives:

-
-
-
    -
  • -

    For requests made for a single resource (i.e. kubectl get pod -n mynamespace my-controller-xxx ), the request latency should remain <= 1 second.

    -
  • -
  • -

    For requests that are made for multiple resources in a namespace or a cluster (for example, kubectl get pods -A) the latency should remain <= 30 seconds

    -
  • -
-
-
-

The SLO has different target values for different request scopes because requests made for a list of Kubernetes resources expect the details of all objects in the request to be returned within the SLO. On large clusters, or large collections of resources, this can result in large response sizes which can take some time to return. For example, in a cluster running tens of thousands of Pods with each Pod being roughly 1 KiB when encoded in JSON, returning all Pods in the cluster would consist of 10MB or more. Kubernetes clients can help reduce this response size using APIListChunking to retrieve large collections of resources.

-
-
-
-
-

Pod Startup Latency

-
-

This SLO is primarily concerned with the time it takes from Pod creation to when the containers in that Pod actually begin execution. To measure this the difference from the creation timestamp recorded on the Pod, and when a WATCH on that Pod reports the containers have started is calculated (excluding time for container image pulls and init container execution). To satisfy the SLO the 99th percentile per cluster-day of this Pod Startup Latency must remain <=5 seconds.

-
-
-

Note that this SLO assumes that the worker nodes already exist in this cluster in a ready state for the Pod to be scheduled on. This SLO does not account for image pulls or init container executions, and also limits the test to “stateless pods” which don’t leverage persistent storage plugins.

-
-
-
-
-

Kubernetes SLI Metrics

-
-

Kubernetes is also improving the Observability around the SLIs by adding Prometheus metrics to Kubernetes components that track these SLIs over time. Using Prometheus Query Language (PromQL) we can build queries that display the SLI performance over time in tools like Prometheus or Grafana dashboards, below are some examples for the SLOs above.

-
-
-

API Server Request Latency

- ---- - - - - - - - - - - - - - - - - -
MetricDefinition

apiserver_request_sli_duration_seconds

Response latency distribution (not counting webhook duration and priority & fairness queue wait times) in seconds for each verb, group, version, resource, subresource, scope and component.

apiserver_request_duration_seconds

Response latency distribution in seconds for each verb, dry run value, group, version, resource, subresource, scope and component.

-
-

Note: The apiserver_request_sli_duration_seconds metric is available starting in Kubernetes 1.27.

-
-
-

You can use these metrics to investigate the API Server response times and if there are bottlenecks in the Kubernetes components or other plugins/components. The queries below are based on the community SLO dashboard.

-
-
-

API Request latency SLI (mutating) - this time does not include webhook execution or time waiting in queue.
-histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

-
-
-

API Request latency Total (mutating) - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and API Priority and Fairness wait times.
-histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"CREATE|DELETE|PATCH|POST|PUT", subresource!~"proxy|attach|log|exec|portforward"}[5m])) by (resource, subresource, verb, scope, le)) > 0

-
-
-

In these queries we are excluding the streaming API requests which do not return immediately, such as kubectl port-forward or kubectl exec requests (subresource!~"proxy|attach|log|exec|portforward"), and we are filtering for only the Kubernetes verbs that modify objects (verb=~"CREATE|DELETE|PATCH|POST|PUT"). We are then calculating the 99th percentile of that latency over the last 5 minutes.

-
-
-

We can use a similar query for the read only API requests, we simply modify the verbs we’re filtering for to include the Read only actions LIST and GET. There are also different SLO thresholds depending on the scope of the request, i.e. getting a single resource or listing a number of resources.

-
-
-

API Request latency SLI (read-only) - this time does not include webhook execution or time waiting in queue. -For a single resource (scope=resource, threshold=1s)
-histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

For a collection of resources in the same namespace (scope=namespace, threshold=5s)
-histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

For a collection of resources across the entire cluster (scope=cluster, threshold=30s)
-histogram_quantile(0.99, sum(rate(apiserver_request_sli_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

API Request latency Total (read-only) - this is the total time the request took on the API server, this time may be longer than the SLI time because it includes webhook execution and wait times. -For a single resource (scope=resource, threshold=1s)
-histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"GET", scope=~"resource"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

For a collection of resources in the same namespace (scope=namespace, threshold=5s)
-histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"namespace"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

For a collection of resources across the entire cluster (scope=cluster, threshold=30s)
-histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{verb=~"LIST", scope=~"cluster"}[5m])) by (resource, subresource, verb, scope, le))

-
-
-

The SLI metrics provide insight into how Kubernetes components are performing by excluding the time that requests spend waiting in API Priority and Fairness queues, working through admission webhooks, or other Kubernetes extensions. The total metrics provide a more holistic view as it reflects the time your applications would be waiting for a response from the API server. Comparing these metrics can provide insight into where the delays in request processing are being introduced.

-
-
-
-

Pod Startup Latency

- ---- - - - - - - - - - - - - - - - - -
MetricDefinition

kubelet_pod_start_sli_duration_seconds

Duration in seconds to start a pod, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch

kubelet_pod_start_duration_seconds

Duration in seconds from kubelet seeing a pod for the first time to the pod starting to run. This does not include the time to schedule the pod or scale out worker node capacity.

-
-

Note: kubelet_pod_start_sli_duration_seconds is available starting in Kubernetes 1.27.

-
-
-

Similar to the queries above you can use these metrics to gain insight into how long node scaling, image pulls and init containers are delaying the pod launch compared to Kubelet actions.

-
-
-

Pod startup latency SLI - this is the time from the pod being created to when the application containers reported as running. This includes the time it takes for the worker node capacity to be available and the pod to be scheduled, but this does not include the time it takes to pull images or for the init containers to run.
-histogram_quantile(0.99, sum(rate(kubelet_pod_start_sli_duration_seconds_bucket[5m])) by (le))

-
-
-

Pod startup latency Total - this is the time it takes the kubelet to start the pod for the first time. This is measured from when the kubelet recieves the pod via WATCH, which does not include the time for worker node scaling or scheduling. This includes the time to pull images and init containers to run.
-histogram_quantile(0.99, sum(rate(kubelet_pod_start_duration_seconds_bucket[5m])) by (le))

-
-
-
-
-

SLOs on Your Cluster

-
-

If you are collecting the Prometheus metrics from the Kubernetes resources in your EKS cluster you can gain deeper insights into the performance of the Kubernetes control plane components.

-
-
-

The perf-tests repo includes Grafana dashboards that display the latencies and critical performance metrics for the cluster during tests. The perf-tests configuration leverages the kube-prometheus-stack, an open source project that comes configured to collect Kubernetes metrics, but you can also use Amazon Managed Prometheus and Amazon Managed Grafana.

-
-
-

If you are using the kube-prometheus-stack or similar Prometheus solution you can install the same dashboard to observe the SLOs on your cluster in real time.

-
-
-
    -
  1. -

    You will first need to install the Prometheus Rules that are used in the dashboards with kubectl apply -f prometheus-rules.yaml. You can download a copy of the rules here: https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/pkg/prometheus/manifests/prometheus-rules.yaml

    -
    -
      -
    1. -

      Be sure to check the namespace in the file matches your environment

      -
    2. -
    3. -

      Verify that the labels match the prometheus.prometheusSpec.ruleSelector helm value if you are using kube-prometheus-stack

      -
    4. -
    -
    -
  2. -
  3. -

    You can then install the dashboards in Grafana. The json dashboards and python scripts to generate them are available here: https://github.com/kubernetes/perf-tests/tree/master/clusterloader2/pkg/prometheus/manifests/dashboards

    -
    -
      -
    1. -

      the slo.json dashboard displays the performance of the cluster in relation to the Kubernetes SLOs

      -
    2. -
    -
    -
  4. -
-
-
-

Consider that the SLOs are focused on the performance of the Kubernetes components in your clusters, but there are additional metrics you can review which provide different perspectives or insights in to your cluster. Kubernetes community projects like Kube-state-metrics can help you quickly analyze trends in your cluster. Most common plugins and drivers from the Kubernetes community also emit Prometheus metrics, allowing you to investigate things like autoscalers or custom schedulers.

-
-
-

The Observability Best Practices Guide has examples of other Kubernetes metrics you can use to gain further insight.

-
-
-
-
-
-

Known Limits and Service Quotas

-
-
-

Amazon EKS can be used for a variety of workloads and can interact with a wide range of AWS services, and we have seen customer workloads encounter a similar range of AWS service quotas and other issues that hamper scalability.

-
-
-

Your AWS account has default quotas (an upper limit on the number of each AWS resource your team can request). Each AWS service defines their own quota, and quotas are generally region-specific. You can request increases for some quotas (soft limits), and other quotas cannot be increased (hard limits). You should consider these values when architecting your applications. Consider reviewing these service limits periodically and incorporate them during in your application design.

-
-
-

You can review the usage in your account and open a quota increase request at the AWS Service Quotas console, or using the AWS CLI. Refer to the AWS documentation from the respective AWS Service for more details on the Service Quotas and any further restrictions or notices on their increase.

-
-
-

!!! note - Amazon EKS Service Quotas lists the service quotas and has links to request increases where available.

-
-
-

Other AWS Service Quotas

-
-

We have seen EKS customers impacted by the quotas listed below for other AWS services. Some of these may only apply to specific use cases or configurations, however you may consider if your solution will encounter any of these as it scales. The Quotas are organized by Service and each Quota has an ID in the format of L-XXXXXXXX you can use to look it up in the AWS Service Quotas console

-
- ------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ServiceQuota (L-xxxxx)ImpactID (L-xxxxx)default

IAM

Roles per account

Can limit the number of clusters or IRSA roles in an account.

L-FE177D64

1,000

IAM

OpenId connect providers per account

Can limit the number of Clusters per account, OpenID Connect is used by IRSA

L-858F3967

100

IAM

Role trust policy length

Can limit the number of of clusters an IAM role is associated with for IRSA

L-C07B4B0D

2,048

VPC

Security groups per network interface

Can limit the control or connectivity of the networking for your cluster

L-2AFB9258

5

VPC

IPv4 CIDR blocks per VPC

Can limit the number of EKS Worker Nodes

L-83CA0A9D

5

VPC

Routes per route table

Can limit the control or connectivity of the networking for your cluster

L-93826ACB

50

VPC

Active VPC peering connections per VPC

Can limit the control or connectivity of the networking for your cluster

L-7E9ECCDB

50

VPC

Inbound or outbound rules per security group.

Can limit the control or connectivity of the networking for your cluster, some controllers in EKS create new rules

L-0EA8095F

50

VPC

VPCs per Region

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-F678F1CE

5

VPC

Internet gateways per Region

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-A4707A72

5

VPC

Network interfaces per Region

Can limit the number of EKS Worker nodes, or Impact EKS control plane scaling/update activities.

L-DF5E4CA3

5,000

VPC

Network Address Usage

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-BB24F6E5

64,000

VPC

Peered Network Address Usage

Can limit the number of Clusters per account or the control or connectivity of the networking for your cluster

L-CD17FD4B

128,000

ELB

Listeners per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-57A373D6

50

ELB

Target Groups per Region

Can limit the control of traffic ingress to the cluster.

L-B22855CB

3,000

ELB

Targets per Application Load Balancer

Can limit the control of traffic ingress to the cluster.

L-7E6692B2

1,000

ELB

Targets per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-EEF1AD04

3,000

ELB

Targets per Availability Zone per Network Load Balancer

Can limit the control of traffic ingress to the cluster.

L-B211E961

500

ELB

Targets per Target Group per Region

Can limit the control of traffic ingress to the cluster.

L-A0D0B863

1,000

ELB

Application Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-53DA6B97

50

ELB

Classic Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-E9E9831D

20

ELB

Network Load Balancers per Region

Can limit the control of traffic ingress to the cluster.

L-69A177A2

50

EC2

Running On-Demand Standard (A, C, D, H, I, M, R, T, Z) instances (as a maximum vCPU count)

Can limit the number of EKS Worker Nodes

L-1216C47A

5

EC2

All Standard (A, C, D, H, I, M, R, T, Z) Spot Instance Requests (as a maximum vCPU count)

Can limit the number of EKS Worker Nodes

L-34B43A08

5

EC2

EC2-VPC Elastic IPs

Can limit the number of NAT GWs (and thus VPCs), which may limit the number of clusters in a region

L-0263D0A3

5

EBS

Snapshots per Region

Can limit the backup strategy for stateful workloads

L-309BACF6

100,000

EBS

Storage for General Purpose SSD (gp3) volumes, in TiB

Can limit the number of EKS Worker Nodes, or PersistentVolume storage

L-7A658B76

50

EBS

Storage for General Purpose SSD (gp2) volumes, in TiB

Can limit the number of EKS Worker Nodes, or PersistentVolume storage

L-D18FCD1D

50

ECR

Registered repositories

Can limit the number of workloads in your clusters

L-CFEB8E8D

10,000

ECR

Images per repository

Can limit the number of workloads in your clusters

L-03A36CE1

10,000

SecretsManager

Secrets per Region

Can limit the number of workloads in your clusters

L-2F66C23C

500,000

-
-
-

AWS Request Throttling

-
-

AWS services also implement request throttling to ensure that they remain performant and available for all customers. Simliar to Service Quotas, each AWS service maintains their own request throttling thresholds. Consider reviewing the respective AWS Service documentation if your workloads will need to quickly issue a large number of API calls or if you notice request throttling errors in your application.

-
-
-

EC2 API requests around provisioning EC2 network interfaces or IP addresses can encounter request throttling in large clusters or when clusters scale drastically. The table below shows some of the API actions that we have seen customers encounter request throttling from. -You can review the EC2 rate limit defaults and the steps to request a rate limit increase in the EC2 documentation on Rate Throttling.

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Mutating ActionsRead-only Actions

AssignPrivateIpAddresses

DescribeDhcpOptions

AttachNetworkInterface

DescribeInstances

CreateNetworkInterface

DescribeNetworkInterfaces

DeleteNetworkInterface

DescribeSecurityGroups

DeleteTags

DescribeTags

DetachNetworkInterface

DescribeVpcs

ModifyNetworkInterfaceAttribute

DescribeVolumes

UnassignPrivateIpAddresses

-
-
-

Other Known Limits

-
- -
-
-
-
-
- - - \ No newline at end of file diff --git a/latest/bpg/scalability/quotas.adoc b/latest/bpg/scalability/quotas.adoc index 3ca148bfd..9cd12c456 100644 --- a/latest/bpg/scalability/quotas.adoc +++ b/latest/bpg/scalability/quotas.adoc @@ -240,7 +240,7 @@ You can review the EC2 rate limit defaults and the steps to request a rate limit == Other Known Limits -* Route 53 DNS resolvers are limited to https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-limits[1024 Packets per second]. This limit can be encountered when DNS traffic from a large cluster is funneled through a small number of CoreDNS Pod replicas. link:../cluster-services/#scale-coredns[Scaling CoreDNS and optimizing DNS behavior] can avoid timeouts on DNS lookups. +// * Route 53 DNS resolvers are limited to https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-limits[1024 Packets per second]. This limit can be encountered when DNS traffic from a large cluster is funneled through a small number of CoreDNS Pod replicas. xref:scale-coredns[Scaling CoreDNS and optimizing DNS behavior] can avoid timeouts on DNS lookups. ** https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests[Route 53 also has a fairly low rate limit of 5 requests per second to the Route 53 API]. If you have a large number of domains to update with a project like External DNS you may see rate throttling and delays in updating domains. * Some https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html#instance-type-volume-limits[Nitro instance types have a volume attachment limit of 28] that is shared between Amazon EBS volumes, network interfaces, and NVMe instance store volumes. If your workloads are mounting numerous EBS volumes you may encounter limits to the pod density you can achieve with these instance types * There is a maximum number of connections that can be tracked per Ec2 instance. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html#connection-tracking-throttling[If your workloads are handling a large number of connections you may see communication failures or errors because this maximum has been hit.] You can use the `conntrack_allowance_available` and `conntrack_allowance_exceeded` https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html[network performance metrics to monitor the number of tracked connections on your EKS worker nodes]. diff --git a/latest/bpg/scalability/workloads.adoc b/latest/bpg/scalability/workloads.adoc index e577f8db4..7936d21fa 100644 --- a/latest/bpg/scalability/workloads.adoc +++ b/latest/bpg/scalability/workloads.adoc @@ -1,3 +1,4 @@ +[#workloads] = Workloads Workloads have an impact on how large your cluster can scale. Workloads that use the Kubernetes APIs heavily will limit the total amount of workloads you can have in a single cluster, but there are some defaults you can change to help reduce the load. diff --git a/latest/bpg/security/hosts.adoc b/latest/bpg/security/hosts.adoc index f648f16e9..12825179f 100644 --- a/latest/bpg/security/hosts.adoc +++ b/latest/bpg/security/hosts.adoc @@ -12,7 +12,7 @@ Inasmuch as it's important to secure your container images, it's equally important to safeguard the infrastructure that runs them. This section explores different ways to mitigate risks from attacks launched directly against the host. These guidelines should be used in conjunction with -those outlined in the link:runtime.md[Runtime Security] section. +those outlined in the xref:runtime-security[Runtime Security] section. == Recommendations @@ -339,7 +339,7 @@ We have implemented https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These AMIs were developed to demonstrate sample implementations that meet -requirements of highly regulated customers, such as STIG, CJIS, and C2S. +requirements of highly regulated customers. !!! caution SELinux will ignore containers where the type is unconfined. diff --git a/latest/bpg/security/hosts.adoc.backup b/latest/bpg/security/hosts.adoc.backup deleted file mode 100644 index 248970c4f..000000000 --- a/latest/bpg/security/hosts.adoc.backup +++ /dev/null @@ -1,366 +0,0 @@ -//!!NODE_ROOT
-[."topic"] -[[protecting-the-infrastructure-(hosts),protecting-the-infrastructure-(hosts).title]] -= Protecting the infrastructure (hosts) -:info_doctype: section -:info_title: Protecting the infrastructure (hosts) -:info_abstract: Protecting the infrastructure (hosts) -:info_titleabbrev: Protecting the infrastructure (hosts) -:imagesdir: images/ - -Inasmuch as it’s important to secure your container images, it’s equally -important to safeguard the infrastructure that runs them. This section -explores different ways to mitigate risks from attacks launched directly -against the host. These guidelines should be used in conjunction with -those outlined in the link:runtime.md[Runtime Security] section. - -== Recommendations - -=== Use an OS optimized for running containers - -Consider using Flatcar Linux, Project Atomic, RancherOS, and -https://github.com/bottlerocket-os/bottlerocket/[Bottlerocket], a -special purpose OS from AWS designed for running Linux containers. It -includes a reduced attack surface, a disk image that is verified on -boot, and enforced permission boundaries using SELinux. - -Alternately, use the -https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html[EKS -optimized AMI] for your Kubernetes worker nodes. The EKS optimized AMI -is released regularly and contains a minimal set of OS packages and -binaries necessary to run your containerized workloads. - -Please refer https://github.com/aws-samples/amazon-eks-ami-rhel[Amazon -EKS AMI RHEL Build Specification] for a sample configuration script -which can be used for building a custom Amazon EKS AMI running on Red -Hat Enterprise Linux using Hashicorp Packer. This script can be further -leveraged to build STIG compliant EKS custom AMIs. - -=== Keep your worker node OS updated - -Regardless of whether you use a container-optimized host OS like -Bottlerocket or a larger, but still minimalist, Amazon Machine Image -like the EKS optimized AMIs, it is best practice to keep these host OS -images up to date with the latest security patches. - -For the EKS optimized AMIs, regularly check the -https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md[CHANGELOG] -and/or https://github.com/awslabs/amazon-eks-ami/releases[release notes -channel] and automate the rollout of updated worker node images into -your cluster. - -=== Treat your infrastructure as immutable and automate the replacement of your worker nodes - -Rather than performing in-place upgrades, replace your workers when a -new patch or update becomes available. This can be approached a couple -of ways. You can either add instances to an existing autoscaling group -using the latest AMI as you sequentially cordon and drain nodes until -all of the nodes in the group have been replaced with the latest AMI. -Alternatively, you can add instances to a new node group while you -sequentially cordon and drain nodes from the old node group until all of -the nodes have been replaced. EKS -https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html[managed -node groups] uses the first approach and will display a message in the -console to upgrade your workers when a new AMI becomes available. -`eksctl` also has a mechanism for creating node groups with the latest -AMI and for gracefully cordoning and draining pods from nodes groups -before the instances are terminated. If you decide to use a different -method for replacing your worker nodes, it is strongly recommended that -you automate the process to minimize human oversight as you will likely -need to replace workers regularly as new updates/patches are released -and when the control plane is upgraded. - -With EKS Fargate, AWS will automatically update the underlying -infrastructure as updates become available. Oftentimes this can be done -seamlessly, but there may be times when an update will cause your pod to -be rescheduled. Hence, we recommend that you create deployments with -multiple replicas when running your application as a Fargate pod. - -=== Periodically run kube-bench to verify compliance with https://www.cisecurity.org/benchmark/kubernetes/[CIS benchmarks for Kubernetes] - -kube-bench is an open source project from Aqua that evaluates your -cluster against the CIS benchmarks for Kubernetes. The benchmark -describes the best practices for securing unmanaged Kubernetes clusters. -The CIS Kubernetes Benchmark encompasses the control plane and the data -plane. Since Amazon EKS provides a fully managed control plane, not all -of the recommendations from the CIS Kubernetes Benchmark are applicable. -To ensure this scope reflects how Amazon EKS is implemented, AWS created -the _CIS Amazon EKS Benchmark_. The EKS benchmark inherits from CIS -Kubernetes Benchmark with additional inputs from the community with -specific configuration considerations for EKS clusters. - -When running https://github.com/aquasecurity/kube-bench[kube-bench] -against an EKS cluster, follow -https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster[these -instructions] from Aqua Security. For further information see -https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/[Introducing -The CIS Amazon EKS Benchmark]. - -=== Minimize access to worker nodes - -Instead of enabling SSH access, use -https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html[SSM -Session Manager] when you need to remote into a host. Unlike SSH keys -which can be lost, copied, or shared, Session Manager allows you to -control access to EC2 instances using IAM. Moreover, it provides an -audit trail and log of the commands that were run on the instance. - -As of August 19th, 2020 Managed Node Groups support custom AMIs and EC2 -Launch Templates. This allows you to embed the SSM agent into the AMI or -install it as the worker node is being bootstrapped. If you rather not -modify the Optimized AMI or the ASG’s launch template, you can install -the SSM agent with a DaemonSet as in -https://github.com/aws-samples/ssm-agent-daemonset-installer[this -example]. - -==== Minimal IAM policy for SSM based SSH Access - -The `AmazonSSMManagedInstanceCore` AWS managed policy contains a -number of permissions that are not required for SSM Session Manager / -SSM RunCommand if you’re just looking to avoid SSH access. Of concern -specifically is the `*` permissions for `ssm:GetParameter(s)` which -would allow for the role to access all parameters in Parameter Store -(including SecureStrings with the AWS managed KMS key configured). - -The following IAM policy contains the minimal set of permissions to -enable node access via SSM Systems Manager. - -[source,json] ----- -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "EnableAccessViaSSMSessionManager", - "Effect": "Allow", - "Action": [ - "ssmmessages:OpenDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:CreateControlChannel", - "ssm:UpdateInstanceInformation" - ], - "Resource": "*" - }, - { - "Sid": "EnableSSMRunCommand", - "Effect": "Allow", - "Action": [ - "ssm:UpdateInstanceInformation", - "ec2messages:SendReply", - "ec2messages:GetMessages", - "ec2messages:GetEndpoint", - "ec2messages:FailMessage", - "ec2messages:DeleteMessage", - "ec2messages:AcknowledgeMessage" - ], - "Resource": "*" - } - ] -} ----- - -With this policy in place and the -https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html[Session -Manager plugin] installed, you can then run - -[source,bash] ----- -aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE] ----- - -to access the node. - -!!! note You may also want to consider adding permissions to -https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging[enable -Session Manager logging]. - -=== Deploy workers onto private subnets - -By deploying workers onto private subnets, you minimize their exposure -to the Internet where attacks often originate. Beginning April 22, 2020, -the assignment of public IP addresses to nodes in a managed node groups -will be controlled by the subnet they are deployed onto. Prior to this, -nodes in a Managed Node Group were automatically assigned a public IP. -If you choose to deploy your worker nodes on to public subnets, -implement restrictive AWS security group rules to limit their exposure. - -=== Run Amazon Inspector to assess hosts for exposure, vulnerabilities, and deviations from best practices - -You can use -https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html[Amazon -Inspector] to check for unintended network access to your nodes and for -vulnerabilities on the underlying Amazon EC2 instances. - -Amazon Inspector can provide common vulnerabilities and exposures (CVE) -data for your Amazon EC2 instances only if the Amazon EC2 Systems -Manager (SSM) agent is installed and enabled. This agent is preinstalled -on several -https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html[Amazon -Machine Images (AMIs)] including -https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html[EKS -optimized Amazon Linux AMIs]. Regardless of SSM agent status, all of -your Amazon EC2 instances are scanned for network reachability issues. -For more information about configuring scans for Amazon EC2, see -https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html[Scanning -Amazon EC2 instances]. - -!!! attention Inspector cannot be run on the infrastructure used to run -Fargate pods. - -== Alternatives - -// [[iam-se-linux,iam-se-linux.title]] -// === Run SELinux - -// !!! info Available on Red Hat Enterprise Linux (RHEL), CentOS, -// Bottlerocket, and Amazon Linux 2023 - -// SELinux provides an additional layer of security to keep containers -// isolated from each other and from the host. SELinux allows -// administrators to enforce mandatory access controls (MAC) for every -// user, application, process, and file. Think of it as a backstop that -// restricts the operations that can be performed against to specific -// resources based on a set of labels. On EKS, SELinux can be used to -// prevent containers from accessing each other’s resources. - -// Container SELinux policies are defined in the -// https://github.com/containers/container-selinux[container-selinux] -// package. Docker CE requires this package (along with its dependencies) -// so that the processes and files created by Docker (or other container -// runtimes) run with limited system access. Containers leverage the -// `container_t` label which is an alias to `svirt_lxc_net_t`. These -// policies effectively prevent containers from accessing certain features -// of the host. - -// When you configure SELinux for Docker, Docker automatically labels -// workloads `container_t` as a type and gives each container a unique -// MCS level. This will isolate containers from one another. If you need -// looser restrictions, you can create your own profile in SElinux which -// grants a container permissions to specific areas of the file system. -// This is similar to PSPs in that you can create different profiles for -// different containers/pods. For example, you can have a profile for -// general workloads with a set of restrictive controls and another for -// things that require privileged access. - -// SELinux for Containers has a set of options that can be configured to -// modify the default restrictions. The following SELinux Booleans can be -// enabled or disabled based on your needs: - -// [width="100%",cols="30%,^40%,30%",options="header",] -// |=== -// |Boolean |Default |Description -// |`container_connect_any` |`off` |Allow containers to access -// privileged ports on the host. For example, if you have a container that -// needs to map ports to 443 or 80 on the host. - -// |`container_manage_cgroup` |`off` |Allow containers to manage cgroup -// configuration. For example, a container running systemd will need this -// to be enabled. - -// |`container_use_cephfs` |`off` |Allow containers to use a ceph file -// system. -// |=== - -// By default, containers are allowed to read/execute under `/usr` and -// read most content from `/etc`. The files under `/var/lib/docker` and -// `/var/lib/containers` have the label `container_var_lib_t`. To view -// a full list of default, labels see the -// https://github.com/containers/container-selinux/blob/master/container.fc[container.fc] -// file. - -// [source,bash] -// ---- -// docker container run -it \ -// -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \ -// centos:7 cat /host/repositories.json -// # cat: /host/repositories.json: Permission denied - -// docker container run -it \ -// -v /etc/passwd:/host/etc/passwd \ -// centos:7 cat /host/etc/passwd -// # cat: /host/etc/passwd: Permission denied -// ---- - -// Files labeled with `container_file_t` are the only files that are -// writable by containers. If you want a volume mount to be writeable, you -// will needed to specify `:z` or `:Z` at the end. - -// * `:z` will re-label the files so that the container can read/write -// * `:Z` will re-label the files so that *only* the container can -// read/write - -// [source,bash] -// ---- -// ls -Z /var/lib/misc -// # -rw-r--r--. root root system_u:object_r:var_lib_t:s0 postfix.aliasesdb-stamp - -// docker container run -it \ -// -v /var/lib/misc:/host/var/lib/misc:z \ -// centos:7 echo "Relabeled!" - -// ls -Z /var/lib/misc -// #-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp -// ---- - -// [source,bash] -// ---- -// docker container run -it \ -// -v /var/log:/host/var/log:Z \ -// fluentbit:latest -// ---- - -// In Kubernetes, relabeling is slightly different. Rather than having -// Docker automatically relabel the files, you can specify a custom MCS -// label to run the pod. Volumes that support relabeling will automatically -// be relabeled so that they are accessible. Pods with a matching MCS label -// will be able to access the volume. If you need strict isolation, set a -// different MCS label for each pod. - -// [source,yaml] -// ---- -// securityContext: -// seLinuxOptions: -// # Provide a unique MCS label per container -// # You can specify user, role, and type also -// # enforcement based on type and level (svert) -// level: s0:c144:c154 -// ---- - -// In this example `s0:c144:c154` corresponds to an MCS label assigned to -// a file that the container is allowed to access. - -// On EKS you could create policies that allow for privileged containers to -// run, like FluentD and create an SELinux policy to allow it to read from -// /var/log on the host without needing to relabel the host directory. Pods -// with the same label will be able to access the same host volumes. - -// We have implemented -// https://github.com/aws-samples/amazon-eks-custom-amis[sample AMIs for -// Amazon EKS] that have SELinux configured on CentOS 7 and RHEL 7. These -// AMIs were developed to demonstrate sample implementations that meet -// requirements of highly regulated customers, such as STIG, CJIS, and C2S. - -// !!! caution SELinux will ignore containers where the type is unconfined. - -== Tools and resources - -* https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/[SELinux -Kubernetes RBAC and Shipping Security Policies for On-prem Applications] -* https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html[Iterative -Hardening of Kubernetes] -* https://linux.die.net/man/1/audit2allow[Audit2Allow] -* https://linux.die.net/man/8/sealert[SEAlert] -* https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica[Generate -SELinux policies for containers with Udica] describes a tool that looks -at container spec files for Linux capabilities, ports, and mount points, -and generates a set of SELinux rules that allow the container to run -properly -* https://github.com/aws-samples/amazon-eks-custom-amis#hardening[AMI -Hardening] playbooks for hardening the OS to meet different regulatory -requirements -* https://github.com/keikoproj/upgrade-manager[Keiko Upgrade Manager] an -open source project from Intuit that orchestrates the rotation of worker -nodes. -* https://sysdig.com/products/kubernetes-security/[Sysdig Secure] -* https://eksctl.io/[eksctl] diff --git a/latest/bpg/security/iam.adoc b/latest/bpg/security/iam.adoc index 38022aec5..f0fdcb9a3 100644 --- a/latest/bpg/security/iam.adoc +++ b/latest/bpg/security/iam.adoc @@ -141,11 +141,9 @@ cluster. authorization for an Access Entry to perform actions in the Amazon EKS cluster. -____ At launch Amazon EKS supports only predefined and AWS managed policies. Access policies are not IAM entities and are defined and managed by Amazon EKS. -____ Cluster Access Manager allows the combination of upstream RBAC with Access Policies supporting allow and pass (but not deny) on Kubernetes @@ -242,11 +240,9 @@ $ aws eks list-access-entries --cluster-name } ---- -____ No Access Entries are available when the cluster is created without the cluster creator admin permission, which is the only entry created by default. -____ === The `aws-auth` ConfigMap _(deprecated)_ @@ -302,12 +298,10 @@ group/groups add, using the following format * *username:* The username within Kubernetes to map to the AWS IAM role. This can be any custom name. -____ It is also possible to map permissions for AWS IAM Users, defining a new configuration block for `mapUsers`, under `data` in the `aws-auth` ConfigMap, replacing the *rolearn* parameter for *userarn*, however as a *Best Practice* it's always recommended to user `mapRoles` instead. -____ To manage permissions, you can edit the `aws-auth` ConfigMap adding or removing access to your Amazon EKS cluster. Although it's possible to @@ -406,10 +400,8 @@ $ aws eks delete-access-entry --cluster-name \ --principal-arn ---- -____ This access can be granted again if needed during an incident, emergency or break glass scenario where the cluster is otherwise inaccessible. -____ If the cluster still configured with the `CONFIG_MAP` authentication method, all additional users should be granted access to the cluster From e4e75ded7f93a411d23e0a5dd46b0860047b4891 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 28 Aug 2024 04:00:38 +0000 Subject: [PATCH 30/56] fixup --- latest/bpg/scalability/cluster-services.adoc | 4 +++- latest/bpg/scalability/control-plane.adoc | 4 +++- latest/bpg/scalability/data-plane.adoc | 4 +++- latest/bpg/scalability/index.adoc | 1 + latest/bpg/scalability/kcp_monitoring.adoc | 2 ++ latest/bpg/scalability/kubernetes_slos.adoc | 2 ++ latest/bpg/scalability/node_efficiency.adoc | 2 ++ latest/bpg/scalability/quotas.adoc | 2 ++ latest/bpg/scalability/scaling_theory.adoc | 2 ++ latest/bpg/scalability/workloads.adoc | 4 +++- 10 files changed, 23 insertions(+), 4 deletions(-) diff --git a/latest/bpg/scalability/cluster-services.adoc b/latest/bpg/scalability/cluster-services.adoc index 25b11b2df..7190d9925 100644 --- a/latest/bpg/scalability/cluster-services.adoc +++ b/latest/bpg/scalability/cluster-services.adoc @@ -1,5 +1,7 @@ -[#cluster-services] +[."topic"] +[#scale-cluster-services] = Cluster Services +:info_doctype: section Cluster services run inside an EKS cluster, but they are not user workloads. If you have a Linux server you often need to run services like NTP, syslog, and a container runtime to support your workloads. Cluster services are similar, supporting services that help you automate and operate your cluster. In Kubernetes these are usually run in the kube-system namespace and some are run as https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/[DaemonSets]. diff --git a/latest/bpg/scalability/control-plane.adoc b/latest/bpg/scalability/control-plane.adoc index 01405d5fd..ffcb6b1b5 100644 --- a/latest/bpg/scalability/control-plane.adoc +++ b/latest/bpg/scalability/control-plane.adoc @@ -1,5 +1,7 @@ -[#control-plane] +[."topic"] +[#scale-control-plane] = Kubernetes Control Plane +:info_doctype: section The Kubernetes control plane consists of the Kubernetes API Server, Kubernetes Controller Manager, Scheduler and other components that are required for Kubernetes to function. Scalability limits of these components are different depending on what you're running in the cluster, but the areas with the biggest impact to scaling include the Kubernetes version, utilization, and individual Node scaling. diff --git a/latest/bpg/scalability/data-plane.adoc b/latest/bpg/scalability/data-plane.adoc index f3a0bcfc8..c0422f329 100644 --- a/latest/bpg/scalability/data-plane.adoc +++ b/latest/bpg/scalability/data-plane.adoc @@ -1,5 +1,7 @@ -[#data-plane] +[."topic"] +[#scale-data-plane] = Kubernetes Data Plane +:info_doctype: section // The Kubernetes Data Plane includes EC2 instances, load balancers, storage, and other APIs used by the Kubernetes Control Plane. For organization purposes we grouped xref:cluster-services[cluster services] in a separate page and load balancer scaling can be found in the xref:workloads[workloads section]. This section will focus on scaling compute resources. diff --git a/latest/bpg/scalability/index.adoc b/latest/bpg/scalability/index.adoc index 8d8334482..9cea5a6af 100644 --- a/latest/bpg/scalability/index.adoc +++ b/latest/bpg/scalability/index.adoc @@ -1,3 +1,4 @@ +[."topic"] = EKS Scalability best practices This guide provides advice for scaling EKS clusters. The goal of scaling an EKS cluster is to maximize the amount of work a single cluster can perform. Using a single, large EKS cluster can reduce operational load compared to using multiple clusters, but it has trade-offs for things like multi-region deployments, tenant isolation, and cluster upgrades. In this document we will focus on how to achieve maximum scalability with a single cluster. diff --git a/latest/bpg/scalability/kcp_monitoring.adoc b/latest/bpg/scalability/kcp_monitoring.adoc index 6e5d42fb7..ca1958322 100644 --- a/latest/bpg/scalability/kcp_monitoring.adoc +++ b/latest/bpg/scalability/kcp_monitoring.adoc @@ -1,4 +1,6 @@ +[."topic"] = Control Plane Monitoring +:info_doctype: section :authors: ["Shane Corbett"] :date: 2023-09-22 diff --git a/latest/bpg/scalability/kubernetes_slos.adoc b/latest/bpg/scalability/kubernetes_slos.adoc index be831a4cb..d6b8a1603 100644 --- a/latest/bpg/scalability/kubernetes_slos.adoc +++ b/latest/bpg/scalability/kubernetes_slos.adoc @@ -1,4 +1,6 @@ +[."topic"] = Kubernetes Upstream SLOs +:info_doctype: section Amazon EKS runs the same code as the upstream Kubernetes releases and ensures that EKS clusters operate within the SLOs defined by the Kubernetes community. The Kuberneteshttps://github.com/kubernetes/community/tree/master/sig-scalability[Scalability Special Interest Group (SIG)] defines the scalability goals and investigates bottlenecks in performance through SLIs and SLOs. diff --git a/latest/bpg/scalability/node_efficiency.adoc b/latest/bpg/scalability/node_efficiency.adoc index 6ba5d1fb1..cf7f973c3 100644 --- a/latest/bpg/scalability/node_efficiency.adoc +++ b/latest/bpg/scalability/node_efficiency.adoc @@ -1,4 +1,6 @@ +[."topic"] = Node and Workload Efficiency +:info_doctype: section :authors: ["Shane Corbett"] :date: 2023-09-22 diff --git a/latest/bpg/scalability/quotas.adoc b/latest/bpg/scalability/quotas.adoc index 9cd12c456..1d4d9691b 100644 --- a/latest/bpg/scalability/quotas.adoc +++ b/latest/bpg/scalability/quotas.adoc @@ -1,4 +1,6 @@ +[."topic"] = Known Limits and Service Quotas +:info_doctype: section Amazon EKS can be used for a variety of workloads and can interact with a wide range of AWS services, and we have seen customer workloads encounter a similar range of AWS service quotas and other issues that hamper scalability. diff --git a/latest/bpg/scalability/scaling_theory.adoc b/latest/bpg/scalability/scaling_theory.adoc index d166cbcb2..4a01b7e8f 100644 --- a/latest/bpg/scalability/scaling_theory.adoc +++ b/latest/bpg/scalability/scaling_theory.adoc @@ -1,4 +1,6 @@ +[."topic"] = Kubernetes Scaling Theory +:info_doctype: section :authors: ["Shane Corbett"] :date: 2023-09-22 diff --git a/latest/bpg/scalability/workloads.adoc b/latest/bpg/scalability/workloads.adoc index 7936d21fa..64b3a677d 100644 --- a/latest/bpg/scalability/workloads.adoc +++ b/latest/bpg/scalability/workloads.adoc @@ -1,5 +1,7 @@ -[#workloads] +[."topic"] +[scale-workloads] = Workloads +:info_doctype: section Workloads have an impact on how large your cluster can scale. Workloads that use the Kubernetes APIs heavily will limit the total amount of workloads you can have in a single cluster, but there are some defaults you can change to help reduce the load. From e3fb0a0929826ac3d5c6f9abdeac4a02b58e5477 Mon Sep 17 00:00:00 2001 From: Geoffrey Cline Date: Wed, 28 Aug 2024 04:03:58 +0000 Subject: [PATCH 31/56] start windows --- latest/bpg/windows/ami.md | 78 +++++++ latest/bpg/windows/gmsa.md | 48 ++++ latest/bpg/windows/hardening.md | 80 +++++++ latest/bpg/windows/images.md | 15 ++ .../windows/images/associated-components.png | Bin 0 -> 118652 bytes .../bpg/windows/images/build-components.png | Bin 0 -> 123894 bytes latest/bpg/windows/images/domainless_gmsa.png | Bin 0 -> 128741 bytes latest/bpg/windows/images/dsr.png | Bin 0 -> 44872 bytes latest/bpg/windows/images/ecr-image.png | Bin 0 -> 44578 bytes latest/bpg/windows/images/images.png | Bin 0 -> 261500 bytes latest/bpg/windows/images/inspector-agent.png | Bin 0 -> 101506 bytes .../windows/images/permissions-policies.png | Bin 0 -> 35753 bytes latest/bpg/windows/images/prom.png | Bin 0 -> 34260 bytes .../windows/images/selected-components.png | Bin 0 -> 98587 bytes .../bpg/windows/images/windows-networking.png | Bin 0 -> 45040 bytes latest/bpg/windows/licensing.md | 12 + latest/bpg/windows/logging.md | 37 ++++ latest/bpg/windows/monitoring.md | 132 +++++++++++ latest/bpg/windows/networking.md | 82 +++++++ latest/bpg/windows/oom.md | 42 ++++ latest/bpg/windows/patching.md | 55 +++++ latest/bpg/windows/scheduling.md | 158 +++++++++++++ latest/bpg/windows/security.md | 82 +++++++ latest/bpg/windows/storage.md | 209 ++++++++++++++++++ 24 files changed, 1030 insertions(+) create mode 100644 latest/bpg/windows/ami.md create mode 100644 latest/bpg/windows/gmsa.md create mode 100644 latest/bpg/windows/hardening.md create mode 100644 latest/bpg/windows/images.md create mode 100644 latest/bpg/windows/images/associated-components.png create mode 100644 latest/bpg/windows/images/build-components.png create mode 100644 latest/bpg/windows/images/domainless_gmsa.png create mode 100644 latest/bpg/windows/images/dsr.png create mode 100644 latest/bpg/windows/images/ecr-image.png create mode 100644 latest/bpg/windows/images/images.png create mode 100644 latest/bpg/windows/images/inspector-agent.png create mode 100644 latest/bpg/windows/images/permissions-policies.png create mode 100644 latest/bpg/windows/images/prom.png create mode 100644 latest/bpg/windows/images/selected-components.png create mode 100644 latest/bpg/windows/images/windows-networking.png create mode 100644 latest/bpg/windows/licensing.md create mode 100644 latest/bpg/windows/logging.md create mode 100644 latest/bpg/windows/monitoring.md create mode 100644 latest/bpg/windows/networking.md create mode 100644 latest/bpg/windows/oom.md create mode 100644 latest/bpg/windows/patching.md create mode 100644 latest/bpg/windows/scheduling.md create mode 100644 latest/bpg/windows/security.md create mode 100644 latest/bpg/windows/storage.md diff --git a/latest/bpg/windows/ami.md b/latest/bpg/windows/ami.md new file mode 100644 index 000000000..1d075b96a --- /dev/null +++ b/latest/bpg/windows/ami.md @@ -0,0 +1,78 @@ +# Amazon EKS optimized Windows AMI management +Windows Amazon EKS optimized AMIs are built on top of Windows Server 2019 and Windows Server 2022. They are configured to serve as the base image for Amazon EKS nodes. By default, the AMIs include the following components: +- [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) +- [kube-proxy](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/) +- [AWS IAM Authenticator for Kubernetes](https://github.com/kubernetes-sigs/aws-iam-authenticator) +- [csi-proxy](https://github.com/kubernetes-csi/csi-proxy) +- [containerd](https://containerd.io/) + +You can programmatically retrieve the Amazon Machine Image (AMI) ID for Amazon EKS optimized AMIs by querying the AWS Systems Manager Parameter Store API. This parameter eliminates the need for you to manually look up Amazon EKS optimized AMI IDs. For more information about the Systems Manager Parameter Store API, see [GetParameter](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameter.html). Your user account must have the ssm:GetParameter IAM permission to retrieve the Amazon EKS optimized AMI metadata. + +The following example retrieves the AMI ID for the latest Amazon EKS optimized AMI for Windows Server 2019 LTSC Core. The version number listed in the AMI name relates to the corresponding Kubernetes build it is prepared for. + +```bash +aws ssm get-parameter --name /aws/service/ami-windows-latest/Windows_Server-2019-English-Core-EKS_Optimized-1.21/image_id --region us-east-1 --query "Parameter.Value" --output text +``` + +Example output: + +``` +ami-09770b3eec4552d4e +``` + +## Managing your own Amazon EKS optimized Windows AMI + +An essential step towards production environments is maintaining the same Amazon EKS optimized Windows AMI and kubelet version across the Amazon EKS cluster. + +Using the same version across the Amazon EKS cluster reduces the time during troubleshooting and increases cluster consistency. [Amazon EC2 Image Builder](https://aws.amazon.com/image-builder/) helps create and maintain custom Amazon EKS optimized Windows AMIs to be used across an Amazon EKS cluster. + +Use Amazon EC2 Image Builder to select between Windows Server versions, AWS Windows Server AMI release dates, and/or OS build version. The build components step, allows you to select between existing EKS Optimized Windows Artifacts as well as the kubelet versions. For more information: https://docs.aws.amazon.com/eks/latest/userguide/eks-custom-ami-windows.html + +![](./images/build-components.png) + +**NOTE:** Prior to selecting a base image, consult the [Windows Server Version and License](licensing.md) section for important details pertaining to release channel updates. + +## Configuring faster launching for custom EKS optimized AMIs ## + +When using a custom Windows Amazon EKS optimized AMI, Windows worker nodes can be launched up to 65% faster by enabling the Fast Launch feature. This feature maintains a set of pre-provisioned snapshots which have the _Sysprep specialize_, _Windows Out of Box Experience (OOBE)_ steps and required reboots already completed. These snapshots are then used on subsequent launches, reducing the time to scale-out or replace nodes. Fast Launch can be only enabled for AMIs *you own* through the EC2 console or in the AWS CLI and the number of snapshots maintained is configurable. + +**NOTE:** Fast Launch is not compatible with the default Amazon-provided EKS optimized AMI, create a custom AMI as above before attempting to enable it. + +For more information: [AWS Windows AMIs - Configure your AMI for faster launching](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/windows-ami-version-history.html#win-ami-config-fast-launch) + +## Caching Windows base layers on custom AMIs ## + +Windows container images are larger than their Linux counterparts. If you are running any containerized .NET Framework-based application, the average image size is around 8.24GB. During pod scheduling, the container image must be fully pulled and extracted in the disk before the pod reaches Running status. + +During this process, the container runtime (containerd) pulls and extracts the entire container image in the disk. The pull operation is a parallel process, meaning the container runtime pulls the container image layers in parallel. In contrast, the extraction operation occurs in a sequential process, and it is I/O intensive. Due to that, the container image can take more than 8 minutes to be fully extracted and ready to be used by the container runtime (containerd), and as a result, the pod startup time can take several minutes. + +As mentioned in the **Patching Windows Server and Container** topic, there is an option to build a custom AMI with EKS. During the AMI preparation, you can add an additional EC2 Image builder component to pull all the necessary Windows container images locally and then generate the AMI. This strategy will drastically reduce the time a pod reaches the status **Running**. + +On Amazon EC2 Image Builder, create a [component](https://docs.aws.amazon.com/imagebuilder/latest/userguide/manage-components.html) to download the necessary images and attach it to the Image recipe. The following example pulls a specific image from a ECR repository. + +``` +name: ContainerdPull +description: This component pulls the necessary containers images for a cache strategy. +schemaVersion: 1.0 + +phases: + - name: build + steps: + - name: containerdpull + action: ExecutePowerShell + inputs: + commands: + - Set-ExecutionPolicy Unrestricted -Force + - (Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin 111000111000.dkr.ecr.us-east-1.amazonaws.com + - ctr image pull mcr.microsoft.com/dotnet/framework/aspnet:latest + - ctr image pull 111000111000.dkr.ecr.us-east-1.amazonaws.com/myappcontainerimage:latest +``` + +To make sure the following component works as expected, check if the IAM role used by EC2 Image builder (EC2InstanceProfileForImageBuilder) has the attached policies: + +![](./images/permissions-policies.png) + +## Blog post ## +In the following blog post, you will find a step by step on how to implement caching strategy for custom Amazon EKS Windows AMIs: + +[Speeding up Windows container launch times with EC2 Image builder and image cache strategy](https://aws.amazon.com/blogs/containers/speeding-up-windows-container-launch-times-with-ec2-image-builder-and-image-cache-strategy/) diff --git a/latest/bpg/windows/gmsa.md b/latest/bpg/windows/gmsa.md new file mode 100644 index 000000000..e9a942efc --- /dev/null +++ b/latest/bpg/windows/gmsa.md @@ -0,0 +1,48 @@ +# Configure gMSA for Windows Pods and containers + +## What is a gMSA account + +Windows-based applications such as .NET applications often use Active Directory as an identity provider, providing authorization/authentication using NTLM or Kerberos protocol. + +An application server to exchange Kerberos tickets with Active Directory requires to be domain-joined. Windows containers don’t support domain joins and would not make much sense as containers are ephemeral resources, creating a burden on the Active Directory RID pool. + +However, administrators can leverage [gMSA Active Directory](https://docs.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview) accounts to negotiate a Windows authentication for resources such as Windows containers, NLB, and server farms. + +## Windows container and gMSA use case + +Applications that leverage on Windows authentication, and run as Windows containers, benefit from gMSA because the Windows Node is used to exchange the Kerberos ticket on behalf of the container.There are two options available to setup the Windows worker node to support gMSA integration: + +#### 1 - Domain-joined Windows worker nodes +In this setup, the Windows worker node is domain-joined in the Active Directory domain, and the AD Computer account of the Windows worker nodes is used to authenticate against Active Directory and retrieve the gMSA identity to be used with the pod. + +In the domain-joined approach, you can easily manage and harden your Windows worker nodes using existing Active Directory GPOs; however, it generates additional operational overhead and delays during Windows worker node joining in the Kubernetes cluster, as it requires additional reboots during node startup and Active Directory garage cleaning after the Kubernetes cluster terminates nodes. + +In the following blog post, you will find a detailed step-by-step on how to implement the Domain-joined Windows worker node approach: + +[Windows Authentication on Amazon EKS Windows pods](https://aws.amazon.com/blogs/containers/windows-authentication-on-amazon-eks-windows-pods/) + + +#### 2 - Domainless Windows worker nodes +In this setup, the Windows worker node isn't joined in the Active Directory domain, and a "portable" identity (user/password) is used to authenticate against Active Directory and retrieve the gMSA identity to be used with the pod. + +![](./images/domainless_gmsa.png) + +The portable identity is an Active Directory user; the identity (user/password) is stored on AWS Secrets Manager or AWS System Manager Parameter Store, and an AWS-developed plugin called ccg_plugin will be used to retrieve this identity from AWS Secrets Manager or AWS System Manager Parameter Store and pass it to containerd to retrieve the gMSA identity and made it available for the pod. + +In this domainless approach, you can benefit from not having any Active Directory interaction during Windows worker node startup when using gMSA and reducing the operational overhead for Active Directory administrators. + +In the following blog post, you will find a detailed step-by-step on how to implement the Domainless Windows worker node approach: + +[Domainless Windows Authentication for Amazon EKS Windows pods](https://aws.amazon.com/blogs/containers/domainless-windows-authentication-for-amazon-eks-windows-pods/) + +#### Important note + +Despite the pod being able to use a gMSA account, it is necessary to also setup the application or service accordingly to support Windows authentication, for instance, in order to setup Microsoft IIS to support Windows authentication, you should prepared it via dockerfile: + + +```dockerfile +RUN Install-WindowsFeature -Name Web-Windows-Auth -IncludeAllSubFeature +RUN Import-Module WebAdministration; Set-ItemProperty 'IIS:\AppPools\SiteName' -name processModel.identityType -value 2 +RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/anonymousAuthentication' -Name Enabled -Value False -PSPath 'IIS:\' -Location 'SiteName' +RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/windowsAuthentication' -Name Enabled -Value True -PSPath 'IIS:\' -Location 'SiteName' +``` \ No newline at end of file diff --git a/latest/bpg/windows/hardening.md b/latest/bpg/windows/hardening.md new file mode 100644 index 000000000..bfa6462f0 --- /dev/null +++ b/latest/bpg/windows/hardening.md @@ -0,0 +1,80 @@ +# Windows worker nodes hardening + +OS Hardening is a combination of OS configuration, patching, and removing unnecessary software packages, which aim to lock down a system and reduce the attack surface. It is a best practice to prepare your own EKS Optimized Windows AMI with the hardening configurations required by your company. + +AWS provides a new EKS Optimized Windows AMI every month containing the latest Windows Server Security Patches. However, it is still the user's responsibility to harden their AMI by applying the necessary OS configurations regardless of whether they use self-managed or managed node groups. + +Microsoft offers a range of tools like [Microsoft Security Compliance Toolkit](https://www.microsoft.com/en-us/download/details.aspx?id=55319) and [Security Baselines](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-security-baselines) that helps you to achieve hardening based on your security policies needs. [CIS Benchmarks](https://learn.cisecurity.org/benchmarks?_gl=1*eoog69*_ga*MTgzOTM2NDE0My4xNzA0NDgwNTcy*_ga_3FW1B1JC98*MTcwNDQ4MDU3MS4xLjAuMTcwNDQ4MDU3MS4wLjAuMA..*_ga_N70Z2MKMD7*MTcwNDQ4MDU3MS4xLjAuMTcwNDQ4MDU3MS42MC4wLjA.) are also available and should be implemented on top of an Amazon EKS Optimized Windows AMI for production environments. + +## Reducing attack surface with Windows Server Core + +Windows Server Core is a minimal installation option that is available as part of the [EKS Optimized Windows AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-windows-ami.html). Deploying Windows Server Core has a couple of benefits. First, it has a relatively small disk footprint, being 6GB on Server Core against 10GB on Windows Server with Desktop experience. Second, it has a smaller attack surface because of its smaller code base and available APIs. + +AWS provides customers with new Amazon EKS Optimized Windows AMIs every month, containing the latest Microsoft security patches, regardless of the Amazon EKS-supported version. As a best practice, Windows worker nodes must be replaced with new ones based on the latest Amazon EKS-optimized AMI. Any node running for more than 45 days without an update in place or node replacement lacks security best practices. + +## Avoiding RDP connections + +Remote Desktop Protocol (RDP) is a connection protocol developed by Microsoft to provide users with a graphical interface to connect to another Windows computer over a network. + +As a best practice, you should treat your Windows worker nodes as if they were ephemeral hosts. That means no management connections, no updates, and no troubleshooting. Any modification and update should be implemented as a new custom AMI and replaced by updating an Auto Scaling group. See **Patching Windows Servers and Containers** and **Amazon EKS optimized Windows AMI management**. + +Disable RDP connections on Windows nodes during the deployment by passing the value **false** on the ssh property, as the example below: + +```yaml +nodeGroups: +- name: windows-ng + instanceType: c5.xlarge + minSize: 1 + volumeSize: 50 + amiFamily: WindowsServer2019CoreContainer + ssh: + allow: false +``` + +If access to the Windows node is needed, use [AWS System Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) to establish a secure PowerShell session through the AWS Console and SSM agent. To see how to implement the solution watch [Securely Access Windows Instances Using AWS Systems Manager Session Manager](https://www.youtube.com/watch?v=nt6NTWQ-h6o) + +In order to use System Manager Session Manager an additional IAM policy must be applied to the IAM role used to launch the Windows worker node. Below is an example where the **AmazonSSMManagedInstanceCore** is specified in the `eksctl` cluster manifest: + +```yaml + nodeGroups: +- name: windows-ng + instanceType: c5.xlarge + minSize: 1 + volumeSize: 50 + amiFamily: WindowsServer2019CoreContainer + ssh: + allow: false + iam: + attachPolicyARNs: + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + - arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore +``` + +## Amazon Inspector +> [Amazon Inspector](https://aws.amazon.com/inspector/) is an automated security assessment service that helps improve the security and compliance of applications deployed on AWS. Amazon Inspector automatically assesses applications for exposure, vulnerabilities, and deviations from best practices. After performing an assessment, Amazon Inspector produces a detailed list of security findings prioritized by level of severity. These findings can be reviewed directly or as part of detailed assessment reports which are available via the Amazon Inspector console or API. + +Amazon Inspector can be used to run CIS Benchmark assessment on the Windows worker node and it can be installed on a Windows Server Core by performing the following tasks: + +1. Download the following .exe file: +https://inspector-agent.amazonaws.com/windows/installer/latest/AWSAgentInstall.exe +2. Transfer the agent to the Windows worker node. +3. Run the following command on PowerShell to install the Amazon Inspector Agent: `.\AWSAgentInstall.exe /install` + +Below is the ouput after the first run. As you can see, it generated findings based on the [CVE](https://cve.mitre.org/) database. You can use this to harden your Worker nodes or create an AMI based on the hardened configurations. + +![](./images/inspector-agent.png) + +For more information on Amazon Inspector, including how to install Amazon Inspector agents, set up the CIS Benchmark assessment, and generate reports, watch the [Improving the security and compliance of Windows Workloads with Amazon Inspector](https://www.youtube.com/watch?v=nIcwiJ85EKU) video. + +## Amazon GuardDuty +> [Amazon GuardDuty](https://aws.amazon.com/guardduty/) is a threat detection service that continuously monitors for malicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data stored in Amazon S3. With the cloud, the collection and aggregation of account and network activities is simplified, but it can be time consuming for security teams to continuously analyze event log data for potential threats. + +By using Amazon GuardDuty you have visilitiby on malicious actitivy against Windows worker nodes, like RDP brute force and Port Probe attacks. + +Watch the [Threat Detection for Windows Workloads using Amazon GuardDuty](https://www.youtube.com/watch?v=ozEML585apQ) video to learn how to implement and run CIS Benchmarks on Optimized EKS Windows AMI + +## Security in Amazon EC2 for Windows +Read up on the [Security best practices for Amazon EC2 Windows instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-security.html) to implement security controls at every layer. diff --git a/latest/bpg/windows/images.md b/latest/bpg/windows/images.md new file mode 100644 index 000000000..f19ef5903 --- /dev/null +++ b/latest/bpg/windows/images.md @@ -0,0 +1,15 @@ +# Container image scanning + +Image Scanning is an automated vulnerability assessment feature that helps improve the security of your application’s container images by scanning them for a broad range of operating system vulnerabilities. + +Currently, the Amazon Elastic Container Registry (ECR) is only able to scan Linux container image for vulnerabilities. However; there are third-party tools which can be integrated with an existing CI/CD pipeline for Windows container image scanning. + +* [Anchore](https://anchore.com/blog/scanning-windows-container-images/) +* [PaloAlto Prisma Cloud ](https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/vulnerability_management/windows_image_scanning.html) +* [Trend Micro - Deep Security Smart Check](https://www.trendmicro.com/en_us/business/products/hybrid-cloud/smart-check-image-scanning.html) + +To learn more about how to integrate these solutions with Amazon Elastic Container Repository (ECR), check: + +* [Anchore, scanning images on Amazon Elastic Container Registry (ECR)](https://anchore.com/blog/scanning-images-on-amazon-elastic-container-registry/) +* [PaloAlto, scanning images on Amazon Elastic Container Registry (ECR)](https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/vulnerability_management/registry_scanning0/scan_ecr.html) +* [TrendMicro, scanning images on Amazon Elastic Container Registry (ECR)](https://cloudone.trendmicro.com/docs/container-security/sc-about/) diff --git a/latest/bpg/windows/images/associated-components.png b/latest/bpg/windows/images/associated-components.png new file mode 100644 index 0000000000000000000000000000000000000000..26a2fffb9fcdab631a39e4005bec74a729a2cd1f GIT binary patch literal 118652 zcmeFZcUaTQ*9VAzpdx~zq9BM3MVgd=bPz!i0tf=qi?k$!Aiam8q7>;Zk)lB8AiV}e zdI>F|g%YGg=)Gs-y}xqH`+9eu-M@Ah9>_PDGwqa_b3St>AJkQ!(4S#BLqS17uk`e> z1_cEzBL&3?#3>r`C;U|He8zYo?hfwz6D=Vcw}8l;?G2kh8%Y`-OZhJl6|O2<_k6hTlsvrplyqXEc*^g~1sa;BiyZnD)u|K>%M^tQfj%E8 z3uk=>=NY$Y7$r`Bm!{Nax-fOtoIp`{GD7HrujPXpibAJ|um)`Spt^^gPjh2m^OGC6 zmXYp}w>}O^w0ANu-QmEC)g~9-6Ou}KTzCG;v&=JzZmsU(XB24^-<>_1{2(CX*pup7 zOt9ItQw5X)G&IV|^>NI%8X{7!Tq&g*pxKDmQML~Ju0tFTM=>++gA^=1|{o6AI1t~rL>I6 zRR4ZHf%r)%rzx+bM1IwLWp80&>tGFYbdNe9_dqEPdhycnB~V5D6%5K}Y7R5A;B$rA z{j5SE=_*csgjzV7a=1cmY#qd1rEdO4Ax?h&`7!@Zj^9WeAyPMA0@XR>VfGdr06t;9 z2REh9aBy%)+M8R7Ydlu`S9S6`shif0j&|bw{4Opod@e$KFncS00WmQ#{s)5mf`Ytc z3SI{{TSrq@UR#G-zc=#lb{<!1sXvf2!sPvix7F{Ve&t+Hdpvy*tUDjfrbHSlG+Mpim22N9q4E zSMs->{#5wiasFOW9pq|Z^YSr>T+@L(CuxC)4<7!j+Fy(Q$Ev#jttu?=;Ey%`Q1XYG zKj$E>W)C6{)buA4r3EDU|MuCx=q34oa`+D%|6QEFeM*+6^chM1|LBJF8GeySvNp<6 zC_R>Y;d)|m^rYv-=HYK^w0>0{b^#OG2FmE-V%)SbER);GgQz+>`qn+%tZ{Tys*cUC zW~0MG1lewAf0~&kg0Om{tV}|p>R=R&9`26#q0nB{E$k&y`2NoTw~EGaaLB$65e+mH9P;Z=YtARVg$% z^((f?Qutoum!;^rMp=8fUnL9~(iV3i-oaXRv_;T1rnYLP0*60t!wGbJoe{*AXE%Py zkWagm&DUfPJysbr^=k`u;Nz^YB)j{t>a9GRp=t$f9^)HHUdIaW`bpn>sS2UPA_t`I z&-GXD-ztgUUK!?RotRi8?UwK23I%!TPA?7>4M^}6c7qG<|7w=9FMVH~<2YWO?O?90f9YhYhXZL4W(7_%`QLUg!;liMP{Be?)gQdIW9hk`F^6hCMsA1Py(uc#-v@hudnQcwW$~;ok5ItLXb$9h;WDIUpvk z=U?8$KA~;;n8bli$AoERYby`gTcpYz?b|oar$0-Sq!wbow%)AZWqoaYQzGt z;eZYo#{^#D9u#znhYaKu)g#KBm-L)nSH{qS-rsM>%fNkYM#`T%FOFCYY*8}VIJ%v? zF3qDH!xwv1C~{x*+R@5O-74FJhK8x|qE5-tm^Apr#N>1mT(RZ5LeTVhoxesiPx^|R zSE_kygb};wYS(JGAgI^8s3Sq6OclzdllKXEaV<(N$GNb>tsO?)uO^>|nt&R)dRj%s2&GxoCA6gYSMyelc&lr|PAg-;?d2g}_%Yz+ zW#pPd(8ch)(aNXI+joO#qDi}xYP!X)9~!1QdA&Nt^bx`!n^~+3z9W0z8jPR1-O9#v z%b%7ZvN4ERIjt=^6%wnu9ryLB-|^$ZF8}t>kdWvb@&T=%DjX~hw%P2#D@MJUuV{;4 zW)abeVPPh0Gpqr*`lWgSnyT}6wupUe>nB;SNjs|3FdQ}Gr@NAj_dj`|gu%G(8A2_* zwj*Asi@iC|$JqM_b51)$T@GIYeHCzPPo;d%P2pDt|1m(8kLjTpqUYpR)tpAW38f8U z%xe}{v4+xLw3`=9v)GS19WhKDX22o_E;e{Q4OoU24sb;_1=46G!hcw}ZREN{0I{Oc z*)L)~OezkqNdRS+K2|L&Ki_zMw?ETRf6V(J#9Zz=efNm>tdz(VE4tOAz4-uG8W5>% zzrkD9zEVp9rH{C*jM@`Yu$ZOB7XA8Tz|E+8)E!McC9;&kH zv_8ep(uO!-S4W4fpMe z+QS(P5@|9XbFtkT;^!jcO)B9Yqfvw{z>!N-Sl0N5s~uRiw&_?yGr}G{&T4V6fU9(? zQvw!QwOkI&tNL7fI{4gazRsEzTt%ekQRCeUtyVY9PXs^yl>h~wb8vl+?R-l%r6D?Y zu#XyqG@p&)MV7s%`D)OMH*^{EO7h@lc?h=Gc-5m9Br@G*;s5Y>+|-|DE6o<|J|<~9 zK5u1w>Z&Aep5;{4aT8L(-wshM@_Ab>9kBN(?begfH!Mpb!&R^((H!E0A4q(?sH^rO zy()R8g-t1fGl%4&x_tARK99HS23G-fYz-!TtJ%F$ph9uRU2e7 zG$8R2ItFe|E#se&njyIRFILqztg*#vM+65xk3t=0$xRRIcgEg(eYUSw_q|E=q0Yv) zxf`lq*VT{PCweR^^dNlr(yWrI+%}z>&T7i{QQz|)coG`0MHC&(S+Mgzy`B5A=6lV+ zxQnKyP=6Zjb@vw&6B8r)D_UN~gs$S^)_xyMTW|(Qi`#h+Fwgg zf+iAFavv>)_M|;wcYBIby$Wl;wy|QTNz9K&UR>X*XBZOz94WRfL@O^=cEkhv`t2R# znUN?t{)*j4x&=1R3&$rIP|nDYSQ5g>_v}t8m@7T&hI8+}19?fbh^h<1H}Z z;q{SV!hDT!sZB*}7rpf=^f2yu>9qtks%$>5)gR5y56}lAnEZUbW2+=@>$W7mA}h{( z0Wr(Phe)l^OUx}ey|;P}+o8tr2>pFp@MkbeDKZ^jeJq1-p1oenP&k~`ZU;&LozbCc zU#XFL5bvw%(%itz3BR3mT8A_LSF-)KcCp2dg3NF#IVr;-O_gtInk$;_c%7q-VOVWE z!Y5$SV`);IN*7VwWH?}pR-v!Sx2g3^Q;sd198MbPuUSZfA7AC0-Kl!~?kuY(@-EA}edO?$d%@Di1T!opAzKr00NP z*|7I1x=Z)X%gPi(7M$@TZW~M4$6`Z+JIj6bdSiA+PGhcYaiTD}!kv9Zsv4~e5M-&! zS-*u{&%JeI%{`(X)6%V8V~LgSA5kSzbeH&e3beB4a-3^OM=NI}a^RPd-ZuehE=j}j z7f9B7qg75N!@14s+1g6YE$1~Qv?2+gZH5Hbv0b%zuOi6Ka)X8nPzl>*X_uv&@@}dA z`3{^JdplExP4LJJd_73OE#l+pgk|#I!Pmg9vMb&BW6DMvYR!=BenoNev- z)qJm-sKHM2520hPcUxp@-|ip#(ncU2^syK-$gIZ+!-f=#VY0wzZk-77_@9x-UmV{G z$w$k%C)mF$%ellINhyZ!NTo410QVPvV2!f)fO*cRpZJ29YxI6b9ewrt*$xrkT6W7l zCt}j=QIEv?cLC5l#_^nrSmYt*jr8`erv1R^4xTjGq_!H^2J?%D^yh4h5q;?LI9adO zA<6x^R}^y%s<&R97uI3Y2-)A}WKOSSf+QD3_%4Qt!_Qq+yL&nrKkJ zt<%9wQCH1s6U0QgB=tmHaB8tM(^alWw_k+?zOODlHBz|$z1N$46H@pIR(oVyxU-Dm zh*X1=g2c4;*gZB<3~Tf%RZmYNrapRexm ziN%A@l#MDdg$Q?TFAZ-sDi6EdMi1zDHgki3YOw|(eVfY;qVUvwZ(3-~3&>@fbnRS9 zAciJXrhkXLqd^03+=lg1>J(j>cmI?zPfOHsw1WJIhWms6#TW zcCWGnA)wGHO;mv$hJE(+-gA6RcJy15lWHPO6U#yLNGaY9t4 z(h;sNuK7ao)v;A_d=R-6 z@)Aoe5~_ok(GOLmXT>-E)DsuOqvogeH1rya%%eKFdZkZc1vfUXKeXd$bRE?Jd2woV zG@SZXFv`Jnve%I6b?2vwFLe^Jis!E1C$C%1FsO_-5OHUVX?NCGKGk9N-1?0E%CjSP zr?kX9<3?c}y#lk7u*5fSsIS5ha%>iUp7aX?MQ(wY`EE7_UQ&)pcf+De)nu6;R!{YE zPiJN4MLkbZZ1+1!hptAuJC@atRyxPH5WEQIy5a=nJ0BK>T0i)z5-(V2J})SC(1A@; zO~8+N9{bXN09r4Ur=V&jbLq>$TP*RCZhK4KYXV&|X<5iW{wm)dS1DIxoF&8ITp(^V@qJD2+^osw(6lNC1K=M-(F zcnx!3?LugfTDqM1Q-&nF6OZY^6;8)PxN;mRGc9tswAA+@Cgn(U z0S;u|lv3L#c=~(pZHbC}E5E^~x=*mLN|+%ztc5U`m>1G*=u{#vBpc*xx87Vqj}#GJAwVd9UYr% z%}IgBJL$HgmCtJF_VLdZ0xzo$NbkflwSHy4g?8VHGOed9F-dY=pTAgC0vYC%Kk>LE zTeGT^{sQDP!E+T>%bY5t-CJBOIPL;?{rDxB zMq%uH?_j}Xs>x?Rk&L;fiUG2Ew*>J^LXezLT)8i3qBsjVh3}IQM9JYru%S0vbl{d>n=W`-L+s?-`X1!CKc$P5uEm?#PDQaxO zYV5Ul62kOJ3Bq1ufk2>ztq=S+(q_F95m9c;=4W9sc&#&6^ zGk#_EsJWfsMs%7dkebF9x6#Y>XD;1;_vvzLi|CkZA5FoL8)P7h%c3ntX+!8oQh@2N z)}wLP(^G<&0Cp)Oy5T~LY*3y;SV{Uh6sJed(I_Fd8C4Ea_IRg z#}P6~BHWd>qwczB%aEx1T6)6wBJYNL(=+g_w!xRT;t)KyrrTrHE~l=?E?qaOa!$yV zL&>F9T6)Rn2FZ|aU^l0mLRixbDhiFdu`-4SZw$!(>LMOJOe6OSBl0eLy3C0vGF0G@ z{yHOK#{Q^%mEpRy=irsx60hglc`u$ni@NtC$tJ)lK_}KtgZ|>*j_4WMiWFLx*iWcivJ}vX72axH9d#r_kGQ&)0~X=eO&#Zl-WVQ z+6>JhzEMlhEQuJ4$zS;qKe0Uy02w09oPR+7Pe321EE7u1CZMR|SLXC{Bj%K)Z@@Xm z{R$Z)Hz9kDiNhzZ-uWT&mop&~g2}+9Cf1bYS7=6lUj!f7tN-17YS*WD^+h z%LtJ?kEsV_#{8e0Foghs4fSh$lOwF2`V_~^SGLZXo4=GcM;L+(4FCTO{F|EnUtpkY zB98MNqLfeC2-RiGQMI#74~T#Lrv_zTPzPS*yUoiY9Mv}6u8<~qM((dLjBg8dFPkiG z+!Tod-Y$Lgwk1ZE?@!Ac2Nfk`V#0iVafq5x$fTL)PaTjo=vt6$CGtTZB7mA9^zA3N z^M5#l;J9!Cy*!8xh*7&)aFgM$3fpt>sSAYwf-arsPyPLMfMknp(IXp2QU9?C^dIbe zSMB5}j^p%0o@@VL=Q(#|DFh%(4E;3!KuCJwLooqw>-zr3dHvrQq96xjtwqq{P#Hg! zL!xVu`F81ySmN#1YpfOxachF`<3~fqZrNnCIOf?U?x!25yGr@C33rTZs+%30US9qy z2md4rSrNu=AN>0dk&7{(M$yQNd@moc+Gx!IAF>a-k5Imc)3fmrj&~t}yoS||6?3G| zw-nn+d}wt902FmoP4UUKhj!|>W1rSklb|N{#O)iz-ommYU)N;3}R7_OXT zsB*U950!BZ-JI)v4t|k+e`^63<J4AswZdG+nnukX~7+M06p9a=6I z#s5jRf1V2?&#EyEgUsHh1E>#$u3nvJC&wKcx+U%UQDZ8I1|6^%y384Ge!7@oE`wA zHI?=9pp+tyITK{YHcj1DO_JYPz2|X`$}{%+P#&P1xkr=)mkT`}cZuI)1ZSCK&C%S& z)Iys-j`vhQ`5%n%UrUd#&F!BIihkWYm01WQcxUS8kHNDLx^fLFuK>&sL;W1rM7=6`gfJ=2);$KCorqURCG?jrvBKeE zAqnRNVQle?cK(PF8(!H>lc+wBZT;iBpyzjLT~=mT5av}|^*BzGZ06lZLf~=17jDsQ z(UDi_F1I|w!lry1IQ8f*-Q%!|&&oR4;SAXawWzax&C#gw<9S)rkrztyplih|Pz52@ zPOU3C=viraq$)%-*?(^UZ3+=i2r32PA6xRiv>p(P6|m{cC=kxkY@Zo$Vi9}&#fDJP zKHM}z&-yIV-D%0u3Y+cafqg#zSj=(vD;puhnGNKmp+SiGaX2boEL!StnK#DJV|#E< znVJ8FmGcUCNfDUH6TsAdv>z(7e-v&r(l%9$3t8_j1Zh)F4Yyfz`y zmDup@IYNlqqMJf5{Lx$U{LBiJoN%t(l}}BoNK1cBE$$a#V{8&}dcG$gBO7qvQjSRu zo7Sw7IobtZ93capn?*V}nw&GYw@cE!RzNkcu~tuCGhNKlDSCHJu;d(x1)wK_Kt0RW z%DJ7OR~p5+MO2EvaHkPqoK^QVcV-*}p>({|9#i6*cPCq$CO^>&-c8-|J-WH8VZ zQ|X}9xPsDFY$*`=%!^5VGrb(+d(7Y@rAi!W?LUiSfwQW7vn3pNV?54@67zu>G_mQE zoEXHNN?xm-Ia?~%l2@;$+X?Vk3r@ztYB{Q^5SCr6HqwCRGjnSm5hRN5osgsJVUFt zhaA(-Vj~38D1GN%GL1uR_RAcVkP>}*F@3;s4KD!y>Hk{C-<}F%zune6-y3=g%b!w8`moY#kQJZdD2nuwjwCy=SSFC zA4;S^nCES8*6Q7Qj=afcgDAxbV}*}0GcBX<3%d7S)W4-hfNZ29wBux>X~qmz)tf;S zKu8^^mm|7=id!cuidho3rnm9+Yv$gSYm&uSl@J+V!fGObS;krI`E(14K z5gPCdkq0HK#oI}o^fch^&aKAsy3N{*Ow%R2h-*eYOF1^xR|b<0I{5faJnGrmU|S&o z9Ux=QF97l6;34_Upt~V!o0xGzoZR1h=XCcE|HKfQXNEry+PXD?fVAm+V)F2`Ux0X5 zo}sU$iZUlnv>|Wf_%Q<{&MOOWzn0|jl}A7h_^a$1bD0y+`2xE-Kj(T*gvpoeQ_)AI z!bkeTBaT|L8ZMec#FrWWiqRXs?Ge(g%aX)3V%&O$^tIy1_p6^ zD|WUkHqn&c3`B5c3G1~K1wcp7pGpl80MHLKH4ovzi1bvDxE6#RY^P3T!Uq}$LN?|d zfqJjhGfP@p*qu@N}+AyIRiM^bN4O z=0L%V58uSWtIsu08V}jJO#`v1e9)m9%sKG&5WM-q4Q!Ix+D)Ys7%EQJ46iHT@#Xhi z#<7#qVR>hD^0wROY}%rq>AmY;#W`_@UpZ9982d+8o+IZ1I5!Rtu%VjLX+$;s;t* zi>XsBo17}`aWxG2m5Yz|<~CsF`yFETvp&sJQzE&kdL{SmTc|^dXMV(;j)bnNipoMN z6ol9SZ>N=W6w*%!(9a|c99-mzxRT)99;jv`-FLD_m=Rz~#z%*4RLwkXk5xT$xHQC^ zaU+)7g-<7HC(FW`UJ@#fODc_*wX{?30jlLn(x-y(FodBKXgx>F`9bL;g@ejF1zf#_ zH5@5)W?=Y7J`nHIlKx|=l6ZAsWxfFmz%7t1=c>Mf%8Smtl{)!=5%ZxEmwbAbtlXF% zLs7sp9F@stx|**vHM5RC004$Y7?^(?XU5A)*VA4QtZk7&2^ODLr-T&F)yhR2CYLbk z^F%YZb#PTtU-tcFfE48;>|AYoox zM_q+|)aA$5)H!?0;79<*h|s z;dJ4xg3RYS!_bXVS%=hVF92gULVCv@n82AWY7o2cVZ;Mkf< z@v=Pm%Ww{^4WgcnvaWrjIg5#ue{xRwlkQG5ao_{ZsKG`iiwSldK{F&gzrG#Mfg;J1 zb&T`cLk_;=a)E**#RRLZcMq$A=~+bs`+0K6!3XaXnP7ZyruUVgi}&w2bd-V@!Uqqt zi`GPWv)JOn_9q5#hm%YLpZ)kB5@%eF*ulC17yRQKnE6Wq&$hVyuWm38T3Q6fQ_SPb zA68+~Er`Xn9jtKGkY zvp7y=R^_UG-YLRsrs?{wnwY(ym==fpYA%=U+D__?2rvdD_9KF(c9RfT0UJonAaQd| z4Lp5`TjQ}Aw{{eO^QD++lM3tYoR_6Jo7MxJow+5H0Fya{L0@>@)&AZZAN)-2F!WgP zgD)oJLka0JB02MT0P&&nQyz+-7^^32bDO-K7t|@RrI(zOD7C&ZeZfETvyBLh&IVE; z=&Sc3bI;>MOM`44-z!bCTy-6)7tMX5axX?*urrvlgD<8_=tBEZaou9Gx2mN|3F5`p z%VX<-e-3BI61SgZc!_{bdi#Vsp6=Nu!Z6Z(2rn?Oj&gFMqv))q{w0Z=P#OavgvLf_stOeU!oTL&Ql;-z*O(WIq5VQDWpy|?&*wiH z=9|O4I+ScYH6f(hRmt6g_{$o4I7^BD^0_p*+=?L0D$#lx6K`p`s_ruPI@|Zkd=Iu% z%VF4Yo^{2G2hyJxD~57wTTYO8EMAp+{$+u|(2I@O`{B4$Yr7^px#n@t&tm~})o?*uHH=Ke-o`Wrc@x<$jwAij8gwb^ z0OyMi`XR}Vp`d6D%^hbbP{-akh9jk7RF}^ugLNQB=~l&TDJvBIfen8Lka876pPu9M z4b|X%radaSI_9qPFQQlNo{$TL zQmotlmRjZeg8H`vW1xk5pb~LHv~Ba`hQ&@InhPaB`6uqZkMW^l&=yj!w2>3*>% z{$#b70vYU99m3k&{RhJHrx;~}DL(uSoBWHsrY`;jyDij;68=7>Kh69x2N@ouyj}R0 z`hR^Jruh@>j*`MS{{z^~=t~B>PldJk{i&C~Hs>R&dY*h*pt&tP{NW!6|G&pT*~DB4 z=f`0o|0H9MFs9#?A9I?uP2?Zs;v7Q`A(^(VXiLrcF8(f8Udvc@(q zf<-R=17R^4AxA+UpZm`y^*__w2a`4ST2c0p`acl%UM8#T|0@_6#!LBL-(|5yKq8nd z72iqzZ(=jM$f5=xie~mFl;jmCtc3a@zg6y09o`&%LfT;netq^0@6^N2(;i|Tuv^V` z+heshY(MD`vZZ7um-?#6|3`uTCb8ex?%P6^hN7*4>OU~K5KWebO>NMS>^~6RWNu+{ z>zC~u_1I~{@4AZFPd#lYn(0i?&x+#bS2%Mi(3M^ApKRjW8uL>Z`i3o5Q4}{B%}=ds z+Txsh`VTiQD138x!}2I5!c(41ul}gNivLnSpHUF^`Q!tpe^|RuT`T%|fFw0@$1;*q zIE;mfDH2%v4nw|m@#+49SK9_x#cfhI=lT`&N~|L^uMRHr+-F>x6v9tiJQvZX`^iO) zH{VjZu;z!UnGrI^Co1;#x#g!!E>eCz$r(3k`9;h-@G{rU0V5~SoXY&QDmdIPm`z4W z@lZmWoS(&SmEaucxPli*NDE{0U8R(8S&A`J2zt}??c%=~%|S^v!1EjxJVeok)`RQt z8_KcyQBoe;PlM-&3k)jk?Wfb2pAPr)8j2WsQC7Jug@+(Tm4AGHo90;|Si^PprjO5= z5&HqEFU&4!%F$6eNpQidZBLTC@1!&XizjJnHjAU~8SxBlT35RfM?)>z`*RCT)-?7u z(E};ZZ(DqlrF?Z)rIY|U*5WhH%fV%61Np>BHe41T+ev~Jo4dFGPwiYI?h1$Ir(0mH zYG8}Co6(8iyp(tzy8)kO^NpC?F^w~qc{sGlx$WdEmxyJ1FOS@Rbr4H*T3W}7d`$w2YfBptiQ0zm5dA2+3DRWgn9ofU&D zq^Un5We=M$_AByggVWJGMg~Ukc~S(g1a2#vrj0m|dn?x1zUCtT<#MZuE*EhAvb|ER z1KPgkaQn$sanIsnoBqePEARx-#NQ34n{pofUD)xw*sC1r0z9engdn6-l2sCy+i$5W z+R)g#;KXWA^N6N&y{tB%ZInTh6IQ)pN;6}5nYyr67PHW2K9FZvXx|6!3AlI&nu=R< zMvO^z1do5_BW{jKExxr_VIMsVvV0hDYH_G)fc=&G*-DafEN`soEycF2vJqaa6=qNE zj-b0IpKj%M@12p2Zz-+)GAYw{xZjA9eG6I6Gd3f|LlW1CZf=uJKtZQ{l>`0#A9oWY zQ&7quo@$mmn5J%6z4bIuHh+r_Ll4~86)J-sILDWne3m@=&Mm^|z@wjpUz2cKaMX8f zp8-y%S+U1v^VQD1yxdrQs>Rqppq+Ka+d9;ko*mpvOW2Z_BDWo$)~=oWMmC1|iila% zj)e6VzNFBur`Mc#ZDHSObe~?(6IVNvxI|S5BY7hUNh{<7x#$pNsq3^2p$5zMidYIA zdr0%!KKPxEd);!BCjjPNS-oMzz)lS#s581>0Lc z9z_m9BHvKaE{4{U4enXrU|Vb3z}1g&-)0actmah}yB~5jxOC|+B%n5CMTk){aPJL& z`+VI1EsY^bi>q0v)@`;*X-MkR@b4OEaL#}Y@w0qD2NN_PM~;2+s|8VneCY;_%huFC zbFpP5cV__rS^7FN0PV6k-b=3vK3>w~KRWUC)vPV(Wvy!A683K9KweNJ?@W-i@tCBg zyCHF=tu-URGhftv0s};By=G1G%jC^eON?M_vGLV(ca9dAq$)YP#Z}=wn*e3bEJ@$= zQ_~F1OIXZ4?xAJY&ey#wfw2LQ!+R9lcnE#ch%K&>%=FA(}JIzP9}QpdUJtmbSyFP+{T_qXsLdqtGju*@mb9w z%I=?X^-B6x^L3@P$#y-*Ii!>OJp05N0(JRS_?Nelz@piqU7-Ek>Wxf|iU?8Okpfmv zPa1dtsM`=i#w?$YQh%p&o6a>TYGU1vWiv=@kHW9zxgAtL`F$zQuC z(1)l686w|FcyD?8#^ftOn02yV)EVhiZ4HC+{I^)D)j#`PfJhJQdDhnZ<=2;R;oeZ4 zE_Kr)In{Wp4#Yv;70!Gb&x1@(h~kNcx#2NgBRU)w*L~eKnA>QRyiG+j?9&46Nrq*E zN79gGN(af>8wZ%9RNCtviqZ$G^d33$=xacC<7biV?X>6EHyP7$jVd}>d^uN!o>f5HW@(6D#$Ep-yV!mI<6UL%<1IB0lKIr! z+RTml<>Q-+s}k2eZ-z>_ss*kE|K>70)#sT1Xo7chu=)5LmC3q8MOs(hZ*{XuTGoA$ zY0$&kA4Etu_QcTij-fnt3MafzWX84@Of{hmqZ1z^xOV?h>s4zRSmV<{~X36v(<96J=2hG z?0px0j@=SQK@71#>*gpSozUCx*!E0xWowBj!2+p>TXVY(ARWg?9N zHpQK{Y}wqT1gM|I@_}H&){#kj9say4@XZP-zUGffJcbfwWvpvU47DvTGDj28Fm~m# z5yu3_CC5S=LEq}TiQYZZ6cd7TF2fLhNejZctJ2S;_ouj59^y83Zc!~qG=(e-uh3#H zdMX8e|oexJVqal%W(C$#LM>YOdhj5X;rNXgiZ}wSj zjg`l2%eaH<5+0y|PV5d~SOE+?JSG72N~^}6E$Q9NB`muyd(ZlJsf6r5cXrzHxCI-l zc8-%d_2xngQZ$L)NEFul5?>59MKW()U#TMx8_Kf0i=OE9UdOYpxHqErmY;kfbqRZM z7&$*TzPh^|fXeSoB~nN^!^*dx&G(^$5}FMIh;DNEU0d!(RQs_;t~D+Rgm2UxR$U1z zyeWoAZBCAg{?f$MTO}R(n3XcVnH^Rxk5ejfl9=JJX7);*wirGOLYX!GrET^0eYd6D zokiH{$)K30Bkw|tzOJQNT`${_8atR%9;W=j&MM=%749{-*)+UdG<%4;3lMC!g01WZ zHhHCvPl}dvGr(S5X?ae`t#XpiWo)UZq$pSGVUy$h7Y3JIZp(*Jl5S>;N0oG)Qo~~_ z-D|JcUfbFi4#XGD;y279o9H7$X6b+W#^e~Z0^9lMoR@u98oQ~u$UqS8E|B6G{~N$O zPys06ycpJup?CKxY)cY$&8U;1zh>Qg_bk9QLsTDNjhesiP^1N!*^8uM;Ev+A0$(}_ zz6)l`T0tPI5t~8V@w3KTegSF9C%uKitIKHvgf-?@aLI+ncl{JS$Z|yS<*5E^J)3J* zgu(I8$38X#m1%~FA}O2u!`BDrmqTq=5af;1o%j%~D>1iIyEtXm7+7hueKYM-W@aYf zrlvC3ZcvgwT@3^3WjzCDV6zR_Qo_i>wY3zeLMq2t826@kYL^^INt?S1H69Z~vCviZ zohJv*P@AE4?VP9;@54T0p88YffwHsbe1pg#2LxjdjJ&{43HX{$-d#b*v&QEnrLvOr z(Q+A}uX~;y0%|e)ku=^T@(g&MNE*-0B8_IrmhLPCAue*#F*C(lS9*PqWGHnk=78x* zGNk#NKqjQx9Xc+dPBp^kn!$Wj0)A1}+=E>4H2GL|w7yK6g!f7G4w&CjT+#!eStg1s zyNa-ejQX|BXX22P_~Kxhy--8a?zrhu-jH<-6URF~%71?sfFqm1{wkIqnoY6SK`*<5 zMqxLro{(nSqSx=Lxqo!wg*40w%$R<(1;85=NXRnHjZcN>X-l_$)I;=tlH@*Cm6<+p!#$y(-hg#i zb5%?-m-u0{YNt(3b5fy}Y11X7s%CF(maru9t}5pJRN29t08{n&XK((-CT*qj8JqbM z_2e%IK-(IBbuIAH|0=t#ec6EB3rNHZkE~_qUb&>an4;X?LsUCT&}gFels=x&=O?R~ z9QyJAK@x@xu#Tk$$cR~u`I$3NL39zDWikDV*yJyr`Jf4McFoWy{>{oqkuiJi*SYdP zFFii~6h;}Og3$%KUvE6gF#67MvAdtX&2z&96tJC(-dPs6?;ojf{>08oj-rZdm$nWR zHJc+NX9gy@S$4v|v(-BL9<~-x$}?Tx?;)JrSAWYXHG{%D&9XipoYK4)23K@XK?>V0 z(i43onisxGC;#x4pZECfoLAPI5+@t{4J2<+9m{QiJri`9e^Wp2@3=DWO<^c+i&e}Z>&+ktJ zS)?Y>+fQfXbrXn1ln|jspGm>jpaf$pu;A8mPan=i&t@2745dssPG!DB@IJ1AUS2B^ zmHDa$1{?E|FRfyib|h_VrSk#pncSqEK?+jNjewHUDF-zvn{-33Nw#gpMti0ftmE2A zuLvj4L*jM+X)J$jbo`C|xo4p($6g2M^fF`b?b8RTWzJcLSblhm!3GubjjSczCo}0+ zaPrM-KFi*ytG#U_kFi}LsKn9A!GXGZ#i6dUV+!xdX{*I@4|Z1r;cltsk=xyR27DkN zbk|V&5bJq-O|3GUn(Zws^3m5QhFWxt#FD%5G=;|Ls8P_<@ANM6P9G`(aCE3Y{)3VJ z+!zd80?~ZJY~-CF#aE()MSJWFdEQZu5iWVcw~A=*4JRC5$tcNa9y@^5e9CFHAt`(! z4f5)Uta5zh6>dnHP4dQh%Pi2B9I(58pSdF7p0io|1CFAR^WHnk|GfPY4jT`;F>@|B zaLScmGb>dTUc0g1(s;B#IMbA0c`PDfB;$`iyz-mDsrdHRIP{b*Ni5bY+mRV$tP5eXaL6Y2q1*5^o4u%Oc}QlH!R)`+2K zgT>zYjRVFg=K{uMJ+r#+cRsCr4pZZHc<&!#enU<7z(b3mQyeo>DRqF5*h&U-CdnsGQ z^bnV_gOsk^ZiyZsm^B}nc?XPoSi#Bn{5D0kNUZtMctCbMN|i2NJ1`;-YwS65y63Xz zAt0n={uwk+Ltm)JgNfLGr(|OMQroxF+~eC;9~x*eN336(13h-#8{7K6>=bW)X7YM( zNacq1aNg?76ekp4ErJ#e<^`X-TPCvOA5&g-A@|_v@#FyaC*Nzl5AY*&eYj4?t7*9t zb7%%=rqYU9DY)nMTTB|Ms#U_6_*lwC1QsLdlQ9Vs1>{{9Jo2#>m~}xb{+=_Cszydc zsf~`Wo9aolz+d%YYAg*kcom@Qk2T5ptre}MU4kni=WcI{YU4a_(4>D+2y{&;?)qkz zsWho5;*)_baqdMl=-u3(BxhnG$RN;ylvj409K0=QP{(u?h{vFKVv7}9X;C7P(tRmP z#z&%OiWQTItlZ_-bQIlLnW8%HjHp3aD!fkW_UWr4Y4t88Fv6Bv zb(q62lJSLu@Zx%$&o_ZnbD^)iB8=hP;7A4hb)@pBI4#&OSLy7%1qN#uhdQ?Oy#6o9 z^w*O#6Ns5^@0TTt#r;wHQ$a8rV?O3B37t+UVsRM8=P^-oqW|pxljb*L$k@s5k$Pb! zj68Q;^SF^F)!GZ};`aAO<;8m8qm^qW$gY~D83>f)bpnV}FH&0NLRPI|`jm|GXnC;_ zWFW^D_GNz7)ZcB6Q;I8Mauiw{gRGU6*7qzA_|RKqv;Gs#n?K*}O>KDJbYHZ;*t7Be zUXSD|iucMzkrQujJvleL7I2PwzqAnc=unC1$u1d0YzD#}5rJsCR`|Icner>k?vIeS z4qO%=>sNXB&ntd|8#+FShLX1u4}*z%ekbsNNDUr(lUg_g5vx=UpyK#}L@5kH^?qOW9b{Siy7qw2 z7wKfL)$tQZWBsqEYe<)V*G;})88JPRJhyxJk}qU@;6%Kn)4TbBir}0FJ2EK5<&om+ z`<^J8G8yv48Ny~?yh&FAiw%yJ{}I3m-z_<^SQ*}11JxH+yBfS1+y3A;Kg`~D%8D?B zb&b6@zA|gKj*Gu>aAuWuf28r?xzZWCY1OmV3QSw-6QQ!ann~ignGoTMY1(&@l;;I3 z*&@bogLZ5awJ!oI3&TmWI1+eVGa(FHw=2O zcf)G8KY1RFc9n{m>kZWog(i&Mh)1DIIruk|pHJ1^IWtB?Ku9iU@)e{X%J08s3gPFowgU6N^(UFA4u*Q<5#qk)#nep(f=yuKFb z!<1pQtUp(Oo7kTpJBpeChksG3{a_VG`_&NqvNn%xu{RU#X`yG>>w|gVz}Jr}>xwV^ zpn1f$5-SN${;5vyLvn2rUl=9KM3j8E?X{rMo@u(TTE2yX^nSW) z@a_sWvjDY(;%|8cj8q}eBRW?cN)6n5+}2limDU%&xqK{n`62gH@rro7cdY@FV6(x4 zlN@2^d=sT8Pdq-7%l7gGFZ88klkfX#Exs0SJRV0MFSJ9k7GsZv#`CXUlQe>TF??2Q5!S(nD(0-jYvy`f*2nL*U%+N~m836%}=ZuY(m6`m+NJ zH(jwRnTeB|q6c?Z$WCrPdXH}y;j3R}H~XCoLfLxnWYtFBeP-g80t~6M6P-2i_6nJD zH^arrYFgl}^1NNh-=d_$S2be^7r3yXcQb;pj6d1XF(hIBVV>_1eTmFGHI{Jmw67iI zNtKY;@tR2kBj!ph?MDMfsR#&Gy*Zy-Xje<$+HPQ6Qw55w@#_5AoJVB8-M{Ip`iSF` zEFE^gFU<7T;?DP={MtJVV;)sgqQHj`;{;gEM!2ZHe*?uAuhp(iA!aKu9HOoeIVRJ) zQ6Np7K>|1}Fj^Z8)F@4=-JU%X4m7bpcd45o#KcLnyfaUwK)*mk`F~LMl~HkZ%eKKG z1b24`?kYnuK5e6GhAUHyhqVXhUFhV8;-tbD6f&qNL{P3FUH zAeiPkhpoSB>HH&6nMZV&<+NjYQMPZPXMHO0ICVI98D zk$;52lBS%Ed9qNgU*o~{AZgzYz;Q@Lr==7I?3m_hLZcj+zA`94AYyo&d`O`vWd6YO zevcC(=UHYS$BYs}oU!b~Efd>}v$(*=s}y0HMQWa=LFd*=#cw`OC)R0Hc{4y5H=Qv= zcS*Sd+w}W;x?BR@HUN8*#8|AY%VE)Luqf(Q;XH5T$fv*XyNWs_y=$w|Y)qQx7#XhW zU?lOosZV^byt4LtPWXJa5uBL&ITaz`3Vu%_<1kWmcbWkHSO+dmZ0@!=3n;N3zE6Ml zHguXMQfX3=(1juu@=aKAIL4Z4ll?H7L>`sOq7B=ApOwft>bKVuj zu$*iTfYi_IXwdszKvrkG?J1O~(C5XX0wik1yF+l&HqPDtf z(VE7ZUn7SZ2?9YGdM>r!zJB@bj)IeMo80qfr$V(2D4jMRYQoX~R<6}n>bh}nzU)|U zt=?GWIelEuy_PUqbT4N6b~PJ-VyF4C;kY?{bWZIqE~`40!K6!yEo(W$L4xCo<|Oy?)c&cb7h* zC99N3^3RM&*BIR%nN~nMepM$~YZ+K!e=Br~^z)I+QQpX!mq-qr4oWrq!MT6x;v;O( zGU(VP*2X1oU;AvCd3)S_7bG0(&!v2jw%9gQ7ytXz(D$&RqQO$%*1+v_%}2xucI~EP z1HZ|-lj7!OmmBo%?R`$&PV0JW?eD7G9$RZUGQ^LRf7|G#0#?ZSL-9(xD4vz$;u0tC z*=ov1Qa(I_em?IU9>=iw-Rtn@tAs?j&h((Hm}W0baW5&RQXhLAm41LLuqazr80jPd zR!@zD+6KyE3bW zMGH!wxZIT=|516HZw9txCrGRFM)Ev(urh?CgpN-3=Q24^S>~!}eUWg$9h(fsA^aGm|p5JYeI(!&`F4cLV!Dx4^uCj zmpb3<-43;`9U||BS-42^1N!}coJTUn_&hEB?VMj+# zy`F{UIb6Fbr;}%OCg0>!&(9bGNi>~ZC*APVm={=&qb{#wdo-eoj<{=`;_~~bI31Zo z&&`o(uVrg0q>E?v&vo}ggNHtfKR=7<%Zgtt>sycC@>j)ZW>r?*Y)goeYLVWt;|S=3 z55)>~*ku!lWj~Dcw8rVBhw}N_lC^_gz!=H;Q{w`dxIc*9SsxPR_A-4=XLSt@h8>gakRR`ldiFLvV`O=+IFDv)&jp`FlK*1o?&b{)1Z zw)!f4*m|1OPY>xEfR^9qXHLGRUy?B6%|$a;6qkRNz&wXYM@O(a(Zo^=xw#<_K@Ey zbAO@o>uNL(&$0}`<{KL~U5qB1S%`g z7O~F68VTJlJhHK?)geIpIM@eJcPpZnf~mTZlAPP}x6E>h(ynyfE#XXwF#R!ooyqUE zoDR8>78mKfT1P!FwM`G;@mE4fID>4?;0n$FJli6Tpu+y<_Be(F0d2!|_iU3X^u-#N z^ir6HMLj}nPLY$(XfSMbc>UkX=A=gP)y25>(X3J@`C@|U(jDUvKGmBj&Od}VO_q%k z?R&I2r>fAVJ?eCjjoIl@sagxDEm=hy0_?Wk1qZNk?#{HMYVmkdv7vjfg75Zyae-dy zR0D%88?D+>qhAN1fP)l=Qi{f=yP|CPK0Ij-r1o)ZdB<&|&9Yew5j+k&g4-YXjo2#2 znmzyFOww}tvuGD2jHszJD^tZGLR;S;Mgq<3PDPKtY{B)ieihMFvz<(J_tyaxNbP<0 z;(Eg?zRA_P=&L{Q8UgZ>kJ%M_(P(GOcF6GfT{*KuYs?lAzgybl2S=4+jqC8L=e*Lr z=na#$7|cIz1uzftJ^rimfmct)}Fkzoq+U@%5%H;U3w;g0+g4mI2R z_luO)0N{u!qYohLro2~HmP>@;xrq;gg+ukg2Q{Ib0@R307=W?T&MFH)5uN5^Rb6La z=sF#}^GRviaZ6_}@Mgm+;3AS2iv{{fm>=gaM?TqiT}Hw|_A(j~uv4 zy04gj#SXkd1*lenHx#-7|LuDIZyKQ*KueSii4*qh1d+xP6-sXU7vo~(fj4NDKs0Ff7XyJGgbbflDtPx7CRX$14}q+PV)3sA=8*xm zh#!&oS0={whp8&>N}2vw13CWKqF5Z;Uzpec^&eXtjQ+&_7X!mXfjhByuLAoQCblRJ z*do_roXuYioCIbSE|SF1KTIs(9l}>Ueg#;8v+#0*w!X0r*HzC)-(Mwu>}m#PBXxkM zIr5&X$Fx$bS_K^)olT%)%>DNO+8+%hLP5`~lp$%`9hz)U$u+Ono|&3Y7E49)>7M{< z4PM$jXj;?Ij|N5PssxZgT>$Ydzk?&80jj~1VnFwL4+aj^dQPiRHAWkG4Am76seT*1 zn!k^Pe70}+PvV{*Z_U44f28`iXA>UU+3xe$dbnzln4D@V0EjmYe#rKA9f^c*H;XJ- zLBOD1^nw^pVgl`Ks{&J2{0|Cy#X$S_3c~;lNu!bb2jj3ewxL`u?1xZ2o~?U=$mo!-^}<=N zo-kTM|FBF#zkuLpgc_?^y2YQ4sx#QWPOrMQ+8xj6@ZAy>>+pzEOU}*mKx7+BEZ9tw zUgjBfaMK1`dgPie93l%?Ns9O5>h0%6(`2bX0#TDV`k$NR(l{g(gqkYqtmo(WMzcGF zHL7$NZFL(z*P0z1K9YD-0%BB3o809$NvaiA>iaXL`Oc?vy#&c|0dp0)GGR9~vX^G^ z>}-#$qY2E02DG{jU%wK7y5<7Qb&I1J?Jp87FUI&!7dM8P+N8es^(}26V9+f3xIXL` zM~r#xq?$_sw8j`qqMGTEIAR*VXHKm@#KPBiFR~vmeu;;W0?$_!;8=W!CZzf!V8sl2 zDd;bYTpcFx}K8c|41B$}0aR2~;Q^3{x8z1E#lP~j&13aB{3gdpR* zWZTVOg9dLLM;6Xqy#YziqeDQs>iPl(We+2beuQtPQk}lwevVNW;Emd<)Jk5jYq#A# z)a}-o4i^Gyba`w2Y27{sfy1*V#yz3#s)+UpiHxdq-bvkHqls~~cJF%|G~i7VY;6^O zEQ}Zws?`xL$W|1jvA6(qNEnyR*!(uPxMjKnpzT4;=P$tBG%Pn_(Iwu-+=RLvEm&G} zYE~JjM_@A^M4=E*m|PA_QUD~hy>V>^-?e{LfP5kfkn)Q;z<>0EYhmPZKg(%?)uP=V z{+7Ji8`(5jG#eFE1Uv6btHH4ER?uKq;~Uh(wc4VH&t>B<(m~SmJU0&>J8`?bp4X>% z0IAi?6Ax=jZOeRXb#dDg)t?rxdGVAlD%Gj~zQ$>MR?}z;W&#o>wH{AGFW#O+P3EU| zUbf%XtnX$j7oUbFP7ssQnfO#%gd%_QsSRI|5H$Nx$tIpL)8%bQo$}rx%8s(doAA%D zZEbEoM;hSyRIKP=^`H<M2)E^ceVn(GUkfiO<8+vTJ=;ohhHo|%W^|1byeC{k= z2Ehf^rt&+M)8-4*+%B0e=_X~f@#fingE#yoro7g+p=yGBt|!!ty7d^gQ>sBs&9+OQ zcIUy~);Pxka42|YR+|+K4Jd*aKQniRny+tKT1~B{3o=`-63094hMMawW;Jx`?U>E8 zR_6`G55F$GW+y$)gT-w8`xq(i)NgaC8Ot@kKW)8)`O|nS~n~Q z4Rv{M_&CgG;pSv5QT+Xrlatt!Buq+}{UoOS_}CM4S_!r07S+!k_v6c#KOb*qYh?FF zP60iV+bckH`9#oZXGAWKau9QingxO|R3XXp)O7h~c?Civ0R*zOGl4f=X zMBhV@i3Ke3w&7Lz1-)(yp})i{zXVF`M>?ne_KkVDPyS^-{w;Y}(XJo$EBRTVhpre) zSL6@LsPra6X6lOTpT0ekGVwFXXXO#t^i=(CvC5VX@j)AKv^XXZJSK9srh2XWG%c>j z)iL9$4CP$ock8)522tbLzB-Jz;ck$=C9m(8Cw_i^WbQs=x~M_0g$d za*J9C;&qoN@)2hV##;mz>f863_1%=vVLAmsGPuYS2_J)nJGhQT@SSRpI}VwFG@24L zCWM6W-w*3OqHmrG_M-2mekq5x<`;T#nrRP$GkbRbUws z>Q1uIpvvM3?O6uD%hFdMVW^0X6Yu16){?@_tZPS4aH&4xQq7AT+z?c3Ip1Czb&L8! zg@i=HnwC~?VS*ql4``(%2;4c%`~D&U`Ks*ftq-0JKbazLq$?$p+3>(*Z=|zTjMN6i z3IP`iGw<5U9o|Ug(B6Yd(>iK9Pv@)KcL8`}6jGM_vI%%PF>j@ce{_gJB;4#@D z?EhqUucYY%^+a(}rJ8J~LhSBXH)R)IfPaz?&NZS!->J|R$;RuR#j&}%x#?on)tW6|iasa8kFG>zKdg-Ky zzLyPltCBvCS9!B#Nz;H3_Iv%My5H&KF!lEHk}^^$EM!Rcb~#VoVJM2#ANvZ%GWjOH z?yLTWt4*Z%5M>Oq;j*PxWLYsLQ%kN~6(@MN!|$8H9(gcd^#M)WWE@NXV-b8e*JY6Z zbX*d%t_Z-{$@`khHdT(N3V9^ZtI#VN@)kXq(a>yILbZ6bj@>JIo5w(GU8Bv62-{x| z>nYR+Bp&<`kdw^QuHBXS9CTeYnqK<3_brF<6K?70nSF*mM$OnhJXMulTj~ zRBCxE<2uy6+Y3|wnz>3{MHs~2#igp$%4@A2zc?&9Ac9KVt3RT{))oW0eEGJ^HjpjJ z%!UgW>|3ym{Hk!#6}t7YKi$tar}|04ih&vjWg4?z)3r_0+BRnBmPW9ybdUXSHniu; zUa?kNJrZ;{>}6`rVvNLX&5;I8t!f*ytywph3N7Rm2l%lbz5J71vGDsAwZ z!pug~CWseRS9(z=nP>%bf@w97`L;uG`x z>Wy*REs^&Fq;dz4n~(uzK#yTCJX(oy&;v&_%p#(8Po4Mu=e%6YA+L?sR^8g1JB&5; z)q+9IL`vz87e(2>6j2rX%x4ty(S3Kc`^}#OqZIFC06EOkyDv7KTXs)BC)H{tU4Tt5 zZMeDRM|Lj;jRO4G#QO14Q^HY+>rd06tZP}Tr8|0ru{6%ex-vfyfyqj%DZx^^4_tZ~ zBUy@(K&AF2dk11O+1AdX|jKt)&aL95Q>+|=9flVRsL_@ z5@>M)!q1s}4avL|cZfD}J!TwAi34$_6d!qBk@5_^<8<5?VJ>&!nI97wW4;=#VPeKR zJxl2^!#}a?^&%3SQsX>@HHh6gzjVVKfIFC5DsbtPgJ4lM8Vqa0M7%x&eg-u`lQjsP z(L)Q*HFX_#yaLpH?j5HBcNc#^PuI)R=(Jj7{d~dY{p|eah42Zfe9!0v zB@3QFjDW*RbmA*?04Id22HVqiBo3F*G#)U;K_7qPI#NLT5?=eicEcLbdu)p7Un5<% zo!#m3H*;QQXRO}n~&EdELtZS^>M#F*VoBhDHk%rgRz)YRJxmeS5+$;?UwBnO$0?e zfZ~WBurPeDj%$##CfnaR(YZa3pqtF(IhtH;`bTveDce78ANVq4AgX0?u5a{&#bX~k zJf%7_SRkS{`U17$SnGGc2UR;nz(`23t^*Srz6?@tW5>=v_KhsY7b}8aZr*c&$c>vm zjL}Ok2f3lm?026 zJi{Yw5hZ`N%?gqZZ=M_r{*rM2e0|G`V7F2bQedjeL!D}P+>G=*VZhb0-)M9H_RHzK zU#uW8&7k-69TtP0fN;un_f;|Ih3B9j|Eo%0TK4=sgt-7n;1P%}2JbUSc9(1O)>iJ{ zE>}%z^!tWcCk6<4U-rrKGHcY73!*4!naFo99+d|3Z^m@G67k96*KM6`fVWo!mT!n! z?o3BAbW;pJA=BF@s$$xz_T)R8QJB&{HRh~@to`}z-J}jHhMW=hjt6%)nV47_A zB(t#l$^BdGICGn+J>~zgyGeFB3LRJx>$REbrxNI#Vz)B5zc~{M1)_j*y!ZR|;C75n zCm-uJ`Lz0YPb~||(a&=?dA+i5%_JjXj-bkcCEtcLa?4@O5_D4DyCP@28Y$cs%UF(- zEdog9P`=Loz>IT^P!ecnBs%Tpz=8zCS5Ob!YKxnqsKB|+x~vkjHN#S*F`@{%nY*)U z6}`}mI#@VBEWNz{BRT~}lh5fxXGIa;HR$AST#qo010U@VrYn}b>*eZ1k zF;;+EsQ-how|Sm!h1Ngs&AkKd?rtka!UUncSGe9vBfnQRS;dsAG>%FZ+p61_5MY^a z+)x|cIIliL)wv#fdcJHnSvZhEJ>j~Goe?PKdvdbwriRLothd^xYuNcrn~rCFlSF=9 zGw?2%;4<{Tc_Rcgyy2-ZXp^ifn=60$qViDmLo)KUm8qN;!4L~^!RGgE&xfhl+@4>C zeLr%8dfy$6A3|Djz3_O2-q{O_@H+kek&MG`_U?u;PN{Cjz0VxQO+ci@@4*r)Q_xLF z$%}Bhx#i_+{RkoLL2;FL08d}4bsbWXd5%1{`J8jh>u^G`f^>WlqfUB(bF_TvNAm;O zHF>Y!1Ih^FSrjdTYv~EyQ5PErdDca9ifn*c*-l-NhTOZ{JKHL?YZY9{39|joj#6PI zVu(jGLI)Ji#2#6s^~kixgrbSO`T-2nJVV*132GnR%)6I=$U-r zd{TX3cA}OJ((iRwq@{(7@F&lKfB*M`cM80FT1;BYg&FbF{Vvz*w(rXm{e_OtC$U3& ztV{n1ou@>PBJlG)?nu*gkvs*qil|kkeZ~ArP|FrgHuTQCk;gBYlO+^QoSgDSgH-zZ zo!+Jm07Y76Iw3+eV_4Q}b;e6pK=7us$H$t-QNVy^MNRwq<0gSj%ySOa#a4TuZXS!o z>buJvcVJ*g3n$#qC)}&mvU-@A#X?mtZRXA<{=YA?d3xs1(?#=@;2$4)?*#Z5KOS<* zM0BQ03d4lk;~O&?{?k_Pl1XFvTk5~)h z5{m^UdEyBB0HjhG-~5h5=!l=|T-)D=d?cxPgTP^RNj*_Oo2}TRJ1mBDY&}!*0nThB zG2mdXR6@OMwxDL4eloPaj8-J@E}*6}!xDpQTc^SbOD36&ol(0cG4vh2aP`OD%?BUI z0u&r3_h~wlC2GBe7|6uO1}0c!{O-Utmn-?xtiVQ-HlQf2NGaC3YCtW}G=J;u0)MK;;8Pa=2y>k^uAyMQ<3_?~qN>4k4EBVdIEKm=&>27u0 zDjLQgG1EBH1U$Xk;xesVLi^v&ZHpI8pbi|&+>AB{8XB8kNzrVtK~VFiSSIH4l1Swo zp->b)Cn}ia8%&EkF{zuD=fQI2fph&>9D}9GM)Ih0O2!@<~2#gdgOmO zChqpA;Y9q{*L!QVUEOJcc!94#UTABp zj;D%1^F8FYDbP7`_PxLOHU(>c$uA4%=LM1@R5awYlyp#NH=BK%oEEjw-G+W3f;yYy zOLWhhluqeLju2?y5eRcRct2Y<{|g5O7ozNq0y(4K093>&^8klvy7_n(%mT0VAo|B* z8+=u7RiG=$w=~ZB`$F~*v9rg=(+{7*-UsVOCvqL*pw|WYSPD-ZGKx5r8+Ad}4ZpVk z>8_-WhHQvC?2%0Gy4YYnzqCxAStOgzRUd3`F8@Ijx}pb=7R7i{3dG~k0kjC0y;-TR zs}Uk)YbA-G!`nLcX(U8U&@DSixB^4HL3-U0IP@Q@`lj7k5&EOkNtfE`lb90CqqvNc ztGKV4pMRyFTV_3L%>8gKvOW54XF(WE$eP&fcG&GJ?lg78>(qu#ieK(_^dkx`D4^-) zT>4|+RmndWl)tSjXAl(Yqkw5Nn!A?*@@^5#9rlkm*!1l08{M*fIgGn0y|Bo5=ee(! z5K(r%6yNlK$StOeMqPbj1wz!NBANu@Z6CiYL-F43#Ee?VupJ5zzTj1OCvb14a7^&Y zZ6;{B%eg)aD?c$#q_{hAw8C>>WuE6!XV&JkKiRJ|Z!?q%j?AWsMH4neRow)8LzW4W zYHE2dH|o#QhFp@A^Wfq0W1jjtNzonh4i3{pb>agLs6zE`+NbBSI z@ipA}xzB|QJQZ;9dx*B18GdeI7p71;Gp&A1WAOPbh)sf55Svy{DR?A&Bd9>(+ zAlgYTVPiWmFhXB>d%WCF&E*tvKl1hKhhX>(OMYt=(djvO62T}O>($a+p!H393X9L# z9vPtC55_;fd2)G_Uis-L5IqiieK1seI?;r9yxfuP@JgeQL1_eIt8DHvp57Q6Pc2JF z?GQr(BHN-i5SZVZJ>Nm6QJ`D^*kTFz+_oZA5jgo&vdNLC?aur0&`uzkf8Q(LLy`zV zu8n*Ma!Ll$1_`4Pk2fcn@~nw4w+KIyssYc(F~OJ-RIu}q@8M+BVGlP^o~l|3-@*-# z5LiSop#De}3?h?Gth6cZk)KoM|u^#uAs7>m)nyN=ZARu2cnAI(9{eL{Y{;cu)Z zHQnJs<$BU6)rcfj;`GM2=x&387ofPyeSv~SWNxt<9p4-hA=iHb8p+7J4*>O`=nP3} z?=_=CFJMRFP3hP=w1Y?;bbnen`mbc&O}zQSh~ss0WI`{7)%y*S3$)b~*cVO2j9y2&D`fv`*Y!v9H-t%{49-DJ421at_245WiCC&0X*L7E9ak=m#NNkItjKUWKl1YWxsZ9jD zpX+A6uo)>}%7sy+vTe{Drwf5$!}}^F%<Vag;1-BZ3D%@hnu`>_rM$teba2RY4pG2guLK(6Ahu6cv3#^Gm;L~SxT_-V{GOYd3JH0qi8Kg--82lrIvp|;0V8zm%!zZRX}IhGEh$^x zIZ$~YT!rFtI;o3m9K6Mg$!tJaeAQv`n&1^Wf%O6@a(}s-pkMfTW2Y(>9uWb+01sj?Wyw_*!Lqm~^y!T42#b zUh?+#l;VSL@kFkuZUV2M->NSpMqO4Pjq5Vd{86oM`qvk(T!AN#xk`1hrOoma!-Yh8 z4mu>`++6e9s!>ya6I`5U_oF>DhF|uhIwhb%l++2$b^-xXVc)iYNA&<#zya;dOb9=t zrKK0&e0?`dz(*2qsyJWf8{JvoELB}r#inqH+0I$0=G)Sym(^vrf<+XPr4hZ4PK@uJ z_mn<6-{8z;gKGPrSbT31k3{sB;zts zVC)lV+!PYTxeN`A>G_EGUB0oLJ+l`n)LbUcmZ`^$rX&>0Q9P}G5CX)JA-F8~E^J2A zxQcv7>>DkY1L!o%g^Bp<3Wqf-;a?ZpyqL8??+xlo%DGcQ-8aSL`T8k1C`1}h7qY}4 zb{@a3V|J_BurO*i)YTE~=WOpDr$J2-d=4utZa*#^0~R_}V{D=Ps%|Q|%N=<&e+&Ql zE!_{Kn9HCWufuw)kbf;7XI$7zR;NA8jz+7*>GcIlCZ4j|LJGF<2uSZuJbT?D z6d8Pd^Y$Kv=q2h8*jvP#+vT>gDM8Es`S*ZAWXEu~JUlg$$sxz2E=K-Du9g0c468SMb5U%$KJXoRUHgcQcHkn!U1k~HIkyOYLJoz0 zt`C1R76AM0T)wwZI(@q>>JM))gt}7!G@>koCT1v1xyp*J+<8dpZ$}u$6R`x{O^#@P z4&Pai?}cE@$nn`7%cLRManeskZF9Ly(%N<0j(OS3_ERp$W&I>pN|S;5dbO__m@`9% z>oe57S~g#a&H&rA=_dawj8}Q5^h#JiH zcWJlP+q!w9*zc>hoQ~UtD{PPVv#-E<`-)C|R zh^%9?=>J4(sFcuZP^?l8mLLD+<|;u4hIJ;;DDGjVn>-76a-4UdwoY+0{wu)y_tOd6 z)LgS3gB)Uw9;W8GCBjp!)NQbUYwU>he~bFsGH!6H_upRGKT!Ms#{oWAcu$xN|Gz@X ze?Qaz^TStdXoF?A&EaI`Hdsbyi*Kr)NJ;-AuK4du%m4gqjSNx*n{=(sFMG_OSzH8- zG}IL0;}ehLd#l9vr)L`VR{#EN{{2<`&ma2RcW1%EvFcFFdhLXi8)W!r8TDA>PC``w zUq1oBBk=KW&~(C3VcU`0+(*5Ebij`CKmEzSyaM2|0_Md?r67OJmu-SGt+&o~XFg9V z^Z6W}!#U;0WVOGGyD?~cO|%p6eCRvzS}t7mFMT$4bfpdEDmUnY2`NIKDOfcP+lpe5=hq%dA>eV0K^{R*IRQ-b;+jCpOJx-$6!1y`yUGK5L5AS#o>!#i7|9y3<~MkO5vI@Fa&PbVcV(7;g1#0S>w4#|R^ z>-dE6`w^vvS%9gt=4j4DxzLx*_7 z2!zq=pWC=C2SzP=Y3h?A+t-eP2_7ghRxe zYd(XS@6-M@pGKwqUalKW5|zXm`d7==_`|5JYJ@uP*T0k9(l=!QjQnr&nlW2`2ai z4#mK){e=(d?CNEy#f@Zp&@dQ$E4}SAo2Rb3RBLV+`~7XHTNd|rj&at>p!ODPRgKSl z{7{?OP<$p3Tb(e_j%IN7@AG4WiNw|lSS?2<7u}jgd%ttIEXlRVqA@6>wtv3Az)Ilk ztR8QC2AI{fZK7|$6h>}9-#^U&Z!XUj=!YVEzvj=|R{jnnUt)<$*OS;Pt<6(|`{A`i5&LAXyBwT5qiwdua_Tv93??!wp=eR_p4s--C$5=rKP!`4IHw z&0KtEZ4>#3?jMlv<#y5hYVrd~lMMAnm>)kmSaxK8?Zao+Dl%40cuV3XJXia899NBO z&UXY8)eZhGkcGDd0Y6UNF6&&nMBb!XmbNd7wha~J2=yi`M$)Bn!G<6ZMQlnuFA!tT zBsdt0Dld*WzQ5>yU1P#T=i%LaFzg&X&$?a`gj{Yo&2c^EpA137IYuB6aA3q&$;bGo z763=sk81J3n#5l;tejRe!q}`y4B9dT9uVF=&74=gIHiRdbhB2|09mU+jJ(_zJ2_t`9q48>6FB3t{fo*87l&(q)0U`kIM4&ga{J=VH4D1 zUeTdRKM8r=FqjU+W~me_V69hf_Qx>K1MpNH*bnqErso&XVo>KQv3{UPAxj)^iD-^s z%XO>BB%V3wX1}Wk~(gD-FTlqP|7CBC9;2T9f}oNC9r>sO$q#xSyewq z0@RaEosF1wty%6|g-&=U>=qWrJygd@Q4Hus3%6?h>-aBe^yy?nvm~z7W*6NxoWTUD zeCPdX8QiS=MzuOAvbPx2?|Q!wEiW^~GZ_a$C-S>7(Zz!7V=pW>-NHHxNQx%THuCol zww+EZ(OxIhc1LyJpPH|{04z-mG*EVJP`2B+Or;K%-G38JOOLIAUwt~Tk{PC4}U#g6Gn zZF1VJ!wG?59T|=tkL9+M({bVe?=xuEDB-^-fc+e@HGni6ApKSZthTDBS*sGY#Nf{p zv8Q3v04^@?$_p&=(S1?r?{^zr+}z&S#6M8Ron9wZEYl+R(TJcT-#ohdXV55SjR@VG zfIAd{F7aC)uJ{qCWRPtqjY@ClKoaXnWN)H0&irzCL1X!ZyftmPX?0o>q@U3IP2-A2 zbrv6)WjZ`AH3l^D3ft77f7pdYsU0sj<}zjS@l<%NJ%ykf)Jk#|pOeVslzAb2Y3lCC z3`52_p`cU$PAL(Axi99i^1A5y;#CMDdy*pi%J2G27P2K#`)jg$c+*qqyZhM{OlHe- zii$U}bgI>w#=Px=0J($l9X>>C+Q1SQihx*Z7(S) zpEA%61YEbssO~rfeDJ#(pne74_l1w#k_=_pN-{2Y=L>d5Cg{f4*vg{|l1m_wP%B0E z>%BTwg0!!4+61y%-KBBtKtQoaoD3Fw{P6B&yxTTW$4d%%D5CuNJ+X*;L%+R15pEnP z?^VLP{;-!wApoB^_>J4oF3KZLU%S$elCC01du63EseG8)-j>4bE`HowAfk}x4biKdYGi!^A zT{(W%?W96N(swi4SbeUEgaD%F?ODN(xx{4^DwaUp;e%ZUq&!@oACP3a5F5tekDGiR znSjuRqpPsC2GunZhsv&o1&e?|4^2*7jGaoS&O(7(S(yH+)*^ebQd`qB*!iwEGI@U^ zAMQeLgu7EGtkI+|4bF!ka!aVy->wgBv&sO-yB6)*qXpa}VxtF3_D7TCdtB};_uDI_ zzX3V{VYO}fWgCd2I0Un`^zGitHt7MKI%B@ubdc~q=v-ZD8Xmwg+oI{X@#;ovbZm; z(k6;W4uKxpK@TpJn3sHDHA?^}sj%*B!gD=u{C(Pl7E0Cwtdm4C)3QOrfX=eTz=W~D z>zZl*?ff&G9LMqMWu(v1@mj5BH_(=v^n*EAGy!c389#*8AdsE*__D}>8ih)~VIO$U8Jr^tkMS=~v+hlJPbP#(AJLH9t?oNnss$t{Wa1s1t%3=S))bnYNwNU2UR6cgPNow@` zI``OR-${XVJiMR9W>>MW?3m2NU7Pd%+e?J(MGpmx(_?;tk}cG2ldR7dzbzwBSp#L; zISTsHxxGWmSiM%Gc5=J+`#lgpwW}?>E=M>hJ|zzx9=Km0aC%-`AyA!xQIF{|IR#3_ zhr_r@jT5TKG;a^=D%X!|Z-0rUbMX)h3i8{#8~3w0M!6)*CcBTYX1{A+#REk+2hv_n zI&S@{9uJXA*?RODDcKmvyUL<4()IBjC%CUn=eE4{h?w)Ou(+f;Zi-X6SsV&%`=F2x zQ=7xeUy%Sd%-DHJz)`bVslqHA#g};=#eTc|5$oE(X~oh213n?~IQc~aO{c2p>bXJX zi0N=Y@@09iarjmqolejZM0HRdN2eepmF>73i@e`|%tK@8St+D|$MbH+trv{>eNkqJ z&AnJ}KJ_|XPiz93&6M-uJUlV3@>GMi_O)46&3eb!OY1ALwdGjAa6Ft}31};a=(E0C zLxtRo$+L@|8M~wF#t8-;j}^1T78~0QSSGtcS4{9{ROsEZEYc2PZn!r}2}wUmLnh~> zT}&st_wa16`K3fQBWBB`=Rx~{`Xbn#m%{d-^~wIhu%-U@vKI!`ohOufwy#tcOqQ(- zve>eJ3)zPZxu4f55z7yj%h~&Qh-4zDv70YjuKMjt9P}#JL{%}=$v|^=V0)g)?O-ibpE91w6-pg~ zqXpDMUhcM^UINRyk;UXj8G5KM^kwTFyW`JSs-1_4Dovs`yZ8gvU{s6cBAC%E-fus` z(fSNY_bM&CbFAk|@Yls`Q+|x+e@G~|ejZKLDAQRqP%GDBEd_Ej&i*)(EZU9*^@nqp z(FbR0-#;OEsa1arp*q@iff&tS!q^-1gN0y`|5m1fBmWa%y(krZ#XGvS3wFLefjQB< z5l_NMxdB-G0YLsBuvg9SBGC|DH5kS!#qv@pp3p;j0g+*1iU0GJ0AZSRiU#g_=1E|uqwng+RDn%|iD z_AB0rT)Z-v_6cQg(FA4 zwOAyb{)JAXl4&d7wnc$jIw!yQR&z!%PbQ0Avuf!wEu{6Q$W*Qk(4_AoY`d?LwYs_{zb(<$2GZEs3tGmSU; z>LoUD28)Dym5C59|9&Doj75Z&1#-a|?hpZ2RSO<=<37kJvkM-{vCSntYL`)`fQ4!B zTsPbUVXgQ~8`0^vyW&>nQuXD0Jh5L16!p;dayM9$(0nArB&Huh&SRq`jZ~TK{>3|v zDIqb$o@~HdY<;W~wLKU2RRa{E((!sbv3y!bs~AH<4XNd9*!~d)Xk->|rBOv4n3Szi ziR{3h!oH>J&&%~dv%|ylF)OS|`Rxh28Iu{X=m`e3M|r3Qi1rqMK1Lg@=#7{{ym`pp z8c*r(&wzA#KNH0319Z15H3;gfS?uOOKK`y;M%*RGqG!*O?w3~Q`Q%0(E9j-6)96Yy zTdJRsCyv~D4(X;}Nn8PMZa(uEkai zIbBw82u#R#b-KuP9PcFlm*L;+A6oM}Z#UeY?xY`%8!5W!1MG(ZrYwSChjG62$<^NI zW%n(SH_4jrPTLpzI#$Hf69b~%w^f%%L>_y9TMpw1&Lc5-fw;IjYTXFQ4D1cS#c(k8 zug5sU*^9&_34Nyl(3TrUP24M?MnY@R#cHu_8H`IU&*L?*)BTxu*kn$*A?bv#&b%A4 zo5kd{!js6(i?3A6$~meP`1tyKVfr5t56TzGSQze}nE>C@*?Q>{1sE62lJv1e_wf-6 zU*i~YX_b>(-aa;tjrs>Gc&>Hs(l~v5;>?9+Z}?ZX^urEJ`~({IP9okTqIFO2h;>9nrX%C+& z`Z<~ahEk4khLzY6>b}=_~!0KP5 zpi%j(;)PjEXU~@!-mBG>`Y6y1+8(@4gQ2@{Ejk}mIc)p!hT=HzN1y3xS8i3AzyuK( zoC4R3$q`BQPb$6$T3(KwLzl`HdzLikXPx6G?4v3wcJw5=ekWZu^5ZF=-Na9 zjZbNdEEx6l@rer64Try1tFR-#D+Un`Y;-yBRy~Z;-$~~_X(q$;9NrPr zn}3n5?HCewKassLEZ9MOK}DLg5qeE%hmTU3@O*W({V0-`JNv-~F{g0)SB}QzYt9x! zon!}iiI(P?>2TQ0z9+rF(_0a>Q{4JQZ<*Y_z15>YorNEvd+a?ul|qITQ?=}PoRJx; zYsLZuN0d>RkVv<<^T`oj|8LJ{X3_N+iVqSj{=H^T<&i2oTxDt%(#2Z-tR7R)L+Lb) z2uUWrZ?}IhM9|cpwOFpUk&x!TO1Su`ddns;G=6w}c_dNs-HyN#=Rr=$Vws!+h?SFL z^aI_eaTFhxGp$X~kP&g7A5jWMQrROH_3w((I4s$iGZORE>64{(WigqlU0S^@y{gh- zMC+>Mmyxe%t&=+6f#>yGr1(5V8P!$dXCW5t8Z2VhrCClBe}58Z??kosNa5;9Y)$ov~%!yCdXhA2%|1d{nnVxj6dRa%Dle zCeC86oc9KannE%fEg2Gz-89kd9^k?M1VcZWMP=UwjhIdq%FBlLKN4SN;&UDjP$vO& zo_s!5r)UZe_~;ko%hY$Wl%x!m6pDkJy+K!*Nh1%pUF1KkuE)ta%9Yv)v1nD4`d+-( z7{-UG!MPZ{F*ustX)fO@-Y3VEo<3m0?nRo9+tR3S~^TWHOoLwTlAbV%L(#nPP#u*K2F zz6SCkBZ2EIFU=r31OP@po^^_okyB-EEWZ8P8P-XkjltTCTB9qYC3c^{8q)C+Y)0hB z^JIg_Y&p`;t&WlBR0`-&(_zhc^Jpa9!T5WnWIMqBJ1a}SY?(QzZ-GjTkySoO5;O;KL-Q5!)xa%pp`|atTZ|0jme-8gbc^5;X%zF=LBO58>#jAvqob_L;8T&ZF)HMjc3EIG{)cK2TYDo&fsqD;ObC zg!ZuC|YgubOrcDvgC?X%^&L+&cZjy1gUFK5_b&%PaGI-VC?*8q(1V+T;`na=lE$7_ch8;X+s=T?0^kERRRk3(7mo}V zjJ#P)aN^HbW3nZi>uPJ^mN847={}x8AqG1a9e2_2FE^*Yj*3Vu>Ybh;51FX#w~{Sd z{F(~#Kn`XN0P;biMTF(AMc)}#CncB4@)xCJRfkGFEN|#|Jym8hOzVFy(RjSlj=m+= zHf6e^F1S7DA~(LwSxFp*Ch*kl8@)ZW#eZ}Yh&sf*keYEw2#i{C7ws*3y!-C)wv=6r z+T^vSdOqf^kv(l#l53A~{z1F#O}NqlcAa$bplW9i9QieL7XNB!X^+7?{%(WXypqpz zht09BqN?)Ys#TbHq94E0QLcB2RY@-0TeDCur}Jj%bMX*cB!5ol%ZovO_}Nf|vd&_^ z26epYeJH~%_dbQvA2`NNpE z0)%}VR`!;6mNk6=QiC=e~}aOxU(3(Xih0g{gx}# zTd7p`w4C4hMP~qeDMrRwf}_1}CL7=QdsKTWmHxcNLXw3JNmH@@tUL08&z6hd3Wvi2 zPM8oDV#Yw+aTIpb(iNRXyK--<;~zr({2|#`iv{WG;vS9_zgu@AoxP-bK-6=UIEVKJ zXe;;v9?Sxuj~2 zc0c@{H6__xTz8jDG#>&gGA9xWA5T%e;FvuoxLa5!`?F)^GWY2K;r2C^MQc?$a|)xH z(8Ae4REE7yxskdBGT(**<+i22STCT+-x?yzamyY;;UQ~(i+?DJ^LDsepph8mx_?fOXfvgrG1J9A-29p!s&dMJzrA%l-jIst^}Lr~S!}Uz;ad=lb%@m7 zASXU_9ZGizY~WKnexS?AIK$ZRaV>JS?smUB)!p+P2v_kw=&-@%TCgEJXSzbBO76zn zw_2)J_pjR@BVKIh7|f1j2_v<9d5l61K0~0)455Q8 zFz*@E?Y2ZJ7eD^#d$e5mu`7j%Ql;WT&sklWU}|*-3HCv>pEcT04w*hg(!aa>K<=5Y zr5Zn={0heH>R5nCH6-5rv+DBPow2iaZV6a)<61uVE)6vqF>!+(05<0!HZhHe`W($; zmNWBn)M%p}t&YC9jhZeGCitui9`aF*%~B;orj4=89$dOpR|K<&-Bcdi^H^^1u^%|l zn*xb`H{e3e=&H}?GZ-5<+^{o5Z-fUHaNAjd=XHmc7Gq><>(k*m5~eQ)L}SZ$>*osP zH(!>u)_?43^&qj?WOt--Vd1URqlh(@kYLm~fkWQ{$;f_Cg;O(^DN4O!m%5={FzNz5 z{b_lijXw+QBF%wV6i|}o=8j9Q(#K5Kwhs14S)7^No*weR)5b{|76-N z;Vs5{$vyq`)+UCh*FJt|sFC<>>+#g+_uWTQmxTRz6*h7!uw=y8iG)yNvAyWM3cd zC$x$c*L+MJE3Vnqw1q)1%HfB$tEM+Xv;LRibnB_u02@Kmy-!u3qzMseOG!Rj#i(7{ zNItL(6e^>@>wUvrvCp2}7eiVvA#;VGU2D#GAbX&- z3-+*`gOWJO)`~N(tFt*NVt9*TG4xduJ%V$BPtXG6$6WazD47*VnOgazuqU&=&8D9* zENoL%TxfE%%Urc&B-x~6DS|(0nC`~Mk~^)ArgqzeKuoT4NfW44Wxvg~wsa6Gyu93S zyWZ3LK2(UEV1rzn&&mBUABT2U;PKQu79)cd+v}0#yAM@*bRn9m6=7mPH$0^k4D3!< zUSesFA1847wUiW$@H9cvfDb7Ag)-R63js&nbTc%H`JWXh12pruDvuKl$J>5S#U@#q zqlJnu7dy%Kds@9@3)Q12-l$QfaaOC15gep@OkAh5wd(9tBBq=C!IyP!6lQSzN_H1J zq{=bllPu1>&;jr-8iv-4f^}L<&MdMZApRMJtE_i6rp^vnk35UvSIk5?*I83Xm}+4 zh_hVVI`$D51=&H5Dq)~?tK-sq9-9w-4CxwuxV5iw*12 z(RwNpmj#+Q6#!D$bh9TUZ+ndfOWFLP$b7@0=;5c&yh!>p(!(5JZdZHpP^skO@uYQ` zhHFM+sj?Gy&zBJ=B|{={y^y41t9(zHeqH9&b4XG!^ifBa*+GoscOS0^e{8m9a@3+c zYi6^%#gDfqAxgo(q<-|3=&Z1my^Ek*`fS|Ue%-f6VekP@gXKQ?U?fiHnct0z?eeyh zdHpG*JBdnFWE8<+i0@^5eTNIopG?24u_BXo#Y|b9xWa2P@Jf_dV|ep>z(<5Sx+C`M z(3j7>Z|O<7eu_Vwc|Hv}w6xR}OW}*=K<94o2 zi0XAYO!W{daV0U=txpDj%B+VpB&of`BR!1FI;yx}%j44qRRS_C)eaOWguYXo_l3ZX zzmDhx^@lyyKQpfzQJ`>ea~4fs!G=Cj z)8jl|+4-M;E)s(&e$FKF#z_{nU8-bq8R$1p8ne@Bb2b#6gwob+$_>m3Djs`=U8sv? z^5V|GT;D0piM7tl3+KqN?)FxGl=mDqbjr}}Eipz^7BZ4ikO;=`b0 z9!o{`TN~p2wNDNQOM^+r=!KzJ#3UD#4DZv4l74^r#Q_c&$Fpnk_ta+1hHoq^=4(HN zS7VYW6VX9;;tQ#M`Mf>lNS|=k+fZGI$_GK#_(NVUUv(>gYb>usFRt0DG1<3IACItP zS}s@QyM=7j+Ynr-HP7mZynBEsI`Gb9(;YK$HrpiQSK3^>_ziy*yW|Mezx;*FMm?!O z=mpwcw{5W2$5PgeLpUZs?T@re_8zJ|e-sGSDUksI)&igZ%imI28H1uOFtBuleE<| zuL+uWA?5la`twut!Lu0(D*`sBI9f=}z2bLI_1mX#c<`K>q;-PUhTES~KNRp~!gs2yLSz6CQA$CXv)Z&z? zPU6kwdUp@d4KW{J!I%JA-=s52X-7kSWysJES>0k=;GpXhSzHtuT_8API1UBlOJ6S!6(QgW z3A@w@3^Q-`2t(ur1A=k^=?nvFoeiH#z`wL5j958|u_MpesE<$M%NQ43 zXm+u)mNp88!M0UWvRyGaWhiNPl|O=*gy~K9O>?+Y4x?6cY#$FfT#M@kql)S5fh(O{ z4y(GSI8j%zsmn|2ICYzOR~;uG{9BDwJ7AfRpx4$+9Dnuq;dcBLTSw%NdTTyc;&&8t zB)WxBKEmt}izpA8_pupyD6}7}boH9_iDoR0ym}#en735c9jpBo;>M`U4@upj+N)DF zg5g4~nY~)s{z#jd0#zS$wSTv2)eA_f2=a%HP^gtB0QPAUJIr$Qb6b{etyPXPAG!pwW<(euv|r2@P|ZM z(asLm+0SVHKR~8)uWqB4rcpSh&DvsP$H_0@Cm(l0%r1J}K9fpzk3%iV@VH$nYh27q zZX{)DV1-Mt^44@3F9S$4SK!O(W4rlFXo z_`1H$b(?#u`YjDCmgsvuc+EC-(MNSvAA}P3(7`ajT3V~b%TdtZoG^d-nJd{&1ouXfJ|$y<;433bH{$QMW! ztC`dzw)^lQc~p&?S>y{oBjh%VI*DD^wU*fh-R(PA4YAzZ$h1Ic%U*f8jSlw;vme{)=_25&Ztc)) z=`;%rx0n|D{<7KC=IO3Vvf>?A+)2AKnmDtbaVxjk_hIPSRs;q#uiF;4~ROjIgW)Kwi`6Kc>=q$B!lOT{Z2+1we)& zf*G>$I^SdWw3Gf=ES};F)KwqjS<=$UZQ=UVd-w6o=)S%-x<DmFl}b%OduLbNGc~@%7DU6DnNPi_a2b zQqCJ0R1(;g*7=dO>!#&vGM*}F5-@!x7CqG`hVW#_frg{AHW!w!9^*VG%QdtTzZ45eBVZQo4_ldiPgj7;;0fiE zF*L2WQ61?ilhM9X4ja`MM;we?zu!5QoWO=QSqKguEyaK!@!+S>bI@w zot&yBEV%_IRBUSM`q8DG{-9#woYU(uQrnf?q17s3xAg|Q zeFQ~jZ4IcDN)8@u(*b6;(`_=k8Vep@K#0a(3%$+j_0eMqr^DOJ+MnI zjE2{cl71*9-Bm5RUO-b!K?t)Wsm^>a&p#-@RbtZU>iA~^CB6A~ed02?hbPD5BMdfr z&4Jp?uQ+ncRC#4ChjW(>scm>48Z?~30Mj%1fiXMt$uy5kA!MjZ`x<^4u^BVVjVsFe zj2G;rNyG@;0%Y7~+Z4&7Xn|!E(ZVv_!F(IFtz^?B+HZ+mgjsq$TQO}`kxfD>ptLB@ zblf7wR$ck%XVaW$Sf^YbF(#*%nRNVwJ?%e7dX2d={tQ_wexGB2CKE>rcCO&ES79cu zI4}#)z#U8LWu^!WAXO9B%$A80G_<{_LjNN|YB(-62N(IHMwD!3?CB;xm7-#73CoXm zELG4qw9#9WH))S9ow4=0iRX*Wbm)=p(&$O;j*TP|)2G64)Uem~OL=Ar6yZ8($dj<^ zy(r@Itsd}^R8lTdiOf`Qoeuw3Ugu0ol}g$hG}_dhgL|$VRyaTTV)-7ha*Bl5Y7|T| zPymu5JXmC@OVd5 zoi*+p1cz(8I|v9($%cYHPd zo6U;#A;1AbryBu&Bcgg4#|*Wnh8@j2{)?QfAx)%BJG-5cX*t{OY|YwM{q$=4Dg9j| ztjq8B9k9*ohvZFNreE+}l_3x8w-==8{CfBN^jsgum7&y`jKqhy!tWFS0XeDVe0t6R zcU&pBTO^u71D2C8J4g}M0bzx5m8_LIbLH0#)-D?=#muD|Xfj;`+t)};#wkIxy#k4( z@SQKAVyn+Valf8UON1}-{m2mhVG@a^%60J5#7BatZ?y^Yln&?J_Cli$>FF}p>78(d{u?qZuU|G z^!gdR+MJwjN6a+pjokc(dO8?_!UYdWEL#NhtQjO=B(OUo*=sF(>j16%zC$~RjWDPX z(8@_s$Yii46F+t5Jwt}ezj=EZF@+eS65dQ)72yoEcC-u*QkiAb7|*T%y5GHlbLo16 z0ZF8}t*pQ()o2IuE8J%yE3EKAjhiW0@Y|&hT|lK=x{$%VQ9qf%Tzc;jnG^2<_1Of} z0I0wV=YNN=fn`Vx*sMY%FzBg}NT`xNx4^F~U{NTF7WlNnkhpdO^rGQ#F7lDG8l z&CC@n{AOTq*6k<6DA(KT97hC6iplDPN~fcBAP@C(jErEK&Y^l((GsoynacF`B>q;$ zr??RL#iJMs#{{m&a41Hpp-iP8)wh8mwOGhE^saEXeItEh-3`mTYTK*PV4sq+51V+) z8N|U7s$T$RNthCXra9Otu%)~MG8~5iIU|yqqLP)q*k-LBGKpL#@`?`qs<2Q!VPX9P z42AI9XHXb0pagG-vfXC3xsi40CGz=Tdx}%D&ACGjqK4#OJIFx;({oCRC}4hT;I$fX_s`f1KRxhCC#)sY@Yf zc3lv)hywxRr(5i&=jdv4`~|&}^1bLcf9LOnZZZ`4YnE%G3EhxM9PTN}gZ8 z@O{E9U{e_e5cc|xgO*PA!oFMwqdPC?q*e_sJsekc4ZxoF1cWTP$N%vM1{6E<^~KAL&Mg_c_5S7El%LDKZpA%-GU=1iT*z`C)f;U4F?|=0FEVMH@M* zq@Kr6D^BszZY1eJHI(~Td~mxb9t7*>fMb+@7k7Lx^us5IvsgftHqit*QJD*&t%X*; zce5N&+traQiXkpyBCUz&iczQfAs3W5=P{h4?AVXz#)?`uh|-gW9ZI2Ww)&!;6EIIg zQ+D;?OMws%P&z1#JC>_{P+Wbo6hSC~_e#c4ub>U`llQs(vmd4T1IhKREpS zVva14@AD=L(O8Qw_*@RrQ(G7G;RIQ${#=Ywp^Vz;WG=~ovF|gXr|U*glah2$DkDLO zUz(WMA2pO1VzMek$9%cPgCJ%q85}+h2pan7AbhAX>FhO*iea$K%{G^uBH1jmi1yHK z1I;d*E+o)LYgT~|V7p-c9Ig7B2;Wb6+!ZHvyhvbCcEV5wKWKQy{X~3j^H^m)z~ilt z5}sOS=0xH0{CZzMiOG-!&vwFLQCX2TR|X5U~o_iK*&nQ2PF?EjPd#T*_}p6Zey0k zAq)|tzw7RsZevcs^-%8u*ej#y1t{&Qob(zX2N?H05czb!0`YxQZ+c>6Dcv3?MlT(| z)@FrPyG;pb9M`{B$z~yb$p#z^Hx_db#8t0PkaR%ZX1b)HhPG1MKWppa9!WN z;iLbA$1e)_c#{&3b1095VKa0_;JFTm&ngV@{ButRi-J4UCz#J+Xfcgw++#`WcsdwF zdTcNPJ>^AAJ5dJnLkeA8`z41)vpgsYwb(IWZwkzah{jz3x*n+Z=MWAOb(#)Dpuy4m zeCxS#rIt1DH0*3l7t9#TPDGW2q*CTNXQ=;BW;+?Ob%?CHRAD6 zL!i;9lfex(^~6;VL%mpT_lhu=yfsBn+ef)Yw%v(2=``zhJeu0c_`)vffudtg=J2LG zt4V*z;&e-2X*ec7yzfi(2eG5J$p#n~4N#1PV-NzzcWpi3ds@JYzy_&#z`@~Ms@gVz z(2KLI|LRC2B6-SvLpa>c9dBU*sPtvMv_+g54#$)BGb(jHyA@)!W6N+Fc78^xhN8FW zlpzSQ7_0ku{Uo}eg5y@+Xr(dZwXp}MbQSE<*M`u#zN3qFy29-{(BlW5`llu)Xv08DRi%wqW!Li2#$*NIxvyDog-qTrdW*SC^ zIhEBKQ$gzn9qZoyL6?#squKD`aeEoXh1_=oL?gPajd|Sds$b;N^<1R3Pjq_j+?Z6) zuTRF;#?Pk)v7lUaj>*){-PO2&-@OX}^*_v>0$_{%sMdgzZw=|a;3-s^Ul;7hwC2=1 ztM$RJa1XMj-7UqH-QSR)23YN1{Ab46?#^bHrBeC@nwlO693v;&e&t{0zRLf`eA?!4 z+pS^dgS7ByL6PNX6H8r*>;~ic;U;eSyIdczl@=JDDA8d(Z88Z8py+KJD%8VBpb?v@P1M(?(v6_2m^AXe%1aKZw zlHN${T(@vE8t~c-`kw8{;;y1VVD=QgJNtpn5A`+%0LI8Sa~YvKijHj8jS&$Z=2{2C%B(iL{IpOY*Uhz2VKQF+09Zz3st(_HA+j%b?o?P4aARI9 zTivU6o*a(m%uii%meI)r0{U0)Wj_{srQf}XZGl*MQec%>b5_8Kk#Lk>cJMBp{o z+C7ogVkL{y?>RqOt#)zxCR`4CBMYWKhk&Y9URK`C&V%?_?tE=a3d1U>4M%PE+j1V} z&B?Y_^I`OxJ@x7ZmXp8};u)su68k|msm!bfL`$TJcW=+yCgZ|My?I#vnqy;5CS3_n>Ase|@Uk2hwl0cybCLJ8T@UdflF2ZXZSi zoQu*Y=F`irh-SdMsr2r{e}u!{6uALC%H%af0}wP^{7YTiI~Th{j;Cu6P3}}BvnYg7 zIXOASMgq}3*S{2EuYjs)JRY|z;+|)^z<;|i5HLVDTCCY*^AS7pUwr*Nv{cQIIGoSe zsFaHSCKKr>Yk7ewUMSDyO+bU94XNs$DKKE(5C{WTZV=jC67(kY>%$@byGKAW=RyiV zaR=dK@f7DQRu-SMTuP?*^HP*3?3y^fy?QlS^?{AV7mk*yg)z>c6I{C#5DJAT9nmo= z8sO`4z~gYw<@+M22^?Oxn*&M8cD6L)tjql%6f+-L_%@kMGa7r9) z)H-p^S1iT?b|fjlAWa(S2iQ($Tj~zY*H@BcSDUP!;J+<)qG&hUPUD>|seXjTB62bv zjt|0ODW80C$Bx2a2+!v6lI(DIt~;#D&fIZEC0AA+l-(VSBDc#EcKkg<>V9#uesiJ_-!Z~szUNBg zBPI|GJhzte{O6r%Vk?V#zcaG$&p(%+HkHa>01#eSh};(E?Pn3mRC-XaONq}ZQQjk9 zfwtSd65REv(OK+0{{DfVdE29w!;p3zH0t#LjQ771e zlhr1LQ)?Yh)h;x>!4$o zI;1{vdd#k~=MMU=s~=J&7vF!&dy@LGEvwHSkmg<;&0AdW{YH^Qt$z_Kx0z zll=)!Gd0VN7XNr}%f)L?J?NdqB*t2%Q1OX$=K}KEYAa-+WI}eMB_N%>$7Zlk%%sz8 zOdWF#L*@vF>L4T^>+AItl*Z8YD%#$~XdQ^Vx?@s&1zER8XJ=f5EhbDm7$|MNk0P;d{Y&92dUvcy@-TQgJ?j{{0UxLIKXbp*Za1;QdTdW(Yv?6|06vF8TbcpQ@K+bGJqtX z*sl12uMfztmPVmQpaTnmM?J5v>qYe36x5#{ZjwVF&nU4=PvMbBo9s7?*xU1{4l_g_ zy%Y3o+Pj~yQ@%?d#iRYk=px?uGIRS59QNt>md7HEUM#}f{ASi=e?+BpsNV3bQE(gP2$>21TiXUY*Ns=JUIEYbS@q>TxV_e>8K3E=qS8tztzo z8!$ObU~X&$vMvBPm!mlgk|NP7bn@Om;xgyMJK>iH!&c~cMB_u-yvYUAK)-O}Q_S8o ztrq*0ppeiKjfVLCx92NP4$jvGt66`O$xKO+d$$lfqMw^B7ERRF$|dp>v|G==@?%O2 z0J?s3)?_pUZ0>jlfVn`$QPVuI7R zM({?2V0sld{F(8<>`B)9A}qP#m_jAzEtx?GgUfwiCY!i#eroLi7pvt7OZ4)#%mqVF z5lsfGTFpm@NYadddRiIM2K;v~xc@(#j^H>&bW6Qt;S2YzjieTRxjk!Ov8cDFuY|M_8i|SLh?( zfbF(OqI4by$`?k*>LDaO-bCJGU0inZiGfc7s)@eHP^=Jhz8IFYLGZ%RCvStVA4lTHtkHPp;rKiM#-`Hq<^0*d*iL8#cWjqVYtg zdapZ?^dX?zE_M8^2w{_7n(#$2Y-gbSrf_|=sn%=n7X!mLAjOIEK3Y!zIHr{Q=f46L zarUBgwfBlj)H=Ck()u|FmK;6}mLsHzA>zepHd*HfhP9V}zzFn>#H1>kxAnj1aYd%{ z27`xjL(PCUe(fEo_kQ_sdvqihwk-c!)<8IBVsJ8=+2Vltp}Ws&?pMtMcVIR>2e1wu zdOgSWdSAia9It9Vf*$&YZ>NRHC&of26#aCPO<|>p!ehxin*Tw3Cm5CPq;}y=;Y22v zCEMqXNjPT9Tav=3i??k0>fh5WGRkVdNu%A)-#b8*S?+VjdmIj&nLUY)2cjC;BeSetInJ_h9WU%lvEGg<2o!3 ztG`?AUy{yMNSTJ?QYFuMUk%#ZJh9w_q8wT8%C}4|fg|7jjO_t8S~DEd>|Mw5YSF0F z>JVM|Os&RW_A-o@6Wbq#GCXtdA40l^kd1?g=%-3ef;5@UDzzh={D<$Y{)Fv}X+*JD zf+hjn`-sc;@fKS=czRw-buq~oSsqN1|L?cGlNwAs3q;@u3W^(IGLx6;n78fjC-Ssl zu1hktb?FoEnsC1wbk#_qw9YBUW-}KUQhTFTZH(j|A|@RmW(7$f$chfw73yO5yf0y1 zt@FsC)@Sa&CjeMDiN-Z~8|8gb#P~Vdb4_w|8eP^&zl5f8#{3-uHk1;N#iBnCw^PX< z3lvU1ihX>QKSU-+Tv3B2_ah+8C6o?;$al_z0Ol!hrdzXwzVi7j7Rtq?vnGh#6*G3B z6WVRJGrM9j1Fn!lNT1U_p^hj$IaloW=T3D`z0*L;l-i1JjO22-$q19-_FMiiHgc1R#n`^rj?5}WB+QfEE?Dg4>XsJ!zF zHk(x(V)f6vn((J^pn3v%y-|18E;>IlSG5Tu2=z6vHi+6(ZV1XVk|+pf28{J&C;j&H zAwLj&;1xhyDglLNBiN{=5KTnKpF)ElWkyM9Yn>UIeL?8mrGy*uly!lQMMJ7Y}V%z=mnGkji8SM`p= zrcLrYM>n8wRQjkLcxIXIdAJDlVtyLuvUv!?&1N?LB$G!GZ-|0dv^yxbw<*lSntsco zy6E)25dAeh{pdnL1h0s@HXAFrN~q*GnInUL?sgU0W0aXz{hzW!k)t4HwFK`W+H=4 zY@R?$+^vND^9e%4fu7s({1l7ot)mW5EffEYWLj*`?2p!VM(}(>I)coB&!WcjZ+dQz zEdcYuB;>8pCh*abOrs2Pr8F5%ju@8BOgM`gQm3PBmc_r`a>9dJPSdX-p=2 zUCp2bl?7>aTKkzCbj5MkU?w6%N;I2vgcMr!xg+-u3C-8gUpwxma@1|tkh$|Q>2MGg zKi8RVw`fGb9iHQKc8ymfldNckGbX!El-RAPOC}a+bj<+Jp-nOlkavJuJ1f{I7N6 zZ!6rnF><#9N8aKV2QHz2eyCJm92I3E-4KeF3zB_n-w%XVpe+aoPq2}9Hm}=bef?{fdWRbSR5YsZ^ARLFRJV%&;(?c?>H#be5X&S)xyXEZhE98*XogdO1SqzSyFoHW*)%A_7C>OLJSDbzy0e3w-Sha z=?gKJq-=qJY3Fyn^}0LdWH?qNOz^f~Vw1gb378M%S8}nJrx)SE=iV`PPIZh#)^cqT zaKL3|(-(C32wp0`ZLpJdSmJFgPm(KD-X$aoRDj1zuRJzsfDwsTY5Z;!t zw-v*9&>rsU`DStVGpDlIw~gA0J%8a}qCcS~elJyendX;`*Fs~%XEd3~(7ir{0GO=t z7ADIm7S^OJ%l7SRUPSU50m7k}H?nn-bIC0Qm%$g5nMv2Za)q%}2BX2#QYExPyqm~I zV3y$E<~QaPpR71xn+-@x-OsFe2RrPt1Mr^YC+s`d0C%T-Jh?Q+p#0MU*p1{2*2=D9c;_H1B99Y;vEbq$U5(C;X#i~yY>Kg$3wo{q9wRR^dRzo}T z4c}0tvYQ3`M$xVeHkwriLs6fqRka#w!!Q7z)h;d&)NHpSj-g(T&*T0X2KC?9l|=ru z8PfeReeSj2yL}0YSHmB-1>>-hf`#|KH|13Srl@4AqT!s@-0VIUrFY(Wz~1#g)c1~N zR`TTo?7~S?MHmil3seLE8Jr~Nk7kL}4>U(W4YAJc)S{#WEBMk?R-RYs7#r-u&#g|3LxdoT$C zdS|pb7QMzU{{w3dv$~Zi)9AH{ssDc2#ja(PJ3qog3TFyn;7=zTS(9WX>@Wr`Qn0Z2H@Ei zke~KaFzdey1`&A*dfuGYz+|56k0kxrVFbwxIVHtJ-< zXDj!|H@rVjNl_tyQ$4{m7IU^3rAo*(%OJUWdpbD!_75My3#n|P_>o>CB{xUhP=6Y= zZmYOS!`Ct`Z9(Te9lcYYr`Kzw4hbqWAE)6AJ9%@*v6d2#7(#tv`Vq05ZP-~<+Or;nIn??`tmsSNIke)3XikoaB$+lYTD5(E4+)pGwEu@N7=dCr50S<*1 zY*wtSJx`<{a;7r}l8h$HLWeHh+{BZ0DB=&W;)ui{*)1{w!8d06W%D>#4NMJNB)4z1 z3PwAD!-|F0>lz1T0-e!QW#`eEOdhR!U24r{&~SK+%87FY5(zWx0KrH+Q?14b%{)K& z2Fh*io#W1T`-@DU<|9JQp19@M2c=N2F40$kfeRU`Aul<7Y#n=`D|Ub%Ii!0naxk5o zo+%tH9F7$LC%OK@sz>ml>Qhpg#M@9bZZW{{i|{}Bqb+{K_Dw#=8ttFn8jnw_y(m_RIEa_4muyHkAn35$MT5g- z)$%?B==VuSfCMMs>*;oSJHTTYD!}4;*9^LkvfUx>82JwE70q(i$ z{M#Tk2Z`>l!J8lZ*`<@&S;S(|MJqV9Xb(yVxSZ5?Dw*sx6o!M>XAO3amNb7&nZJcs z_uSBcq$WKaoo?b`ghqjf(E;m2AnW)rp;TNnNW!%JeszHq6cniRk#)iX1+mK! z!1g^!_D1-4v$xDcEOzdvaDKks_fBmT?7WQpJsSbvl;Ol94H3kE%xE=8ou-@;f7Q_k z<(`ngy!F7QToTKOgp$A#j;iz3^M8T!5TGjdKWu|mp!uNY=D`nw$yaP zw`msGAv8K5ANj6Dcv7083I=rdLYBRtVm;#5+rxMrm1oeqJ((99>3le_khSECM%1|x z8rcnrDexc`Tf<~c6v$nI!=M*mh@x|?AcU0x@IvMTwFAmk`i4g*=r2pNKA<)7+nYddYgR5tYZ-a0W=VE2OXNT=DBbk#1}&RBMrHv>qgtI|Yqb+Rbqx z_cnxdqag_W^!OnFSv~Sm4+g7CwDB{2?k>3B#pSr>;R6{0F0bV75{MO)J>Ttf4{|uU zk@)VTMrG2M%t-I&I&QCnNM$~UN9t`uG>qblRl%S7du1o{ZB-b^3SZPO_n2)a94$f% z0AAEj9>7t>U3lOfb<+d>B!!KU47Y1<4$sBnxrA7Hncjhb&*v@;hV)+mlfPR zpzePcdU{j2y*5uM)p-%E2O8i$@K=e{V_0JE4A*fv7RBSpIst^)#2g+3La2)Lln!z> zs})N)-SA6b$3`kzi2G3R{F$rzO)d|nQp+mrmqNa%%JShR9WgTOrKsS0eI)GPmRk=n zUAs`i&9~QTcj14A4_itE=UdxC46mdHHVm$)?nLxjxmjQ8D3ILukLHhOtOTndSVz8p z8Tw>~8#$?6B5CTS+u<&A3DX-ep#wHsHJ#E!BH-`(wTjO$$0ymfzs>H7Y#j3B+0)-a=K>l_-qZn|%3YkgnjYXi*P@_gtNyb<@VB?1AK^J5sDmeb zJoA_wIN%L8-N}l|!#k+r;Yp4o_pALl2 ze9ZcPbpNlzbee(1uowI;98KX65yeT#j?Dopcs~y02B#?Lc@0zv=!Ie2;x6Ui%3gnE zoB#Vi{Pe^Lgz0e-;3fXAFaGDn_{9jn$9T}~cwhh1&p?QQedC9XRuvg4_^%ZBe?O`B z|KUXjWg+k;0c0%yoS*;GsQ&Y;KuLjYwFH!bT?Z96;h!1ozhvD1)7RaLLkO;SdfXA? zY9RdhPtPoo-oca;CDZ1(@>um8S`?IOy9?+k5MimCkjlk~qI zpeO!4J=`~*7NGc_?!$kT?Ed-P@8bo`vXC}BmH%{%A*9}CS#pZV$HM>gUh=}f&$9o| zZ;IzF#OvcRt<&*F0uU134(A-NHrf0JaDjWr$Jiwf4|8ciy+7&oNc%39U;YJ+n>+LCzXd_^U^&cw=yW<$H^*$eVGdA~ zJih@2*fp@YA9HxjoV~t$6p3kfyr^x+ss!re=NG^{yV%tQ$MyRwDtXK79+c4}x47l5 z2ZG4EXdeBY&&zkKHeWVY4|DuOV(_LT)9TDNU%~O%0(yQ4QK$mjF0oe{wT><0t_$Vr za(p+q{PJpJjP`TvrCm0gpja&KIQzqzzVr++zYQz#dF>Nx567f{-rzOx;F8@UM*a}(dx|S%jQqZmQN6lJWztws{3GqYoTgB(f+QG8c=+H7y_U+4PA3+;Z5#gsz@ar}H{z>ATT#B%bvD;p!aN z>ulGp-KJ^K*jD4lwrw^>8{5`wIMdj++cdWA#41VG50mdc^{#Ao{fAs2j;d;7hBYW33PDYx4LeF=`@sd`nAE##(%$ATk82jWAaCI6QJb|XM$ER zU6Lwr(EY|3cFLK2k6E;;i>jT@y?*N!167DTb+47BJlY-DcDhSaidTV_KORqw--WH3 z`Fp}06D;eOo(zLt?j?M%Tu(T6d@q28y)MkvXYt4&{PEgc#QqcNMSajqJha1;iU@ zwY2>#6TUxEn?coX>pCIG>rJHX zhLy`?THFb%Nay{^eg0cI<1<~2_3XHbfCCAIY+4$#$%wdEXnc%uV8~Z7`^9GCV*JgW zVQr_gweKN>EE!&F)Ue5XriA3uDZ-t>CPUF+5%V2VQVxi?A^?3Et)8vMoo42ljj1sJc& zMBnw8de=$CRVL8QsZ@53F3#z-1}Vt$c_{Xd_A2zrRli_&kdp z;qbZm;bZ9oHTCh#j7)i+k$TEdBFi~FGJ(b;y!X^%gHCbOGKj(_Vx9xQz?ob!Y3etp z$ax1BFvTC&!dRD7nkkZUyy`11n3@+SB!fOQ2;k|fTjHV z8tc{J4MAhDo^DoF-5vv=wPo+nEv5`Aj|2Ur;gcwQ?elj^`<;O@IqE`%9h8nUX{uRv zO5+IO@{Hyf+?-d}ohvEY=rDFjuA!merQB-auOMgE2i=YtOzHc&=GX~ zA%p?3jM?Wx!Dv%!Jv)#iaegl{n#}f??qgZ)cum+o-%>GYT9>B3TgsP*w>N{GstGOB zMzvULT{v~F3TE#O%;!lsIk7hFyNWC|BaAGi@kJ7QyD)_Ox%uZNx5h&91MJC*FW~-^ z6!gLy3`}UHQ9g@*>l%n;)`9&MD}s! z-mUN_rc8|-r9W6K#46FR3lWdRmEWHzi1)tHUlIExGY*s~7&okr9+vB-CRBQ_W%a<> z&z3G%9uGrF^e@(7mWdl;?xxmZBJ~4bm~zj>w)tQlEb7W-9U3K!I7Tp~>^I^Py(&b! ztrNvqig2?#1`+DFcPrq0N?~#3$Dmggd{}6lo}grRIXR1FCTe3cFuY8lL#LFt3L&J! zbv~Z)&k_A8Op`!Y@bPj-@%iDJ%4*IwFZ{mP=zPQK=m`uIxP9sIbUBSB4+}~%|I|_A zi%xT3o!)UUv>P#BRiefIHo!I#D8=B1xwYu8&ON| zfCBjxFxg>!FW_v*s)KiK-In&ZYazkAZ0-K@ToNLEiN;$;uB_C1+{iTp4%h6_RUEkw251p zUX|L(Df&RHW?vS~KYQ}OF0K0X@84FV!Je-5f=kw^2DJG?HB(P8imnsd9u|+w31DmD z4vv8JHbcY<0+1K$U4gNt6O7p+aBF}9{&S?>ZJc);N5ArRRnlh%e5cOgknis^)E6k2 z7})G?h{xAAR%W}@EcF5EihPeTszW5`V(zsvK}bE7)%^ESS7PzGA;?i48iKC@Qz8r~ zv!nl7suMku#viJyW31Dl9Z+y~R~xg~Lq$Tx%VqHBs0zUXv&T>!PeSR5wR+!`syb_=*lc_|GWFxW~_lu>R?y!Vm zA(sG8`_E%~$r9*H@F0gT4=B2Cy@zvue0e;TNv+r#Q5oaV4WgZ~aSO^h(r>cyj|<1) zP^xu3owqFUcMi){SbeX&1B>RLI}U}wrStR3pGnYS>Nn-$Xr{oeF_M(#XbfGQZOqoM z?I#AkdNSi@X!skp5v1LoUMcg_qeEcIF3qz!2UNaa4<~Uo#o6-lT6z)V5rj+DBr^!dRc33~R zPcDl8_GHF9`0&mTtfwd+pGXSQJ-XPh4~Zs6k{kcjv%uFGt;dY@^9Prt32axf@Tg=WU zl>2za_vAT=ObrMHBnYD$0q$ePuLx65k+MLWfR{P#F|A!d1XYGwhS-o)V7@vB+`p3P z0OdxKZ~p9&`KlM_ppk@iA{HqV^!09=cifKOyvUPiBlPkH2E^3H+O<}(%$xNiD<3$U zIL7Aw5;dZa;LXlOC0Ff8&Ig63KIeyC z9qat(A$ms(yVakeI|A2$LHss+Hct4PY_z`z*8q2Ov?zhcZbk98w)?MAzqbA&PV$X4 zgKjIW*sxY@#fhH;x`}w}_I%n~-@P%7T5uhPa5VciK3cv^V)+bPnP>#MR5P0E@d9}^ zPb5Bi+P?z}+dZnavds|KjX5z&tsDMgde~#IrXz>{QbLyfeo4vSB-3 z&&w6yT-0@Ier|hxR%ljR*0ogNu09?5#%aG{bYrJOtjp_hrI-MEx-WDSYCOau31+vQ z7ftR8&PTQXB=6AbWClu8iM$I3}m4vLaw|zb@`~wWt(-^gJ*JWhlzX-jR zs$T8md-grB)oG&lXC^8aNRw3gCDLijUmwio7lh*uJ|CPkGw3x^d2jFXLy!U{+q|;Y zhrw0dwObbF1^Bl&Y1-xQ_~QIXX$+dXCI;*Oqkx>bqn=%H@k+t>7?{b-$mO%#L#)F zIijUHiw{i;&UVP>>sSSILmG}A0@(AKg=$B&TN<| z<&G&w9OdOe^0U4N;UN<_7L{0no=6&0cnNfhkV&ZM!ImM&{LO`O)&F_OlApbY#fDu% zAPoR8yY%|e!>2k=tL*SXjLkwTcEPB@#gK=w1+uyP-j6a#sMxrtORc2Vyw6`op_r>k zNPz)B%q%0oW!kFph9gO%8a+Vk(mGyXGsgx`Igzcb1d{*R>=cvfR*YjYMf{aODuD<~ z(3lV}EeWvRjB&;o6q4K~I6A??0EU@*U>jwpXK@i#YZ}~T+<6A=Ps%AM4*#0$$cMRw zkLnl*dx37VQXLUPA@%ujSRW>w3#jxS=n6)Dqbudxw!Q@QDkM>5%b~CrdNnZbP;}T3 zh^tAiG&fKS`Q5Q^$^e7+;o7QjieWALm(XL?IL+M1&Av#U;s-sh&U`gSmW}JX^G&Ii z-(SBdRT@c|L+wI~1!vS)&Q8`>aa9Xb>v4E`o2lMkz z@@mIN6H6*W)7=*1LzjJOQJ7b}S6LC5GmFYRsja%!7zA*O&(X-ev6_nJ3&N&xc*s98 z!oN4kcfRes;72eq#p^bWhN!TuF!ZNeYtDz=9=KHcr(C>yb?6!{#dqvW;j3fIx^fS! zR|UYeKqcGnz9hE@Xtg&UO&D&pZo61up#233bGY$Nstb38D%00qAxXOB(sI2aY*$+T zk-#;XO)4JT?&0(~)#jZ3C)BV%h>6aw0yM`F-6Bgu?wP5oA zOG7wOW8nv{;VK*(J03P-4{6!Me>A$ga>%nYSj`3pjOVFC=);aP;^vjn9|^&ivs|%! zo^(9}8;HDmP{^4IiM-U@CA_04vqpXI5+&6J@GWC%o13`R# zgE*_*;aKg2_sO!6Mr1S!=KDi7!saLICs#eY6?x+ zjl6!oCmqF;uhjK$asTV|U4tHQ>n3sCJ>E8zU2a_lH$OXo7KnCVo_~18FWefN7#8$zAgVvClW@a~ZqQCr~i>LHE$frwuLPdk1j7or(D@@|()Hc08%@fduSS&=rMz1F<(=qX0YOIQsJ@=L?1# z0fp=qIX8ddVAh#D1-<75@F=SwIB&aM^Q}5iK9L2F44lFqeH`~A9?|gdu;t+?u;;BR z;Msd&u@&8aSli7G@tREeg-48dM!MjIuxA3NRGt7ytefOdMHXUKe(7R&nkIhD%;R> z{%@v0CM_I#zXDJt7Ip35LuiLZuaiTLf57ZK7>CZGhY!Sy%8nxOI3j3|+n62Zu&G+X zNJNI4G%7T+Hi>oiPE)#-y$ z7|oga+#doyF((Re22ct21LJ#n`0^Y7JK%!5P3VX9g_qX8b$8^MK3f|EsB~_X3w8ER zwll>lsp8>;GSk0j3#8*|l>a0#?QiW*qKAhkpYb0J5&8qOe+suvAQPi>GRkRBJNucS z%3n5(HJCbmbF!7UZ<(8Cg2FFQB=EGGk;H4i2gwy$8 zjo@!-K^^$waslE!4G!`mOsZvCEoyqdyMs|wBGxk*B&_UKAt2y87@8gCfjse*htB!4wK|B30+! z!_MFg?I!_3^RC>{qh2}+Gwb_M_Ut~`>rs9XO76-9@(NsBVo)OlLHv83$g+w(j*q~b z{1=FFNa8`j-=gyK<_Vw0^& zVFw||UGDrf${#hb>IXzy1RN_S69gju5U5HeTK$Y>cJFFKh6YZ11C`B!;a}d5@>|;& z`h>ql0B4nbp7YR-a-nA=(L5Df0HB+TGyaC(Tb1aA68q!T^TmL(!Q;B|D$)x{0O?t5 z&~oax$f{UyKcRkG)cUvy3(U$7b^Y@kvHZC-Ph_Y_C-X^ZuFkX+awDptwBjfd0zC3z z=Wu6*BriZsP7!d$6w3Ca{I=*qu>W_zYO26l=J!yLibx1no!fh1*nuSebabq%A#3m% zV1_13Wd5tT)IZ3GjYWf)d!qAOttJG!Dy;RdOgT{I5yQX?dLR0onG8?wa;HXz$MH_t ze^=c{54=|hAR9XWVn6nTCJrw@TJmLicf8|GJnbpxjdccUd93=2>Gf$%E$IYycdwTg|=ZKyG!B0Hbk$eM|?>&!(~-RP=NG_=L*i~m%Kr$Qro@N4>x{eI)y zeP>OD^al)K1}_-;s+q974+q}t^`c4?Y9{;3dEPu7uTYuvbV_wbxL(kRA@Aj*#GA;$ z?_)OpF+-rP`Lw57Be-}9BKzq|?y>>*0c(&K2h_&j^2@WXG>+RDx3j_ZXi6vyY(n5N z5x^8jr;VxA>_+{T>ceHV62_acjZ?+xtzcR|V^`n}i1-mKG=>5c%$j&7l>c&H zt`teJ%uF(<_(FUP+o^;nSeP*#_ycP3zD(eDwvu4u;vP8N9T`UwxY}smANs@HI3C?} z`%awik(`&51nJp{S(cFvzL3)t8;NOt7WwsHOq@rZc6oX6Bw`?{A{Gcqpq@S%Fec5krf-d^PutkM)NvRspitlkx{Tw6M=Q?3zCw$AhHT97)cC zy4Xs!suCz1ed+`k}MIa+(h6bkZ?qcLE@^CsH3?dFiY1eEz3L`DTBAxBwNxFIxUbK9W^!*_jYrvEN|Vn5eae_34j?w|a?mPOA92=^g-sgB?A>Kr5VEwoy!*7~bn<-IyT$$}mqI`gDM%o18oB&+8 zY95TBQ>>UR%mZI%sTx#w zbHLY&>WjdymghXHZeyq+e9>3mQ2a|G5|~AYH_O#*%a4xdI{GOodZl3z>7o)E4VUqK zw##rz9N=Y-1P37N01t5T03Tr@r3kh3exmO_RD@!{#d-HiM#J+xA$W zv6*GA?1+~3M^|Kp-yH#nl7M&3{Ek6D1t?oODh|OqowG+|h?o^rK z5 zwTho^kdcboJ@X|ZGnh%>8bZIu34ViFbI)>`m*yooV8G?_qVgm%Mv`@1P=kFcgyi)` zygkhtV^~QRRA7P}?TO6fEpW5n#1-?^;+_;bKe7>Rgq?bSg!^dvG{(SUIzXM_Ka@Bx z{@QWJhy!IVlNN~VZTIRc+aHEIea>^pVmhi6W;RZBaT|RszV9}v_bN=cN9xK+E(%cH z(hp*KpM4)9Rz74c>EWMqP`nazN0PR%WpP*2B=pXu?rn%HgbH2=eUT#z78XQV8as+b1*cwE$0{zyJO&zrRt+d| zXLC!q1(BR&V4OkZnO`O_$7OolZedB=nggVcYNve%?s^ahj=Qr?xHAX%uLYnF|MdbF zUTY!}gzYAk@JemZML#pULqJ^$uk>sM>R;~2QA57gqOdPEnMv`F5Hd}8P9XKJpQPc3 zJ5L|5P34)(F!efbG4|gbrwf35)A%xb*0G}8FSaUO0vYF$oD5%vJ(T+vd{;l|Ve2-z zgjX632>-f2y`MBym`ASHT2xs5+O=Tvh|#6qUhF?>ZpyH|xMpvZ?IW31_Z%p89dQ=uupP;}NVR}G z@ZZhyFu)N)uP)xV4*Omqvx{$kNC*0P!w}OHaC&jSXx?5(ua!T583{K8OMBaZ$5S$K za>%6SQoVC%=48RpoOB%R%L)J?aW!-@#b(V}Yo2Y0h46fao6d@?pY;FW0OI84klk}4 ze?OhATj9jv;@Wp5s_x`0->3i!`4MoIKz$TbA&S&%&ap&#$u=5q%`X$t)|rxP+V3f@ zb6Q_n%0j1+1;XnRcSEN9-l zexA*-T4Y7s689yGE)tBflK1p=B_qpNPErcGUkJxkoedOI$weNgt1Xfj3?09 z4U?q@q23L+6kv} z>@3@vcChW-(UAN4Gs3g|ff42}!wtm;f3#^<=*KhgYt+=viEin;##aJqy}j`R!? zJ)o{LfJy;AxPr59r!pT7mLvn=Eo;7h57jHWwVMX?Y+)l&h7pOp^-o*iaB|QH8Gz+ldEJVq zWm%BI!5n^j^?RtGUE+-Am_k_^@eab}#w3f1j&Cav7SlP&)7U}j{z33nzjEAJi?H(_pr|4gio+g4m_WAE3 z@!F-ib7w1HpO*pI$)9N7b!x?lUI|qWX?z)?-@WJ$r}M1tOaT`>X@moFNC-Tt#%#bT z(*_s{#t}+04jB|*+1e%tR_>{t;brE24LsT^PR_TDKd{gLatonS^_WoNcHcxXmPSra zAZjr_w$~Z1p88xzK1JCkksWlYFdoLIUh+8E6aG!N?~?<>Oqy35;p^i<8{bauKP&(( z#K^YrlFEq!$J?UmCp4$y7r4g1;+EFk(nhc3O9430B zv#OcVWxLv7Xl)Y!8A?D?Tl07N6Ytn@%UIjc@w2`*b6=#N&$~bfh;ONT1JFYju*r9#nyma(|j<`n}^)_0+QNa2$Rr-k>Y5s zVp7Rf-wCI=m(;FQqC-L_#|@4JLoHmOb%TLxE56`WX`r0Z z{BY+QU;diD=3ANLlQ(mo+qnU&!QJRgTLrfINE%m<<)@5RWJ4WbRK%9DuMEtnkYK*$ zD806}?7vxSw}k4n05iHTLt6VIy@Ng{^5Y~2s%Wd%^GqXLuVBB7&zavh zw4fFVP#gN@;*U?%uu$a*X{%@5nF&~>AL?{4H@}Z`uTDPoCYzi1hZ&uqJqI8Vgrs1| zN;=}1=FlBGDkHFOSPOV2&RkMr;4yf{$%a@!0ud;$JFhPB#^pq!pF%AD>Y`ec+^KPy zyS)Brb9TG3(s|W?jdVa4%WyyFOkZLSv`1H}*tJ0$wb-l57fka)irwD~tQ6*ae*QKJ zl?hEXAvv8I-ye$yS0{vLBZnd2x8CbZ;wteWlo%PBk(n4KJkJuU_$T*K8Pt!l{;{xt z5Rlyd37)q+$B9=k9U!mnu=R4CSA^XpF<{lFo$5XT&g8>jiYIw-uzP zJB$a_&i~SU&+u>qvS7e6d$^WDyW5NuFna2bHo;^lgRH#o%LEN7x5Wu6q6$j(w{P9S z4px}y1Cp#4E@Y+g&}Y4KMz zrHAmzN{fv1p=NXLH<(lbS9VV(vE05R-HU_kCKqu}g~SF2V@hmZ@i1&Tg89RbU`;~-TD`DRV4qWzUztnf7$B*3y%>4MhFfUX6A=2hI%NhDTmDdo?Gu3XRsT8&YE z)u5EQDfj8Dj&t))MiBCSX)>@Y{VsB*1LMB~=%{;J1Cz>2p!RR>u&b@!c)2O`a**E` zY4xg$p6I_>1-2hD8vjOzJQWQH664hE2hwoeb1+Dn{iz(MD+u54dWEoGT#uH-(s`V- z0EUdr%3m(WouBVNI*U83CSV0Cifi*_T?p_a>4Mq6!vSi+Z%bGP41c1-W8i z+Oih&LrYa><9v0*+Il7MHmtLk(T#e9>k1lyE;Ve2pqwgKd#>HoZHLcLp-atbkGUK5 zGiywRlvGYo{{4|={q>Rem((vQZXa_-vGG4oogs^EpEs3Cr<&JHDhaop72wG)=aYkN z#)2;f+}ZPwYVSXdLbWLG8%`{2f+ngGZTIE{%6i^GZ{{K4(S9f61Krx5yBz5a8q`X36ZU)&6F@=lHukLFu#jx>fzkZPBVaHhV z*bpj7k5)eo3TZ&$>U}MuVx>PCZFOK^|pCue%QensrX?_+eTR04E*7RfN> zUIP%Vb*<4h8GImlK98$v7jrklQk@D7VTDdl_#o4O!sTl7;%PM3#TkOBcuHt&aS^w$ zr4x=bU(75@kuG2p_?%oq`%OX6?fA`v_Cknd`hoc+vpvg7 zcBGx!&|x(1r{VUIOac|fdX(ckG%5daHf2f;yXRi(_CdV1t zg@!J05z>IsPwpdgIA4-h^;7ppZ%h`*#&KiN#O3~(zZ?VRd1hx> zFEdY;*s~YLp?Qd{301eOycg#nlvhvH|4b6z!pWJ$0?3ceKWRf2jM+P%yWEjRD=9w< zyW;kWNPxu<+v#?R6pQms$!HJShZFN~FQ6M^LesR7l|6gy2d{^G?(rL)GGEqoLd>+C zmcC01*wtP8TTAALF&Q^(FL`s(vqQxxkYtNTu6ju0jc7K*6qjd@tNeV?HTz`&f8QP6 zSD8-gYhADA2;l(ZbM8!c_y+Tg&3yzUq19Wtm4 zkqAN>1G}SEnU3X1qug#nHtd8sOPT_6yZW#=od!uqed}%X=>jw)#DJ-ce);N9U~GYa z_wz7BWY=aN;&^n|W49yx?pRA-q|>^eSf+@s!a>p_>&*FQ&~Qr4kz8$P45f_p8!5mW zbYOf`OMjk2lx^!h7d2I`q;j4lA}@-u3wg0UOvi(gb2YWkQW>!-*BiEP^xU2;Qf+$6 zuX#&vaQ-I-0jV{tIk&adwg<-HegXqF+yWcvxJl4WTNW~)g4}A()m+kHyBeE?L9Y_K zWL*wML49lS>U>@f1_QRNO4kcS4BiD?pxX<(J5f;|IRz+rzet4RifC4D=P+$jR#FlG}aTqxI_tFm)bMSi}(zgbjp`IZ2n>mkMjWc7Cvnr zecj;=EL&}rY4Z0#BIM5l=F=z?x_>iyR8GDxRYff|So2MVTW{SvQLKV&lQj@e_5PQG zZW9#<;y`b_CSZJ&+*8!o6alsRY(A`;28^;@5LQHXIr8r?=C4kmA@=MO{YoRp{CfWA zL>(PRQ7K^{$==#g%xM1iYzB$21oe*S}%J1U# z3oEK@)@NN8;&DlRp3&vSC$l!aRYc6~NGw(YL!s-#U$~&|%4CC~dxJEU;=%&sv|=XD z2`W~TLvraAOX&1%yP_|^WPlPmRK!EbW~JWP@e2o+04iDSs!wYAzaFLk))gQ2_^lYlUig`7Y-dxv zT&ys1ck`$xpQZ^qEjz1#1N=aZK`PfDo5^4zJe8vx+aPY8yb@($imGektH6#&Mrq$h z)N<5Zg=X2=rNiF@a+VGeXp%1|%oEYX_&`S^6PY@BbML|QFS=>O$3VQEAWCQa>*eCz zNQ1NhU(^OMJPwO*1gYNM*vQ|F#8xVAtQQqIRg%6wHa5z2LPIsSc-~GB-tY&kX@LQ{ zKOlE?5-NhtW;6Jd^@u?}nowJCL45s(v$f)hKd!zOH~~(S&2@PqB6ifBSR`To&$}4# zKl_P79X0BbxZHtn1ILya*)&KVhLUto*>&UW8PDkeQoAhKS_b1ogeU5e;f* zVPf=Coc?&9p$SYy+{q;cZSS8)WNtpO!ZjP=u~rB0rwh0yg!kn(Wc;rUA(H}7sXW}4 zqg+P?D!Ul|nlQ6Nb{;Z*#5;@7@s?D0ao?;?MMI<0Ch9*H-=yGvwE&4wFS_AYdFA*KT)t^$f5bOJ7jc~;JZ}Y4N_e> z?;)#les$6sA`wRksa8&yL+o2K{~iR1X zZKOmNwqKvFPPR%G2Ik`0B^6G+(R3Ap|M~SPEKHmdV?sPPoQ`=?3lT3gsvs29Vt6!> zk9wB}L#&#}^f-}3-I8LOgXf1c1fw1YF!bEB!46ao|8-Eb7Ye;|hg;`L0OH;Y+f~Cm z{$~M033Q40X1(*+4fA2vm#BoYQ9zDLGu+PgSvV{8@ZOamgASS36&sa0hTN||KQuAy zbDhi;dfF-(=jj;N&2F-&Zx!iA6 zWzXS-Yxa^TLlo2(o}q4O*HKL%Yn1p9{e0ISw46xke3VkZ9EQBk1JI?|=rkA;0dl}$ zZL1pbz&zCEVmEB;wkCIsesyG;m1F?;C8u5)c*h4lpR5z_Av($W4CMbFpQTP}af`KKVSmg6fXx3|Idr)f@-$L+%)0&FRJ zgVdA8*D;yqvA!@up=7SULXuv-Ca`00O3$45iQ0cRF5){h7>p`bY+xGU`Y|VD~Lvt*S`cU=!9_d#K&pk^+>vZK1kLStM zc}HB`VsY(#x;>gR!oyt(xr`3d3ty#21RXseuLp4q6-oIix>Lg)DrGU^8)^B;55KyD zzU5g2X|Vou#Ai=Br(vVn6I%^H6sx+O&u}gFf;C(3NS(3*S}{g=m|C`?%5rOU;=0&3 zpMs(oN!oIht%%e5xJXF2?(k6-SY1Pksv|Br#W%gcA343Kx0dullS`y^RJwmosf4!5 z%<(+wgg3-0w^E`Io|PdoVSG(TGnC#?2v}nP3W2LkObF2zBU3yQhw`4dxfyjVEZK3( zSm+W{Zu<|i!5^#p5Y*lSz**(}+4Ogp>i=Xj&$dxDDxCt;yfD~*lgp%ZLy7i;V30ws z0~Y}*+ZEnQTL6v`2Q<<&I^BPw({C6o;P1rj3=Za&nEOEQ)9eat{g*`}oNtv=1!|^9DjedJ8QeQD-7g%6v(5Xvlmj z6paQmo4Xi^yssd5Rkft)l$qzx$oh2CAM z^f>%RWFm}F7<6i#;D@VYhIJ8{I4TqCxL7_kiEu)iZJHUZixU%0`6^(YZVwNh3L zV5tRdfwe2AE*_a4x^1D_A_3k;#rt|f0v;Egi}22-X~3;0%qE*OX0%l&()2ft27|=e z(V<^imP+()Nymo^pTl-ude^5-kUEw!7obKAonl!VbO%QS4w?$STQ42euNR#Dt(J}M zl|HQ8q=qoS7TlJY%xuDVdf~>$_Nv>pS~YDsJN`8T+jlA8PT-wC=NopC)pUe+-sgD- zVfgma4Ib-88_``?nWBfd&n(u2?w9Df!IDorHk(WpWl1qCCLxj{&41J0L}@?T;DZ6o zN0#D~dk+%SOMKMQiAvnYnUi7evKnIQPlZ1)uZCsKoU9&)k5yKiAfg0rx=QSoZ(~}s ztav@)cQt7)WjR0hW^zGhA)^=;e6Io6%|L647|V@LjluqiGyRf}^j8Xkgvv%Mc;1e6 zE)hFPd=YL8DbaMoR}s2h%?GMjZd?p`++^`-Ng3;g)lwM+nXhg;9cw%CgO!PTq@@85 zn$KbRD^hKR^g2Oj`R4PE6UdvmLGb2r_4=5Ss6Q#Dq$OI^GxA%DL5WawaO81mQR0U> zM^cVHT=fu{}Rv%A~N-Ndi?wQ9c+n{5|bVY~4X- zvW#3UcyCGDC!&AtNSWoKNk{VY55YkQ>K!CZv&m^!UnJqAKQv~U&J%%NjREX*>Ee$d zL_8ZleSBmI*Y-+WvVm3VHl9jVF+%@>Ju4Xb3*dPaihUbk z4kgJ3TBc4Bnw5JT3emLFTy%2hM@;bK66~aOyAP;@TPS>%-}M+-bT|Vz&x- z--^!Y_I4QGzC;v*(IPN!Fe7nqC|;r(t+wnnE_=ac*yN&o}pF$-&ol*`b0uHZW?Qv#R>-QB;PRN~3u~XrXCjC(v;_yUYdKFkN@*=Lk zy=Vw&s7eNxEgden1*y7c3dWHAgwbn-QL@~^6D|33G;R9k?G68`3H;N(fldwfaf zuFVy&T`h3G#O$|4xpe}(Jk}?v329ZREB$xgbr#F=jX~Ka2YIj;P3#e0Yh|gmM!wTr zZVwHutBJ@k@w$Hh7YKu``xww<%^$9C4BknQV}FhonH-{dZ~My&5i)^ZpSsZZ72(G3 z5$AS3hFr${3_!p(8RNxr={!FdjgTbImaR&XiiagUz#NA*r&NjOTM&%tc? z5z98 zUD@7zsy+km$gf67J#O+hxg)1XLeO2L!kOH$;4~s8R4_5yP;p(W(|(3=+CWZ_vzwRW z^Q!}a>pUBKR^pYBgmIbMdtrh7%Dl*aX#XIHWqENPR59utu>N)SY;@AOmy zH^9(ahD>msiO<)wy3#RZ=blK~l161!+{4vQ&uwIk01@Y4JeLwc%*KlN&$l``vPY!W z-Oc+^QuTyl&1z!M{SR(K03wOZ>G6g@I*n@GbM##VG2O<~*SDw?kc&cw$MKEFOY^)3 zASy@8*ySr0raMfVi9B4v`shGGwdw4lRKOjzGb_yqSe ztPgMOaSas_G05XvO1eAZ{qa=pYYn#n=|R2`ja^?FyWBSns#;Gp7<|q*KI*o51)erZ zrbV)tWW5(OZRZPhg8m{+ObmIJM#z4|@qUKE{&l(8UMA!6_%#E{h<9P^PLzPVIvT(ui2h z6z$l(_R)4%If@}tMg(JXIhwpGfc7Fs)&z zKfwDkjmLjuRwX$#NVt+qo5UH%EgVgfS`m|(=y>+*?wV?C0ln5j_HZ8eoi$kTxY|29 z1~Go}c(9+0KT-P+Hp7q0w=XhtESbd=w(1;zK;ZRB1cn-%PwERjP@)Z*upgQB%WqjS z=owEIeBS{t-i6lFx{}TVif)3Ie`E)IFTgK-mj+9#S07+8U8*qeuobNse22$v_6;PR z%-jRbcZ@llsuXD>8I<)8m+=jvatmpr(3~2cR4JPEzkbU%2crNPqurU}zfy^n6W{p0 z^m!&$mT0?5YKCiFdrcbmZ)n%~7*b1kdlkrK8e4ZEowfp-SoM4+B?x7HrP4Tc>MdMv z>s3a^?mVbov@tXoa|*B_wy?!ldoKoJDJL)und^pu#NcTUT%yscZCm;kooZfv%_`Y| z%HxK{|2$0B4n1F2yzlXvEN=-{ACU;DQ2$rd4$=~0vGy2!*`~9bnthX2t@2OYYQ4M6 zAdOn7&Gh?h0bwMa28)`bp$wX`y~r^(5-YptMrsw)C~GhK2rlZ)w7ym=v&#~lngThH zKZuaR8DM*T-lkF0dhmHZs5u=K0WaOm%-{x4IGzYf!a^>(E?i{J{J>Q+L=Gjc{lx*{cyNET*JXB^6EpRCOzOLDY z;3M3%g^BpuVxqeWurpg-y>dr@iU@NSetg^ZtjzFb2gK5cc26iBB*QcfVN;GF-w$9T z0XLzuKOr6}1;fCfuG{FOIrwlzKx~}h0Kg%G&sZXCn;94*J2GPLUpn|NAEB=%t6cSQ z{CU`w2Tq3CZb?%%31nY{S0-ZZSC$)Z42<#qHb{X$2 z4)cQ*brA5T3W15)JpahO^VxFZ}+mBM*-X4A3gCtJ`YH$B(9OVuQ|3$nE|jqbqnT z@bMKwcSL4Se@kRnaPXJ$)eaGTmysj43PCtQLA~#M2);l&E|tl4oB{OkyA}@(isM>; zMtM)QuId31yyj<GxYBaUy$?@l3v?GO6N*!Dr5wd%dT|lSLhx z?#E4Ut`FuUfUz0sQk_t64&(GY98Md@{aHES5c9qP96V`Mbi@v|$L0fp((F?VmC{d; zGbp~?wj!PUvt-F5T6eursIaEW$hYJ54g?b&L*=$)vgZ=$4)t6L%j0Fr1QUZEW z1YRKgSP#eHT~^H{xqhb64BX+XOn3Py74q;yF`0#}cQIqsFC*w=%nQ^SV->nS`~=oL zGu?)i1Gn(hxJIBmE~lt$#Klgdo1mY+x1_>;W8GD~r;FAhQSOlTC>MfZ zm*iy3;ERT;H(a0-(FgVC8YW5xr2``Qf*%>MyNPjB6B?D;c#F znpE@S?&PPJbkH47qdn)IYR1+F&YvzBv>9Bp!R5!d=iAd7hn)5icPH~+ZEF2R=j|Wg zJjBpw_07LHlzl-b)LZI~8vux3)ziO%ZXM(3v?5qe#F^kTu6rFH2xVvS@a!0HCs!?t zfVthUjKSd+kRey#9YfqzIzp>ib)px`XOQWC5BbD{1FTv%#iUpQ+ zZSbgOcL*O$4_{K9&@;K<&mU~OJ%8|a`=iNrzXF=Z*ixX9bht>-wdW7=)C_+UT! z^2qGM=*mZ^o*>m3KO-D?rC<#eNvuEmI+RgaUDiJTQ>IF~PbiM%5juaHuTGu*CG>+6 zhPBqKB}NjFh8~n`blnXaRPc^V|M&^wrqmmNN1so+z2P-OxKVtpW+0UX`Qrd?I$iM= zl}=HbN5n}9=UaFSAkhPD1MR*_#TMZ^UZPu64f{OK|HgytcN7tn1(5(EiNRhKMuu9& zslT*k2@l)_5L?O1V_$78>}~7U+2kU`P{@lDZXI0A(cGT1SS<4kv55(L-&nLW3tF=@OwUVre|yT&Qa=C{|jp1CNjTuPq4L`tKGTj*J_3H>-7b6hE-5v}#9H ziJD-K_KKQy23KK&!JQWScQrN#`OJhy56R2&&Tr?j#R|VVB#td6ws;9$c@q=0)KURt z>oh{ynw$I};_%cMH@5VCzD9gG(FJ%JTg1cHID+VsbPM2r|%ef|bEx)#sNvd<5ufnih+t3=H(gnfnvgX};`*l-HIqyjGvwLBA#e%_*wcZHrVk26PhRani z5i1ZFdn;$5DrIEVMHLe*Yb8@RJH*nc5iC4s8h22nf+xBGsD{#RL9~arc(SqqLeGp( z7q7h;W(-Qoen>yZnza^OfYt5ZS2KJlm_HB14p>}nC**XDci59%KP+trX;Lr5rR#BU zb`IuR19|ClB@@PXl;v}z<79e^wJN=CUP(WW(k=$OPO}IqQyND#yV0_<+^-p|jww?r zRl!Lm)5qRj?+auPL}!ESv^*FcQPF_p5oO+J&wsi86|(TO9Tfs=4Zk-S0qe+T4jMe$wmT?jm#)QxzE4A_MV`KGqyCP#SLx`wm4FSCoa z*N;lhr?W1;gdsKK#kf!72BT0ACmpSLjOw9p;wl`y%1*Z~StJ6MtU1~p!T~Fau@QwP z6i#$siavkpE33Sgf4hguT5pwtlt(v(jKUWmWAq$^Q`pjUcl@`eR2=5+z)~>6V-h(cf?US8ix@ zf_|$+M*T!r=cs4drJBvtJ5aca1rZ+2&KD=E0sw_dHJu>F=fl12z;C;3uLE;Lq0`&yN@7E`>?FRe|~Uo(P`># z_Z=kNTdd}M4u?)g5`>xw&K{#3A_)26aH_nHy_Ws!(f((fb{W9kwU11!GB|gO?KzW? zw0~z@fv$+%r#*cF&A-=;zg3U___Ku)X8zdTl%UHf4N+niYiPQ7Asg!F5~9b9zV`ZT zxvoNqx{6L*IPF@a-r0tIm6o!cV&PVHkZa}kFc})s>#Y&GRvD0pE#JT=MaZ=*iHy+x z4t0ecoi<)TvwhQOKb9sys5f!t{&S|^TMCIS$#%P4-M!J4w;-X;OE?Tupyd)%t}u3J z7l`UWiVbr8J32a9gQ5o zcqwf5xjryIpwO7FQW{E_=@WCO+qUAc+m&Ya-50Cb<8<39nr$VEL0OqA7IW%yu$4BM zG5fh#kJEYWf_3}gE>?G`{rzjMlrQ`~EWLYgo$^>ld(57qYO{SxO<*ExPr6s#H1%19 zBLs45Lka90%ogj!Dl)LyH$H%>Bh+zR4y4dy+^gIa60w5{>8|ynm4UqvdFD(o7-*$) z;y=3P{Gf+A?Fyx-fo)`y5Kh;xUkxrhx&Y0KRD9thzoGJ;o2hB4D^@xa1B82YwwuSwKm!KipG~^As#wF|EsTggS zP?#~&zHyX)3(c^sE^Z3@_r0Nr?DJe^(`Fa(gRJUv52@8daHh<{ zVpI_kO%7x=$#-a$)qSq~_BN5(uk1F1(eZ2xc+YKRy{>!>a)eY< zwQ&svl2d-jBN61C9rHnOWx=(oufKj5yqJv1QbZSylf}niU^_f_oV>K{s^MRJ6{P5 z-?WPjgu(0MVi{HI>n;S7OCFYKz|`SeRqBFzi>+_V`*xy69_EKqU7!5CQz1X3QBe_#@Y#Rtw13-g z|Gw)Qy!vo&j*bmU_DXyC9v*%yVm2x)B_$=*MHu(GZz4BM<)qwX7@YAw=SX7c;~hdQ z1i8AY+P!F{607zEYUl3)wq#Ox1c2r~!+eQDf{v@!e1#Nkv1-MwTKCM^VyTIy6%Wh3 zbh@T8dfV!z7Dhz-lOd%-U^c@|L-YG`N~huj=L+Bue(|1{4H7I3#dz>^G568vG)|;W zeRGs-9!2(@DSJF&S1l>Kip^6Q=RC1kq&St#p=ySAsD0DU;Cah(tA_~2$8SvRrnXB& z{jh$=DRKOI4z`r!zU#a!9=Hv{y9T?x`%K@sT@L5%)|3NGmyF{jFBwdGw#TZab#;4c zD*`0uPeY-u{<=1=;-TOzritBy=nWjHU+Ny3nMH|PjVY(d<#1u-Bx7-6-bZ$5;U)vI z7;~H!^=mZh6BV3m2FUoS3K7abAN_#L-w39=Wg%NSCFq8(A=2Bsc`QBT)d$ld!#x)! zUg`k?E*-*C?TgJd*ZX2y~o*Hm;$;mdmPvbVEnqoMcm)@%BBq$@f)FaL%uDhPFr(0xZ zTRbs4ds_SkM#r@=V;14Ro=*SeFw_YR1LO}`_GW5@N2Kd*k!3y~2-`~JSuIpWd_%Z) za0KLqjb}^sQzGWonH;>}Ck$T%t^R#I5dv4<|*VQ@P@DJ2mV(QXt)3+FaD4JwXpqDo%`#rqHwUtWIj?l z;eS6${O6VZ-#wp3`u^PzhpY`?C>R~Dy1`lE|Hmc!+lN#Zfr81f zOCEjwS8ws3&Iteb!vEt5GOQ=@H7<`NB32jar~mPl|9A`ad(jJ7;(?)2nE%!Pz=uzO z_#J-2$1wB!{=Zp(eEj%O&^^vJN-49SO5Ie9CVrrd#H zT^5;4TEX^oh|A51?B4x3R0BXr<`FOup*-nipkUVGT3;wb|Bq{ckBewDOGScmQ#JOH z(}8FB*z^(d97JN>kr$so+#}YnFdm^!S`}ejuh?uG9yQ(CUd}UDYw-^?xm-&x(^2yf zdA7xo{@9S9gF5&Amjd)(?iimd(dVJU*K@P8qYf&S-L=ISOX0<4as`Toq;B_zwZi+d zh6!!u>twy9ngXholmUxN1IkC=(eM$yVZVBQ@U~=N`X4{YcPp6VmDb!pp%cM{;L3ck zK+)_sdn+$03a3%$7~$oewy$Uf&^Ee@elUBbSO7*Kesw$ryO;YjwvX*Xui@WLV2SUy zR1Sp~lN-(vil=bIXkzhbOH_J1apupg__8 zgW%cR{Jb2%G)~Z8Vw_a3nsm+tm11adw)lz0z6!zo7-qfEFHmB>nI9>l*sqmG{uYlx z^^nc%?ui_DEadq{l$Jo;`>D>McD`;g4Eg{mBAd#nIhqO zD*G&lfxcW%ep0=^7Uh(2BY)#-auSrFyJr0;7uwO73d*_s{+rPXYb1UNt(b%H_P_|b-Jc4D#w#>UZ- z%f|l9_cL^Ie#NFHlC)K#9`dO($J;YS*)QJe;tk?Tu2O(0kyDc|KNEh2W~ns7K2aiI zP%na}z<&DZXf7YvHAJi7B1h}rWc}ot-1_y@Uc6tiA!--OhEVw#FTp;MuM7VX(4B8 zV}G&o3m$t+cv`Fac4_O|G3ih)xK2v2J(dSyMg7}C*R~A{T#|V2R{inFLEhISz#$WX zksS`NdonJsd(msGv}^vpIMTLQQ`gWN)l=qmlb)F$r6gMN#1pW<0$sA%#YM4R+<{)Uq}MyMizrPJ$7H z176~AYRrmDtlX5wt6tqpV@;hx#OK;32Jcn`QBPhR zqE9d?l{h^5U^+vlNbkcCk`*R6Hr$&U$udnz3@N*^ZX#ClpI23Wxacz#$9 zVEFfS`UBa?-W1i|OevmJ0;3RQr{wtcm?J`Tw;jwuq}4C4=b%~D*_$mV0)9x?467mP zRd|WaV^nUW)K3kzho69NS9T(EL80Bp9GUcnl^Laxn8B8%g=lJxCR?!pE6;J}+*|{a zU6$ysrL0wejX^(5)g%K)H~eDda`D%qcE&RqVo|x{VJVGzgZ13^S7M(ch5DP@GiXYq zq7V@s1|Gp+Df>OyW8^JRi_5=?TRW3M3y7ml;rQ%t&s%U#x#`yv^GRYd<2gLqn3hLM zh9XsLf&Tdx?av8=;k@mwX^-n=?(*Z-{GvvzP^^z~SNZDsFlNgYp{XzT7o9Zgtrdg( zTUvM~i%rPpNCCFd{@MZ^U=In2%x2UB>KYPbA-f#fQ#0Ex&Q})+WjX3HF4u=-r3H$U zmx3hktE{sRT2v2Movc$nU&}pmvhm^AgH4Q)*9yYcA48QpcsyI51dv=AftLsh3mD5- z35@z#YOJ(s8>MefR@Yxr;O2@&`GMw3lEUXix!zhRdwypOGj{99jFt6Elnr>Ncga%I zC$K>ilv1V!cp6^3{z=aQPB0--^YQTi_DItHs?0aBw3IG|)8U=u8UZw#&$DOGjKH9; z%K6fm^7BtVu0{Qg+RhTbTC)`~(Cz1rmVKruI5G5Nc>YmO)WRw<1mj~r3!X227O@c5 zhE2`g0>Lks+wTU$Fmr!GuJdkm}ZlynA`AGwA9+;#VM0QZte2m=bc!r=ElK9Dcc{yzxX6g zu5|_Hucep&ioUGbpH(StA-L*8i^OA6O6fid4LC7CV*V*B002k~R5Wul_LXW0G93bI zFjio)zF@O+AHLX~(x{7`R;fkw2Q^|G)t9gu(>eZZi6k^9WXw30L-$BD%PAkV&o1}sz_d31!>6|L zTS}!8N)3x?v}r$z7O77bD@|ib!2`KcNuS81AB9Yvl=F3-i<`$K=YSwbjid?**|Y{b zy)>Y;A79p3FuF>1sd;8dzqiPjGgaWR@mvx)H6QbY-TK7W6vC$e6|tM zUMm-;1eYd?kB9|JNR7YTxOr=9_ zPtE$O z>ZnM_)HSbW56CUZX#WBsYO z-5c|OG42Tr^2LCq_fN2Q_M7YL{4$JE8=D66_yBqhox{3y1L0ZRCrqxXb+ z6#(&pdP%OBsvOWO9@CbCwCi2-Z@VYNG&sva0eiLA106TEip2}?S~e|LJ>hsVCk#lH z`uEaxWmWHwTt*~V)3KlZD89|0`VV0H9ZrU>2m-QNkkx$c6F#s?`_dq(PxaBv8i^k@ z*bBrozMsy}r%#47RYOfE;RxA%^}Ah+2IQ=r(0qvwhF=r3mF zPZ;g|Sgo@Bm24P{VQBO~-CmxgSQ9|4To)gZv`u?G%#U{*_+G81KH3rq=IYblWOgIs zK$HI96sYS#cFuBQvOR&%)xps(;Q7?Em+$(NT^HllsjMkAoAUISOmE1I>g$XK@Wz`9 ziwpQNG6cdd`7_Kpk91cs@MqV zB?(GJssP|d%fe=_9B}cW0&35a8iqk-9TmYv3sBT0Y|!4eY5}sG5bz_<1*1%PAj*Cd z=V^l&fC>|+tB)qBgX)=TGBOeUjJ3%4J{xPv@ha9`^_I?z`?~M??82Khf1u#0scJut8eGC2%6jD66(T*>cvZ{WB`gvaag z+HgEXE?ZjQJy}R*XW)DJlL>>0W55Qn)1BRMcb7@NiNcarNp}*9+_1sI!<7)5F7oL8 z>3LzZ!lO`ER_V%?E;4c?$5n-t-WAQHJ5OwFMblQvm=@ZXc&rw!B8rdMy+POt1lN9S2V>2gOS|BLzTshaFByW z!_|*dc$cdk@lY(*jPo^M6Y^Brxt8uwZS1UD_LaqS2Oonj;eMUm#Xs>sRBaqaHpp0QKpCwM@nq?Nvn+dg;)&F7{!Yw)s$)>y*@ z4{5eO@pbthPng8f`qC)&CZ)RP$NI~W-e2&dHVeNX>#^X;mD5RvwmTd9YLQ~GrTS5N zG)LZHcfCsWMX}Xu82qncP%mF<)oK$BK~_vp363dfv>JY3V;@M_uObKl-dRpDAsna2 zhi@|o4|f-1@Uvz`=RlEY)IW&Ok)_l^whBb$@6QqC4H)0m6Saw1EAgA~qR>$}6`Yn(Ee(q*8o zy=1hHsW#gemY0wppt&r!H@D-9C^ zEKxMygTt=lBC#mpgknah@PXEZEb$mQij3dCw^1Nm@zz_t>9Im29VL{92L}pNy!u4| zw~=f35Fm>lakX3OBd( z_q9HyWKt(E$~Ii=MiW-{TpzEzhtF2kzGy~tIEII2cd0Qg;4@+iu=cQYO697Ts+qX@ z*sbMs<4*&RI;Onf&s%wVIhZsu*DHr2=vid%o zd`p$EuP92cQTG(t5ARv*ILvhMyNmPgykB0`4#Gmi*KOJapr9IFNUA!oB z6tWWO5HW~?d=+62IsYzfQ7?K=%a!BJy+~e;=n?_2PaXd@p4AtbYS)^Ke6@`0197F% zMPr#B9XaC~KBc7yoAzbswD`8rjp#JV5{iY6n1>y_kwq%!eL~NI14aL_U0V6Kfpc@` z#KBBHhyd?o*r3yBpw```2BUg+JXSxweQxXk4`9B@su*G= zU7zds21^IaJ0Hdzev(0p&vog09i`>(}zmX9fb?Gr_ItR_iHDicwVL5;lwF7AbIM ziZCgZow%=LKD(nX9*d;^F!pkBmU4uCZk{w7drqqH_2yMXJ#WY%je+!e218>mjY8hf zRb-mfBwZt;!`Lka^(|F(Sj_KyZ;$~7PqL^gRPotDW+^I=0FOuRdTQJ7YgKe%KrCsiIRHk}(p z4nX$TgtE|;udsu%<1qtYjOs1l=D_Kwx9H7TQ{YmXALAF(?^IpGp$&u_X=8?2#k^7}{>MIe~`->;8Dw1IwR;XMQ zpN%bEsYn?q_@hoiog_Xvc>v6_XI-u6`Riwlb)h2##Wsb;!8=ia2e@mE4}WTCc^l z*2RWh!2H(O{`Cg$HOid*qTtno{b%Pf`@tg<<7So#o*gamN%zbU=HAVhzIEF-`{wtNaT&~p65;|48h*|%zH|!rD^gVFD|D@u_Y6h zLQ_z9oy$1kb$2_3Rei)2Y|HAr3z-bXP*cNs>Z z#VZ#j5ul2b!I|CdnO~|^H-5*b0i0598D`j4lq*j!UfEV}K)CoOudcj5{?qkCTOy0! zI%cZcM?dB?0LJ@oYtmc9x{ekoj}iJwFgTg#gW2@?cA1xNuq%eM0?o$1*g$>bs} za@#WacevPegbtfMM`9*5dVqk=N#QE82gKVIUM8>ZfBgFUYroO4Aa3eZZ@u9wcC^+s z_RGBqnc;yF+n7IKF7-sW?1l&W4fjZ3&$BT725N;im=%8L z+cyK?LhNu zRKmpU*w4`I>LtS?Pm`+0P8{QdSns|14<6&nr2;p7Ey3aX!wdq})pr`?3-s>d>FrDT z+H<+88-I34Z>YwMwGHw`TB9g1VdiSKxh~;ad;S-Ygzt`M>0lFuRZm(J%Z9^l9pd~- zJ43lV!=k5uWB%h z0CKL3y*HKHYTKx~BKSs7{vMRwvZ9KS1bH)^C}M`o5_*ihoepixu`I2jdzJYURA|Ay0iJ8VN|b4=>+|mCGV!b+li!l2x)f z?oXS|Hyhwx?#-p-NWY3kI4r+k1vb+C3?MC%y5n74v}L-HJeln8&K04-Qilp@rv#RD z4ptC&oA`c^8-%5aXi?h66~ z;ma9)kI#J<#^~oA_h?avQ-kasfbY;2&;E$~@34VM$pC*FOwQo862XC|1_1=kmfTf- zNz>heU|FlnQ>?w33u+C=o5Zu%4mrs|+u{QL&UNqMlefkL3uW@}6Kxn@5C*4WZXu;bfrZpU?dHX03-$l&;4k@pV44g zud15aEW~~i1rv*iG0iF@G&6xzxUzfe8^cL!WiGjuWBe&aFvyu0;qGdaPH_~>Ne zP;BAnXGu?z*E3qVS-vWUqU48*)oKmIcJ{QAz>9cv!3Bo^UkWZ6U|=Tm0INnaKPHO= z{KW!wcJ0RMYvl4b?6Eh{+P*u{J+gHlxh2i!t4M{acwKK~DAk5ThtoJkF86MOjyKnW z>l3Ohu34(DGAuDT++FcgxbMSHP~-x=l=i3tzLY9cc4{vPG}37`XShGS$a7QX+NiRZ zLbMvpeDQec)BAxR&<0T%J~({7+*8ahYqIGv-;lbI%xKCsi7ImcR?_+*&J4XnXJtQBp0ADJ?ba#U!`~uKS9L5W!Cd^Nn$^e zY-a3?7_|>mF>U{rO7OT7XMH*}I97mW$ksp(UL$a5IXj7|3fpk)j<%m1qC$93U6SpV z)I-ntbJn(s;@e~5h)DCW6vay2j%jg!5T<35GUkFsWGz)+R6}hnb3XY@CVIXH94Yyz zyf4;CI-3=Bh5oFsA182Ju36_Ok?c`NoSi^hO6+5g!&yiVlzjw39SH4=d*hoD6-{y^ z>u5g4WZr|;tAuvLi%x&Ym3!m$-k*w(CKFkNIgMXSg(8iOu;p}*Nuuhi*w`!(m&f7$5g^(A^<7o@_Y;J?VNgc|nebY#-F#oqK;bb?aSAkL+(~ z6oWnm0)(}OX+)*2YI4!0FKIk3!Y=0L)OSWk6R|{Nn7mBYf`_1I!#l*X1aQ5WqYfvgiZK6nhYU(tdm7-KhW!(f%}v#yIFf3HtTtMG``pcpJD40$?{!Z11a9KOIs=E)Bq-L;t?t88 zChH{}C|CxQKFV9DXQwcmMc3qnZFL9q8erS3$0u?&^b;}GGP}$-m^Gq= zm^A|&WIkv$$ud5Nli!~xiDoTzgdv)gAV{nX?m<4tL;XlL9~qA@MtOD}1rrl9|8ZX0 zu9MjSI-;usWd6!MIJ?X7y-8*gYG_@mwZOZ*yX$q?N+MnvjSby5j41o6US>$~7Kbs} zE4KJ2cVkULQ*M*y(QVI7Z*J zSK~RkShRDZ`|>1w)#qs$Vm&VSc}WFAqjIn$4(v->eCj#kWDi!0Z5 z?Bd5rw3w%@X6Gc8dKsTB!R=m;Hbaa?oOBwCynCz?munq7fmMd(eSbO8+)^PjEj}aG zx5AFauy;<4wlwBT*l*$@m_n3(NlqWOS<7XLGm1ptSR8cdK_SymHCF>Cp~Vng^jvC2r4-i? zh=g7?{i%;-gN0dNtMWHH5*{JOF)t;Oyt#w-3M40Rhet|&5Rl5!8uKLg`$__ZT0LEf zDn7!T+eISRf;+B6WP&)Hhn3irpsySyJiu)jU_HozPfDpxRJ!!vqzZ#)+RWA14FO=tQ)B`G5ND#{y6WhWw6#8&0eeuMKW{x~cf+II;G*8aoad>*EnGKySO!Hy#J z0cniV06aYTXhEk#KoiZ2R&_k8Gz@TfhP&mSaE^ybPxsvw)^VFmqJIG92k-wFo0ciO zMq=|%BUi4gJD6z9#XK%kndoje+x(jj0G25OxhrU_{v3U0HPfGw7PF`B-fR>R zgX&bpvJ4T4dlyVRt`3*#r$qMtqw; zrc2-cRV_fY=4!Lbh&TOTEcp(|x&NfEKB1MJ9+H|iTWAr0ELcXo4pL5}Rz356nOvcF zd$Hh6-6m0lEE+?J%I#icBZX7=Ublix;`?#nP4es+;+nQ=OZ(P!_e|=sXTE%HqD6oz zAd#_2;Pb=itaS$V2}8<1CjTfagEI@dcN;QV&u{GXNDkT(l}agK8y`({qKH|_{eXU+ zgqEHI9N5n?Yd7#}ixsJbpXv`MX=jaw&o`f`TXR30({CcOIS~G zL^#xGe@MqFFml->ha8_YFjM92BG4!X!Et|kTbD^9yzVUy{i z7!PVnw#|gRuynl=t=1AfqqFFdrJ(ZfhEiBU@$}zRy51}Qy_pwT`pjfdl)%ZDw!pEXVQZDzx9QmO!S@B)DQAuiwdlzu$ z42P5J$K@jKD-hXjdo9kO1@)=1b<@6kdq0EiobAEQHP~<=Y#|MEf~(Cwz1&l6rE7U< zJX2Eau2kJZrm8CN(`AI`Vx|7PN)w`FxDyzn0mQYf5wj#Mx~YrPZwzXNnr`8D*SaLm z8UyD1tct9E|4jcA-Dym+_Q|HA3L#7jya5`O`bQeT_b{@TER#oTEmjgkym4ZFW!j`{ zO-G2Du4UH0@U#2XzS(`r>7e)Byn{o2Tg=pyTx7Z^dOm;?Ti&f@>rA9{Wg?W!qL0AM zTHK_a@x-k6Wdo7A&lWO&vJ~uE)X7u>1|$|2UZS^sCHrR<(hinv&T$9NIIn|NWRzuV zV*6Fp=K`GV&{>hQth7$;u(ue5MU+v#9{J-nLb#yzS;HzL>ZP4xhYKa$1nz*=H8M&* zb%ckQ%ju43eo@0{TM)eJZ$x2ybHuL>n;>QVM{pmJJ0d+P<@1-kx#;al&^^<^eVsa6 zMRPX01j|Fxf zz3awKtwX z?l%sm8S8`2872hSPu1}!k!`0ZKls|_<`Se+H~?(^A<_<38M}dy3vD)-ZRganaRs3A)y)$kL)1jmbB0U^Z?@IE^AZ!^q3>{srvuK?vGpK2%;t*MsaY%C**bX@jRn zHCK!h44O59(y2v*eGQ3#>25zZF!Ky6#qu-$HFg7=M=-G92^>Ce!9j{*4Uhpc#_4r@K`UR znaVf}8w!qTBXiem+VKkBV6W*%il|k%e<7wKw!+yWnk(I39^$mJ_%8jS{PMj){L1QX zZ@=Y%7~*NfpodM;b`7)g{*<9uvzdd(9Nr}e#*>+_rk15#zVi=n_Bw3ddbkojw9?>- zpr)HKu5JnBlZXH|@0X-J^~RLxw4+F&nauhHfrAT{*?gJO^aGD}WZ&bToK#+3t@*niVM^6bh=A`{xpWjfLta4H z^Ndd($zK1$jVAsI1Bi1{ZH+zCe^~cz&M;uxCH3&|P%ZoFd6_cGxQzVU#S`q#@nP8P z$auBB+(MphU_hj2VgLO0-iI%d(Js;0NHNoobtr{f;I%4_`yT(jZ&zGoQ*+_O&5DTp zJd=?gQe!5yYzC|w3jgn40{;3KYQ}G|IDCK~g*cf^a66ly_XY3lJZ@@RG&Qm0|B#QNJ9E7cl9X^}@R@u$ag;G1AGl)&sAgf8ogv>P@Hfu7-w19fFMJ(DaG8Jm0a#j58^b?)AK_cNI*9(Z&j_4b=yt7Uua zHr5oH$++A|{2;%gB3ZYQPMtnZT_Pr0M`zmfDr=EfyoZ07Hu|vfc(CC~VIC7V&R@;$ z1(WelCA-6M*&#gkv)n}1n7IZw|03hrpDpvmK;5{ptD@5IU4L~UJ}&Jj`ij#OMD`P4IWFxaio-vAA~R4S9Fa@%@6nr~zC#xE44Vv97*D&tK?3T&xlHnDDECDMg@ z8}w!rv{)iPglt(N|2}TXR1QU@r_ric6i1=Ja702^IQ%CEq55|g8kGk1R2JjB_aDdr zaN8vihfK?4wnyB@OuUg&122_y%1eP;VcEY3*psBicQBZ&^2N|Y8hD3a!5lw!jUYIh z$~#sLSQJwqB?(E_5Mq-G4gwuI^6`+I4pI$YOOv%slO~#nT8(LDN!&e_Dx;r|->6!s zVnH^0)ulu%ZIn_cyIJn**RLqTpJqx^pjMu_(sj;U>`fKkG%z1fMZ(USk>>Wv=k%@T*qJDx zN2ps~?lBuV^{!1HJW0iwL0tFcb{RK~mKxqNS$BRGk7FsOb^z2DK*x=}1;pHm$^4JK zLqjp&q|*rhu-e9egU9Y<{=}KOlhNGT%e{rhT&~M}HUC+;(C7U#rCJlfN}qbTG^7J2 zoADjIi|Lrd-6V#J+h)I_k<-rpK45m(N9s43qrG7@Uz8k5WQo;p@}DZSCB#QB(yWY~ zE%?Dc^`B^~bVzg~^e+e-xixCtxlySV_^PqrsMgDcH9B|6A#u{x54NHlcep?BsL)Wx z`kTzaBJ~`a<5NQe-n8NAT6UG){yX;4{C%RAZ#-^w_wCml-KlX)-s@UnTbNuA2|#SF zvO=6na3&NqU5ee@T5=6!(#GcP_Kl7KRa%AJS+}=hUlz@KZa!*#NQ8yk`9{=UDuK{< z88KfjJ9;}D*UF8jxgj7~aE7BeX28daZo>-?;N6{d1$nl^sVh>;QL9n`wYYZ7bA zygmB&pz$On@`w2BHQRwO0<#V zhoKa*!6PBY&KGLJ)0kLB(pB2cRVwv4Z#E_?NkI^9TGQ;7Tg%>-o4>Su_a zlJm@39!&%0Gx9*!e_u}jaiv8?f|&zv0Rip6;v)V>W46;rydcA~s0t5nSG{6gI8IJZ z_>i~n2*~|dOa~>0IO}J4y{_#&&u_nFU>SdqNDpyY?Ihth9&9q=<8Bj==Hqsk%6x-Z3q^`ToTH@Uta^2A}Z z(2X4J5;wJ@I%28hPd5!tBaf;F+uZd#5@`h}m!hH&3Vcju_GMrN0lkX>LSb6*Z0RQ; zDUp3;t%25p`~9$ep1Z_&XKBxmme%KcJE$fk4J`yq_qI6SLkvZCH3qrrNrbE;28DM@*Moz#~ z4(DudwW~q_WwR7A@^u$YODSgKLhS+7`jTyy*@(^*VA~M0X-~0w{4~!U!$|PHN+t2Q z*8P`Lv08uR*GyQIi|vtt84k+XJsG0wLG%r1{TQY9Mts+vqr zDFP-5pKF0=)}y?!;+;hyqs!e)8SQ~}D0n1=HS!+i_B+rqoEESK&6K$uf`QZt7OlqA z*pm-{3`s!M!SwX-7&OZ-k7Rj6 zPPc{pD6=t{>tEo`sg}3iVX}dHJrM;z`X?g%r(eX_@RjTfXB+)Rfc)^Yi3tWGt8wTY zS?6qA1--#WfT2fW<<Sfwu+GWf+ zz+x$VW<6g`Y$*lk;62*f`Mq57`o7~&+&S+Q`o0(h3N?lT<>4vosj5%BR==yct5&a7 z3d-5ckNE(Nu=^U{x@JTg5W6249&S6Ap`vl$-OdyszGqZ+In?2W+tFHTb$fYzb@*E& zWblAGvoQ#9dyJy~a%1|3o(}cr>;0!1n^=8KPiK5vD@Zv~+k3~4Er2VAC}43x90^}C z$o~yW9#HL@slo>JgV5T(cSg}9+DV@jVknW`6 z`N=o`OVD%mcO#-B_xy7uy@Db~`glt8XG?mC?OL|C`~UL(y@L5Dw+ftYa-vBklob^f z1AHtZE(3OPOkfTV4+kKS%=_!3)U1F{^op*t+BxD#wrJ-Fah>N|Lt78REnruO`@<;V zU>r5+*@IYW1|OJaqkjvtTnvjd{r|An8Z}+$e zD%WkInaj_!nRhw6f47*_A`oPYG?rrm;mZdfx2oob)VRdn1110TE5p9ncdl{WK~q?L5k8Nn8b7`&8#qZw#zobsJi#!Cx%sscWJCVe9{QKd~PU1u6l7ED$|r z0TQMuT(pXPAV#|ccqQve+LDfuuU@Fq014C@)P(TkoL&GRAr2VoUFeDtd!I>nT*h^+ zKK@dniyl+^J4I6?{IIUxD!X^LdI6-ib?GXUqkI&bbZ#?N^oWB7`6qeJ4N}ESV=~2vvC&Z}sfG<3pGZ7vC^*?^NOOg?bp2EaIL>dw0T1_BRMtOTP5a~&#w8vjQgMYv8lB>W-C{FQT zE&j{c=Tue_2{YQfKzfal! zu_>c-0V6?peA9XT7YqJ>{*90ffR#vi^PeJ|znaRZPGBUmtDLXu|M~`@KEVK`$WOpw zFZ|ih#IVQDKWGw2#pdvxcL$^F0o<2;z+3YF;{pCZf(Q8XL}j7ku$vKV4a5iQE)S}Z zM;6C*C@SFz7}qMxP36BtvY3xZ4f(4pe^a)rK1ycwRoTd=-{kI}8OoT79@IF^1!^!V zV=ICs;Dg&~$^!4eT_EdP4K%lU#m$2iXWItgfkeb~Etc<*sz=Lo#j3~BHL$R>FxNd0 zxmyZ1fOdV734oC?Lv!H5elCE3;6f!ZG~-ea8E(DJVg2eom1f*b`PBF2Diw`+1vD;? zBcOty(s0~HUC@T{M=EMfBxr%Bv&&9WZ9VmuP)j^qKJ z+^?oMVW3B;M7s|Xm9O7N)!reUb6f$ZaAo>PfRKs>VjsxME&1F#ySY1IVwK7RdZMy_ zZGM%;dc@2R`+a?5Fe_GavlM%8!5`)3zGdusTi3wKf!?j^=9 zo?YZ+GPd&Mnd91?)Gj7^nAaFdNe)YFH{Oh=5b0Ing1HhB9t(kT;x{qfz5Zt<}Q&{ z0yzbTOREkF5wSt?a4C;B4;|avcJWyfF!LqMfEw(U^MMds2|yNF?#BrYX7Jo2OkY7f=s+-LkOx$ddn2h0E{Agn9zKRI zBp#n9qRJp#fGSVoLy5)(x^1ZNvg=Dq<{P{$$6@_D7Mh!!VL3~E=jxI zj<$@vDT5KAW-1?r$OSve$f(&wQj#h#FuDFq8j~Xnz0L>GKWsxjZ+;Px%YHt<5O{_D z)uGB*%yR83H=Efdd{YPaM|o08m75@^w!3?0Wjf|hY}n~mS{Cs97!LMSPG+V3cu4(<1Q(Pf-(>YKQIEf)SnjhnSciw*G)^eb#Rs<7hSHlOg}9LoKXlZRPxv zt!c2+tsgMJUG45iQRb76r9i@>R!&leU#oK33YD&#$YK9OTClS#r`RdgYk8yB;^F@X z(5tV;hXy^dizQ@a^XKhLtz~}ym!ZHH7uaUo2l<6&5N}{mptMq86;2=Ka1=?Km^OeX zi?bDYD=aA$>OQbzbJZXf!eUdGL?LIz^KjEqjf*HrM^FX3fox=Yd+^1l)_hFA80a`o zh*r)!Pi_XF9RZL3k*XTJ1sxN+D)H)z2 zs_Ts&bq?>R?UJ)PTklmp8=o^A^jriTma0QgA3h`gLcuGMH@OiPy{!qs8!sdQGW6kZ z5gY2$P8RYos!;zVAn~|8(|82U?=Sb|>+5++)Sc<(N6L!47MIdIV=d+9>h}DDBd23z zaap6(1Jr4wUi(>40P$6dpE1{8hk6$<3$+hY+MQ|`cEU$T&J#efYuGL1GkyPdiDpx= zOPiLCCVu`c2W%VoLfoE>A(O-QO*+@z`>HLY|K#a5yVwpgh=KQKqQP$gRhE~VZNVS; z!lbG2bh8|<6%E~O-&@X9=4iSyLAAj+r-i@v&eL0pigI@|*EWhKApM;MutU@(HZ(r2 zXj}EGHL{XVE{-Z%+uqt*hC|9``eJt=`~}RWR-~-eW28$~K^^vOvEDA5tw;s&Kt-aB zS{czu)A5L8TCSqvur$ z%?F00g0QOw+XrMGn$qWNT51MajdE>LlRG4|a>hk?Yhih4IHbJ2Df42L-{oqb-iAQ? z;?oQbHYQ*@p0@vR>`=&J-sl@*Ioa2@diZyyZ75FoAExb>@D48TT|>+C{NWOg2;;uV zdv1Y`1$td0G+{ceb^=yn%Geg%XA3?y%gWnj9^CGyl{VWz>BM%_xR@nU+rl(RFJar& zC5l1Apw(TNy1Q4Q`?yu#b!adlG*3E#sg%RZF8n2jQepVoD6#3W0o*TdHCYQ=rqiIL zuj6*Zl6j@FZk%FldGv=iU@B5Ss5S}c2IJ`>h*3-au#af$WdD-Qg^(&#Zv#PipWy0p zyyUS*5ohwMn%%%956~LyjsN%raOZ`MWtin3u8DHJ@6M$Yi)>8ueLz0CyxwKC_jD-53>Cy(~abU5=6r^&il>?VOG04@U#+KqjxNX?RI^l9X26HBVvn!1q5N3y4OMRQY_HYR8lBH#0S<0@5e{#EGbs$cpfAG3>|?^ zDKGm6Z`%HcHT>Nu=i!duab3ZV%QSGCTqtv#) z1rx>AMxf~-joB8xsW~A#D=Yr;(}nus+3O$XXzhM&vn9|M(d z-%C^XhGA3p)>$}Kyy_)sti=q~ahP2t^LxDEWPE76IcGzNib@`%Y-(w%dst~}Sx!&a zI)FaXzg#1o0v9T_r)fEcS_hq1mOF(N!>aq>PvfN#@`9z*N`5OR~lf+wjuXd_G%mUD*bz#)XS7o`oRZHd{5}u7FN25>&B~1bA;oaw!rKA$a)LB*ZWQ zUrVg;X9GY;zV#+a#cbLaE$t3??n8Pi2W?VLZ1&09+JF?9+Y`dBAKY+5}d0{ z`Z;v&_GF3pyd|Ype&T_Sr(XbLqH3W7LOp?Qn^kf-p1o2Btwwo_d49O7UWh>B%NP9) z54m440EJp3u4vyg{mKvvn1@kxRXw0y+BI6ByK2b>uyb#zViOby^$ z6`-<(yfbU_=>GD0|7|9WBn|VlchKH8>keY={63hq1gbHueVYLFy3pUrp6279`GQAy zE#tKwwMlIGuP5(6e&UBBVhDMLu60;54y#UOw-o`>e)aIN(Em0RUYH)J2|{gjjsNLh z1PF1Fp04*I-tU}tz|1BB`8Y&Yjk2{vmOLKd-nB~nxxmQEJgWcs0{?caQCAQ|kxsDU z?h*d_8TgOOcujKp3?Bk@_EeP+^ItyvtLG;`sF4zNc^U6sz(XX_eklup=r^XZdDdEN zM$=%CKW<_qPDzUXZwE{avm*GqfgZJDrB!MoThy^6|8<1{#^ksE;TirfLq%;zXf*YM zFX^7$XJld;KPnO7LHpnT_b$#q|GoQWs}-`a?6WR$lkw1YAyUETDW#{8k^8;iB(S-( zZ0Cc6{(GWUc#wWHzyFSpJry0-@ukPW&E|0WPBdYWZbvE%Q}RYH;*HPH^YioO&d!OM z6uKU8@6BO=bFd81p4$bRetM@uuR|DegDbS?dic&!|6-dl%jXF$kgJUh^UsSKAm#<- zu{stVAjUoL0u+NUc~C}-_>)fm1xZxd7<{nnvbO;Ml;8@@O2eu5@3T}-3}Pe0y|sCh~M_0PF{HtO3uHr z$9i-L)Ta5LNqsV?}zfQVnc6rG=z=9VWR%ytbOfM*>)-t&7__5KD zfsW~HM6P)Ham~5A)WkZ= z3-uIsFT0SbmQ>Ueyy?Z{M!YdCfqT9;s{lKB<60CkUB6yr6^voATo2t5$!W7hP`cYE zr=uLq*!~XtgZk?Z22IREoiFyE_E@m!L*c`&dj{34xeRKhsy`2j8MwV9$Y=0jWjmGY zwn?`=T<$dA?D39&L?Kw!3HB>;!L3%biVUBwbaV!q3aMAR&%7Qz7xUIw-}TnpIN~}#-;9}JLso`r2$iH8`uxG?!rJ(akmbIu1|hbRzVc_ zsg~B8a`F?|;y-E;Oy>C*{X{ykpm^Pm@;^W>vjIA2YK|ayUo&~B(UO+OWf%2#g+b&W z3!6+Ly@r2iI*=%6Qf-Ra5+Y&|+sMn-P-Fjc8Pon)jUlFXFgKda8`)Ysodx~isuGI% zYs7R&ev{;t*d+j4qV|3E{&Q>%L%caXt>k)Egwt!^?-P4DTP#LVgH0U#j?4Pycd3>? zpb6PgejLC=z#z-|a=V>c0i<~{Tp5>tySuVhI>dpBL_+BY_lAPLZsd4+Qew%CjdN0`RB&l}4%|JW82-cqmfH&pjO2zJHF^4o?jvW zk$nb$#guS2dxNyw&w72<795Vt8{zY88CPYspWGs%QZTw&8GQ0HW+nR+#XV}C6+=*v zx7AGvfRHy)C?X@{^L)MegYg6S_%V+oT|o}hSL?HhnP6)yq~#9uUs z#SmZ1Kvi0Z5usIE{8F}j&|HtsagcpA7(Qy?$|~4VxDP0!x*WgfS&hOsPB!Q?+rXMn zWqYUu&toy@MoA}7$=_Xox0&=m3vgc~&a>Gqi8g~TLS=BeJkxsPAC8oJ$&?$(iLpZ% zR#H+U4JPt}6V$yfbhh)Tzth3#fm|c?Z>J^>6n1}GPYo*s2&x)U#*1a}d*qmfr>oo1 ztyNE}dHg87Rz%+4DeqiIu~cHzfr2GoveIw7`KrjNvrdJq+uBSzOT^oL3^(?)2eDQd zxG{CO`BVr;hxD_Xit|I$SZ~tGgwGAjp5>=RkvJ;((`1(CVu8x`9%n-t#jzJV0R(je z6J4;cUEt~p-o?bjHO}5e^%D~eGLe8Z0KdwD?HFDANpD^^PS~9Q*hXrpF$!lJ_$`(* z^MBT40$p~Ky^mXAOZn0`K~)V;Q(@$lVRcz6fY2ReP>Lw_Gczy0bn(<& z)ifB}{I+2+9og-I8AktRotbp3G3XL#Nbr00m_5wB4_b5V=f|B1QUjC9?x*0$4--Jk z&E2yNO5_b(g^#{*{^vFbJkX6RGKmbSWm=^hd(A6N&a?NJ%b=gt)eaC;`rary1c=kb(V9FXU!L6X19Z!1bP8!nYjs9ebA0Th zZ`0H&K#EZY0prvC)sY;c+Czc+S#~MgG;4t#Jsk8Ff5#qhY;;dOuvpS+_a-MAeKw^) z`Y@dtg!1IqezF`^cDj1^GlOgB{hsbO|Ce$Qq)>COW_7tGrX z9g!A3IKeZ!*U?#e;@YRw8?LsM^xPa9|Q( z+b#wZ8T&C1n0|IMoN#$?*2qNTw!-hJ#(_^oP7!Nfxg(n@nH((jn z9}5@7kXu|8n*wwwAJHmQv$7T3Ml*Vz;R!F%8VOwu*x@sJ_I6G^DSY*tcTdnNcR%}+ z?IG2I*d`?rM*O4egHQEpC8?WdZnC9m=*-of##8HCd88mQ%KSoD&_Q|E*B`0&4ri_$m9H5=v#h1*S zdi+j8p;Ii>G#p*JgU;ml%Fig!@Ux;9i16RR_C>;D-*8A@Bl0cXxV`6_ED=8LL?i8Y z@Magv%6T*T0wM{vov-Fc1wGLD8iln+_iyw^rYCq^?lSvqgOatXcaWEAJ;Is@HjwvA zHjKg=JD#3{nL~TqQ^fT%L^ge)q zR3h;5A=+WTHksh2<>VoGDog+6p}By2v_shAh0E$)VxTXu@4hS5=%^A)Srd%l$ZS}d zI0*w##5%dj{O0Xqs=tdiZUW3;1R4vpPv!Rn9V*2>H1=Uo%0cXx%yTF9s(K#=v+ebsR9@Qn3p2@w4p#9nno8j}wt`HuCuk#&9VAZqn0g&5fioZu9`X@ZJB zPs;?i8iZF{UD*>n4;?o38HRydA+%nznWN8h&T7oFP5^;<@Jn{<%dC2q?| ziE>oSl!Ci|uO@KcF4W-@1lgytRwY(2r?+tdYxt&9`%`%&Gmo#}(HW8y_^M&){z(t; zf-o3py?07p&B=V<`cSuu+ua1f(9W(4sy42QB7I8UT;Adbo?u>+kV?Gt5EQGH^g`^B ze%QYV6ZqUhNC~F%4raYe7Xc39I0epaw<7W^BqO7(eOAi>_cr6ec`lnU;%IwBhdZO@ zgeHTsMY*%Ui`qmaj{pP#b`gG>Sr1Z!=_(%8TE(`i=^6O@mclyqoBw5v7S6+$oM zmo3zC?&KZhZ47Xnqs}#h-~{1-s;9Bz#69kBTi7SLsWHM8k7lA^4vY+va1Wtz4iUaf zle)sI1MYVnxR(m}?3PA8Pq&;zGvIb7Z&_W1(FUwnmDcbNrsS~V8yAHHtzcm|A}dny8bKSNlva@E+cH!QGzfzeEJwGAF+JQ@924TqT$^6j?H(XrGIb6elxc z5vm>#y6X8%+8qJ3H__Mz{j3O6*2#K%X(z4J2uMCsL3#yqfNaH*mw5O7R<4%q`Golg z1k2-N88+L22#s9`gvpmiz%J+3mKT(G5N2KW;~f8a2e<1!D0NIA%Q1CS zMQ=;q_2eecQf#M7b*Bc?25YV+lyXb*3Sr0Z@ib9T?o=x~M3LW|C89xp8IC?xA;rwW zhWjdE@BYP3DgW~sm3ioGu4)|*jlE-lSBqF4zAh&m#J(rJ>gl5;Z5LW9I0^J^ICFA6 zBG5v=1!}V(gEZ%{^$FcTB|7}uop<8fVdASiY%Vl(bO&mQj_FrB1ibnHryVSCOsDEzHr>z)4q|^R`zFqEcN2)B6vIO zy3T&@=1bh&!7Ujc$@=KH&Tku(2nV)%9lppfLu7_!DKu)*`&0I>jAqU%(Q@W~ALk-$ z%$2R={+gP@vJ1l=nM=u)NtCaZY1&+_U;c~$rD5Yxc0jbMa3o+aQ~AYqqBYqQ*(8Pj z?D1)3G(%;CisAiPjrou`1kZnJc01^h4tbW)fvzG?VPyZdnB z`3EO#yRyvZ;WQET6Wa2wT8z!HYmDy#^w{%@W5Zb8_2lHCnpd!~N4MJIHMqQ-)^3R_ z-}3=3%BuUK{h6om4Ubx>V#fAxhLq`0!kX4%w|IE2m0F3DCZJEB3pL#tFSk*WOUH%y;IMt!ASSp`9Ruh98}C!Now30QoQxONi}maVCKuRc z9%g1*Ah4}=ohVCj?h4)W){{BASh;{B}4v8C>tprAcj4;0gvp78fQEXCG4UB@` zk2%L@vzeMa@eXXMra>SiZrDkcCL6n*~wbT#|tDr3LD{MXrsFYyFs{nkovMOVrU z3hI%o=ZswiXFPcCA->Z&5^mC&0_nYXZW9?_Ko@|BojTTBTspPyvK+a@DF(L5AduID z9;lsd>PfIxfR@H>Ox~1jT}VCNZrh}tA(h46&>uU ze@5@uV$L^2tDcmA@})$-VlcjmFpz^{A^g@BAQT7G&}+5gWPajB^tCt<=3`C1F9tRU z0_I&JT{A(ogiFB)9Pu1+NxCerGpjB$GfJCj|FEkk}B>)0)}r{l2~DggGYZ3y0iwI-aljONn{!BvNgR)kMY z#Jwxe6X4o(Z_tV=agexK9l?(kEBwINi9O?fy3Oi+i@Mc3wJBu;$Sd|!z4{4)%mJmX zRK)}>!ORt~)%0AioXyr7O_1+*j58GNwc3HWE!FAa?n%XN`m$EH6U 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/windows/images/domainless_gmsa.png b/latest/bpg/windows/images/domainless_gmsa.png new file mode 100644 index 0000000000000000000000000000000000000000..41a02017f2c46e42e8194ccd8ef86b5a399aea8e GIT binary patch literal 128741 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 Ab^rhX literal 0 HcmV?d00001 diff --git a/latest/bpg/windows/images/dsr.png b/latest/bpg/windows/images/dsr.png new file mode 100644 index 0000000000000000000000000000000000000000..fedc7a8f65175888990a083f5648b86f8a20cbc4 GIT binary patch literal 44872 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�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

+Lx!ehbXsLF*=pgq6~`hKqc)K`Yio^!#z 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%0Al1P~*ZU-69t%@?2Cr^3_mpdT31GG4l;# zI;=tI7oQfNwX|W_WT{V)2>0x`;)K6ZpYUm8U4Qda93_hJCZ65L%*U-hXyDp69(pg$ z#up0D^5adkgQABRGnllOniAXG+L7W?zH#sDLhU@ymxC3wT7&a@mpexJt&6NVuOVE4 zVEH^dETNJ2$wdZ4-&2C}o_?ErdkJ4U9Kou;B$t|dgN<;m5B#}Uxn{ZCqsQ>H%HDi0 z%n=%Rb)9h^;A5^MeJ9mI?>50^j{}E)|NVVPFeuTj1>fn`X*$xSYwRuB@Hjj!wx)Dx z>EC8~;$P;w8^2CBKiC@(tVtBLD4j>!v-D%(`vXg_|Cly^opqfnbu=zVu(x$_rO* zkP%Aiu$6(rpvm*Cy~vVRAB^LVD1_v2uAok}&As*=6*xP${4%x7pG`w zD$R@cAp&)#B0Zhh{qP+JmF4>?EAstu5X-0+)clJaVC*K>4Q`iy**UhXhzK>4@)zG4 zmiV02wsPx>+ylc?HJkXGL`NsaY|O!Ch@{w*W#*sb2&*%HT0S9)Z>_f}CQrL>+$EQ= z8l1{;t{g*H^I)n!V{(dpxjVCYCMX?{{ut~AZxjcs%g;05w>^pn8}d*mtcx9~`nNpD z)t-&XmqFn2VJ9K!B@5obKNb|W{J!;TXB)II9}U?v*Swnwk66=g*xp%t$^HF()3KBk zw_ASn9k1aw_56Dl9TF4@n=kh7cm6uHFuQpu=8qp@?{FXGv%M5$QD+>C$c3Caw~4(ae8 zn`{^2F2sqbrahVdLIozzMZ;G#$W{ibkrRu*4SXODP6cDDoT>l%IP5R_!XLjPvs{e$ zETXOX_=W3hABCj(_f5oCL&AIGZ^!Yb{gs$n&QG77J6zslA->3Y`N&F}tkOS*q{KKO zm|H1x=x8lh$q^P(OYF+5@t@~V|CG23<&SWRo+D)4;p1(+@D-x;qjGWtPg$bFerH(% zAy5kS^m6m!z%wCDz< z;}JSpZ5nylTtAPMI&B=mL6Sa72cDsA7d_VfL)`j+USK>KhM!L`k}V=wn0_ilMw=q+ zPAI2NPEMOaC;ZYU=DgjglZg{4r^H3bXm(?5BO|+J(R&gyrT6bhI4hD8Z82Jq9babvFX4k7|YM@uT5i?p6-F#IvgC}sn+U@*&& znWSDKYiDO3r4qh;5tx2ybhqr-K(N8u+0@}hca;ns+$0D3XmZ6e?^Vp<={Gd3dbS#F z>Mz>GP`d7i#;_I=c6&}WBaa_lK}IvBh;^;<1v?jkVe%5(!X4qnU6RBfa(?<&c-CX< zoZjCSfs0{W9;SH$vnk?{FDKiy>G;?c1b_zdj-{UYIl9rZPB>bB&# zd*Q+P@f6?+0z5|c@ZYNvez7^I1-=sPhIY<=ytR+m^nQ$qDWu;R z-Mx@VlsF!6UF*7l4*s)sU9i(|cX+&YRL~ef>lqo0pRq7C7Sd(>c)GB@AhKZ|Jnxv; z>cce&O|$AKyLVng)#4EKsaqc#gK}B%auJ67wLcPfjX-^SBO9&xE8j8#-tf(m%+dYr*z{^^>sb4eey8ZxbIoP)CoF)WFEqtqGF8k zV9vVO4X+HEsI&1+!G}Rw(xy6F^EME_0Z{+?fb_g(LM|dGIEKpiuQ6RB6p9B9vOz6n z9}n_Lv_qQGM7SRBjW6~G&Vz0eC|^-a4@f_8zH++?;tqMIzcHI_OS=AN!^0*Y02BMW zxz_}r&`X{pH2^435Sj_mWvsY6q1$}cV!=%UJ6C~+{)p8W(CMu3AcU(NSe7aO^O%z! z^HaId=~783^32Entj@9Y-=4^8^V48+dGqHawfLumlZ)R4TnKYWJ}5-*Ebk43<~Dn> z4D7%8;{ht%UYFPv+MajcjXLGB`c&>Vqo4lZI${|d&~y2qdwJG|vsO(@?W@>s`xW#7 z#ZK24a{FpeHKX%GI{Wxa2DqnHFg%94z8mQQlC+yttgGA1%THHTS?uD58siiE%+YpQ zYrPXE7wq;Q<8i)r^L?~_nHe3j=Cqd2q6oB|@OsP`dTL%TgFsz}PC-1U5c|>0y!Asj zadjGe{RShVwAHqq&e!#_n#b2$4&`Zq#0ipuKFT3;6Z`PvsUVe0nR=w|PYcT_A9EzOE_YU@Tn;bc>W|(Ti zu^Zczs&dym0KnjDbPW$dpg>Vl-|SzHT)t~o0qf28ZxTaZ|Ff9!kus5N&qlfL(K)Wt z`Q;h2)71sH-yxyrr~gT&knn@9%d>UwzLv5z7p~gn798#j7ud=xQNP+-QgbOXVD0h& z>i!}Gm9E=iAh2R>ZJ;fD;e8eP+?$V5urQHz==&7c2up&L0q({Ob;d$yp&~Q)&ojTT zxo!R>-u;nt-;)|_AJ3Y{PF>pR-9c7<#*L+k$8$SCk~ppW4kmp7rYZ zGKrGricKE~7H_f+%vLPu)oOFDDlr~p6nIR|W;PrfP#9e1%+4!lp3HB)|#(qCm zN98(9ehsSku0d`Nbm4^TjSc&MLcikIFjjA^lRNDMoWIw7yq+yaFYGU!&9tJTu-gub z%`T?JMDxZ3PtBFFx2q=fp6vCZP30_>S-$L<+?XB}Kq)9N{+|%OfrG7ilKpvcCxtr> zbhbv;^EJW8^UY38KKYULCqae#u=^@51fC z4Z_5&89ltio8Q;ldiS^TZ9^&rDxqs}ifXzMm*#AG4v<2=GB~eTh4b&p&x8%)tn<)2v2#_oN z-!J&$mZ)K5#4~J7P$eRZKhfrEIW7;TOq2TgtprU>PHB+rCYFchTN8yyAN}HfjTx?f zAN4%uQpeP=VpcByvsX%Xejdd7eQoClp^34PV^-&GoU5E|bEo7)A!4DSI*rH>;Ey%w z{{-v*#PQoCtrhSahn=k^{oz!+zizgg_IA`Ul?)l#UYzHEWg?6h|5$VH zI12w&JLdUyHx+R@+ZU^R{}uZ{+@&oj`C>PcBl4cj1;6&v$luLp%@=$Y1pL>WVU^C4 zv8Drf2@k1WJZ)dBjcr;@wG1s(E_Xmc2h+XsPUr0aHpkt%i$}gp)SbcR#(h{>-{;n$ zyFSR_Jw!k=V95+&fi`v>W4_xTKp`zAjUR8@rI{7&+IRd>!TD=bzOxj;d|8|V0GPz+ z^-g=NnP=_8&EsS(X~FZeL&ir}@*(JAiiryC)q{yBa$|!48 zy>Q5#PVk9Lz)aGpaJVETOtlr#)&DT=)@HYqmXaZUo&jt^7$fd~_FC<2wC1&6AY+2u z;67YVWOTVxzA)x=FI?_4??(^f8?;=%Wm{Gas|2rhy2(0@`B;kume-fdmG@mZ{C(sW zv^8gM%J{~-NFDsK42d)pxtjID6OX&a?_lMjeMD=Z#Oh8Ea%$+!(hku$b(OA%Rk<1J zkDer`RR*8#WG+fR=Bm2yBajLyhSQM9@6$3c`5Q`N|R$G~995_`kgXFb?+V zVS{Jrj;<&FJ8S>@8KjE)dc!s%*85%Ii=G_3qc>&okuf7UkK_@F{80_(9&}rKvYjWm ziK55WA_}(^ih3J%CwDFmFuNB*?V|sg?EL4LzUCGD2|+mF+_A1qV}_Cr$8PEtL)nQn zBVXs%lWHHA2LqV^sE4HE*Pxu9rBkA3THBe)3w@iuu%Gvh0ZA#PhwW>BllEL& zi8{%kQE+{|HF!pIeeK+-bArYnRPgAsCXEQ%x>Wcuh>!xBkxo$J+2I~K`nPfa()2Xs zU9+UYqpKTy zG7LZOPuCk$(8cvZN+}N5UmIA_t_A!$+ZP}F(TPKs{R2uPaMy5~Wy*Ydav8ZE3L{;0 z3&|li5KVNZ8|S2DUwpL=?dlVFbne@({eZ2OQ(psD*{J_8VD-nMzV>YQ2ca#2crK2F zrl|O!On#?7EzI5Os;7r*Da1y=6@`zAmOpFT;5)-=$?&lSX^6p1oV@rIW!>KXrjid_ zG_lh|99gc{uWG^3f2OMQVQgRZceX+N#~H{?~uH>Z$7LzR!Kmb(WX3fUh0Ayw&y3 z6*W*k$sTqIrk_p7NAKJwE0vx^3?>x)&F8Kb>m%(oy z{@3#$=3$f}jRA+;J{=>ys?iUGQ6xPatVl5qLGH5Sl;WMWOp$Nb+kmpgqF;0hIf{yM z=fF`!Pj)W$yyc%K+lzbXT~FJmFU$&>Z5eg`Y^iD5c^Oppj)4C>%1?pFuR&oYea^wS z`_I~Gl2DfjOrW?`IZ|2fRDWwoiQGe6C@pJO_DA7>+$0lS;sb5EL3Y>zLP8>T@h2$f zDXr7-q_0CTcG3?N$N5 zDdj0U&aA~`t;-dEYWansH3lbPwxpQ{8Y-p9~Gq=Gk?QF8p06J2mr7SE6&oM=!97P z`XyYqm6e|hR|0hUUP+WrUyjo6=Q6rXYe`PAEzCjczT~98` z22?DkU1_ng46sQ28gNXF2ft=N`qp+hSid%-RRjB5&rAVyw2Gf^i!r@Jvs?!IS~Gu+ zTiY__rir3Wh&_$J8{Qlv9i}tiHng|MiVpzOot8*`Pae>WJ$!q>QSgd-CYbJakH0Ad z)qtZLI$G`oM?bLN;v6_^fi^i|%WhWI2nmM@bet@?&sqzC$-x2~!}==uxikC=elfip z`DV*P=F4_PIDH5Qhh;5wQk3PWMn{{f<1MbKle|5hJbawFcnc{d&8T><85>h1$24pE z7Q1u-LdyB;!Qe*H82Q0{)WfoNFdB!=*#e?z(i|RNl`l7EAr(F5C%qwky~oKxc3J8?)J}zN_l)rs?O!V9yorMAipfD1&y{?Ot91$h`XbMoQHN z#7Csa$5p>0G=ggUwXZ|>%m2OvO}|9Q^v3{*6`RZT6*_O)Gl8~sjo6;5r&*Hj{3U)e z8uzD{B=bFBjk#zk<4Fn{U6KpjzX?86*#i~@()1^HCnOD)CTSYxU2dx84|=L33Ryk8 zkiNxT{vFY`k%l_yf&>?j^E8{4sh#PRu93#sEBh78Fa$|qXp%F!K%p-iwn`swuU|AW z6b7*tMTomtXFKb@noF6_>WA)>ly)cWMmtJ9c~!#`h+TE;sL<63c`T|&O<8y|mI5}& zdAx*!PLGQ?t(=6lIiMCK9#Gz%F%fd-+C0QB!F_^6{4-T?w}O$>JeTI!TBwL<$m}KM z4KkZ=57-^eZSsLj_%Q#%5dux{8y$t*Rf16-kB>xt#1;M+qoBp<%_~L2BiQe35CQ4K-xJ|v_e69*D34B7|`zbbe+Eb(Nx0$;vpN!iBOP)o%7xP_r5K8=<+n4Tu7YV2`9Ei z-k$NWJCfS7^qu8W3F_{C5656ZWgPME4K2T`I1Xw@P98PjD3YESS$5aPLiEDDio5<_vUgiM z5j6XJoMT)BGKandP$`EC zV=Zu5kDV zm9LfiOdq#>#EYstlTW6u6C+>Zgx1QD#hviIUa5Iq-r6^sPo^g<(9qad)fU%tg=zQwbfVyIGo4*y8mwTQom?8%1H0CSM7n*WW_k~J5KSI-U?p$& zy@01cnf;8Xx3$wf?t;nJN>IymZ|aS%zWRD90w+0&Pcs{Jc|wiHBCW3{B=Iy)L%j&O zl&!kG335(<*w%2`w)wuyRvQiD>v^Os?$#(2e&HAu%y-e|23Z)Sd|e9$xA_QFm}oV5 zhikf?YFiZb+NJ3aBMaZ#x5tedkE$1QbsW`QfL}9 ztzoe^Gj-v)1LEjj2>Pg_f_Fc~_|=qM7B7-3Om(H8<=m==yqi|(c0Jvp&D^sxEdZ)p z0wE_ajx`Szj4eLq4wH@M6`LA6#{24e@_N>w$F`_VqI2E*x!3otsVd)#0BD+3KT1#ZXFn znTkfiLE)_qpY>mVDp&B&b<2*Oj>mLv-M)h0^gs)P1DTz!-Yp(BHZ8ASnw_)WyZ>X@ z`_OIpf!%0ZqYV9|$BzZDmi493q-YGw6p zo;W4Xx*(z zT;;M+7;O}ITzr_?_m1cQx$1hZx6+KsH9l61v$VMKT$pz05kI!V&I9hNCI`LMAho-b ziEcV^7kQogu-d-3qRe_<>NJ0&ncA-amp9Ukbd_<*F|n{MoNQG0!*@N(KJ7BU{L}yE zv~hB1eokb=jvxbrIXV`sZuOxS7dGBNa~uZFt>{<0(Pcp|hI0VL>AFp)@i3-j$w_3W zZ!wvQ74HipSKc*~h%F~HthdSZt1Txmdy8c0g#N#U`!>8r8 zp5NUILz&|=N~0!_PZ*-D2?5gt{9^}SDmrEOXfJfF9|4cnl^H1PV+Mk21lqfX$Lw@m zNHWpdBp_YAM+@_dMoL|~2Dfv^$4bCsH)y5nZV2!3)2nn%DJLh-tF$+h*q$?<9t*PQZfniIL_a{Rjs{b1FvD^u2!Lgc=aD(>MDl9w7>B*h6O13ml*JK1UTigVOsVSn^s5C0{Wa z%PMP?r+!qKyV%YZZUxNQYhn}-6J;72d`&8KlF4gr3l-sGF1g$Ldw>`91&tfL;q{O~ z=OVN+nAwq?`HUwwK{16qy%4NPEqF$=ne%PZRtqVJ=nmb%T-Y8vP>sW(xGueTFS+{H z_9R`u+_ESRNzW9f{xWh@LO-c(+7q_jCN>^@(nN`sw`-;$V(7kr<7j1R1SXZZL?*u@MOxTOaJXU^%!Doz{wyPdYMd$uh%B zyrxemR-{v@lG76wXfTnFgK(Fcbm6OQieVbFtc>i~b9sz4&i2ACiTs)yhw)w!lVUx% zrXjV&4gLb2hzyv{4Aic1f5uBT8ROVSR8EnDzi$z_xeBh}|B|42x+xfLb}{_YD>wPFKzd&VWbHihSP%`SIioWQz)=C%TL_h3?chby-2^oo18 zvgoUy@=@)p*OR?_@Bc>-B@+9TLztch2-tGnF5K|lb;;nf|5Inxpq*-cHw1C2TOm+R z^~0)X3%RzS2fX%&!grF8hW#{YruF|s>1m2*#CA4*Fj?#G{D33*sX4?@P~Jj$k_VCI zD>j+n#w`!F#us(&{j1rliu}s!)TU}Di5)1{$?f#o@x^5xK@G}i1Fft$q4CT(o3K9A zLP9(k{-at4>qa>gh~-=MbtXLhG1g;p`X@^?uZo6=6&?jXoWzw-;@)j9#<$Y_T=q`h zBxtsH>RiaP7~3SdFV9pGC*aMCO}zT^hBXyUF6 zMj=O-NLWmY(;gZMY+Ts5{-R$NShZ-A^sO$G=J)>4AE`jon}!QT8PU*pHMxdNV4>)% z8Pn<7H-t6!g0QgE`~51evbOc2kHX`kE`GsmK}Y(i!zAefg83EAQaizg;&l$ej5L9& zGA^oXbP1r2ZVAY@MmR0?t@XLgn-_RcI+^NNoFg3F@l?t=XEU=PSy{HGkUX(FyamgM z#3|F!5kv6QCyd2mrwAkRR`E_y+H9}ydwp8wQ3Z!;62AlmDD4=45y1u=4IY*Ey2CEo ztd=oGyZ({UzHiO(7CN1G14UH&A(G~SN#pwyN@=WSk{~hf4M2{!yr#RXXankAacK-0 zu(frrFJIbGR@S@TRAdgzmsj_)lz*siGs9A~uLoAFEe+8Qmr#u4mN}G zjSVZEiLK_|XTCI^v*9cg`a%UV7~mIFk}vmq?M*fS=U=b&pOdsrQ(eo-8gwD64=h*{ zla@%p!!I1m#7LGEXOmWng7*pwXoF0|>MX?mRqwav*&y@+RPXFEusQqdC_UYe9E=cr z{k4<&#bf@yZ^~rqg(n9n-p5(z3l|l@(MzDptFMc&(D~1kH`yB1xyq1NV%m$9L!3^lXc86Kr8#iC5;(pye6;UZG=f5t=pNn?o59s2mQ= z|5Q9jZ(ysaQ{a4j&vo^sv$C%7f~(15QKrgRajHU(ud0NMyW%o4d46tUE#OzyRrVL+ z*8Cc`2g|EBaia8_6Ii1p@c37f%ok&WWP=b33%ZNFa8UoU>egLNsy5vt_C8aE-lQ_4 z?BMj+R?j#yg^AJxN+dnDbZK^>G$o_lO=dHL0Ygb?V?3ReKx*^$;&(I-==2ZNkET#1 z!9yaqxme#~u=9ZsiSnfq|32w)i9Md@1+2}AX3k~%LIv`C!OFa+W(_@;bLcY~M+=zR zt7f*m^Y`?1Ojb^QtA4>gC0$Qh4Lm*T=YG!5e1^;U2FZl8<9nFW;q3U&*v1iln zzR|G_<}s(smA7+8H%Q4kjd&T3Xs|GC2Koh%v00Wdd_iSiPA!E zl~8EE{>a4Vs}>}$Y{E!O3#8}s)=cIeFI>uItHDDVwz!*ajb1H@79Wx^pULE3iGb5} z$+0TC!KxRZ_sR1$)9a}9z12iBO@9%w`i=T8jkcQ&?0(I1Bo1Zl?=)4AP76WT9GU=) zTm53nImT5<@h@%(Oqyr^=HDLi4(wq&^=`$^#OUXV{-#aVRlYKUtc279rwA)I&d7W2 zhHkqWGp(e9i`Wcu+)RARb@%@Fn&^d#f!LUS7z^=BKD(g#Zj9uAOEA9XEX&Ug)5c2BC~p6>`1IY`8yo3ePf^ zJ?jT|^_)VU6Pq;r^u{P`xndZbm1cWRXDka5e#lAdG&-8&Zw&UafBm_%>AhAK03|h> zSkaG^1IaM7owrYKReOV!i`rUDEwJnlAGaw&ef=n++*aF9l9Q_msw$BN=qN z43s4xhR@eB(DNvW3C<-K0~4n0GY}Z3wfr zR(r`ttP)YaFPB9G9Q`nR3-KF;l%3Tt6p=-xBi^riNybpxKc@;#a%j{sZIP)Cp|t z*Z(xn!QxX8vB|$1Jkwmi)Wz@9$iz6g?SRw~F-e)>a=gHsoL5J7V2}yT>`z=?Oorx& zq^4R{R`}!D;U#El!ia|`D$d3vMbK$qy*#TN<~D8_$Tx}GkE!efBs#@=4$%U=ZLxMz zF=-MJ_@FSM*=tQ5{nm{`BY;`aO0FtQB|GqMVB;cLzr`R85yei?GCl=;Z({7gbd4K;zBx2-fn0l?ez=oo()^ws(R$2}brZBW+G36al+ zt&_VE-zM4jOoHI7tjz6kzrZ$t0#-U>SdBfZDc$^nasl=vyEy!{Hm56XEe&<5LlUj$%dNneCatEV*6pOIxWofj;D8Rbv&P-hP;7@zsxXI6 zN+vsgP|NUxR5`nK( ziT<&4l{_I&MHVrhIzmg(kOOmfG9gb60EE=*z;C!N*Z5sNa6#NG85}QPvvoyacW?t{Gj3)? zIBa!$DVOuc_cIxoBqbF$QfrZ(Vepv%BAy1x9739EP)8cFSL4Q0+AY zoLj(==Edo*y8=Ys_jf$--4nb~P96AmN(dC@(DXu>(yT(l!`LRhPyw=}roA-&Xf;Vw z^zsmkTa;yK?q^?G+VaLJ?~UX2&7+Dz)9YX@-T8TuHZ&d3vC1;~5`Q=X*03Ax=YH#r z5Av);sKGF5Hdm9|8+LqYpR+!6FpDsfr+)v3e^j8)*Lu^?z?z#$ui?L^-^@+GJ}?j9H45nohdej4EhN>~n=*yLrrmFXD-`N>MB7lh6ds zV-c*Nppok(Ib_UBFxGH#u`EcHjK~I2dpK| zk-r)F?Kj|p2YQSPmoiybK#b|uc(5Tq|C_f)&~s)18e6vW!K))*j}tBRnRF*dmaBH9 zE&*H?8_II$?ZRr$!z(rU4!}&bEHyd9`|28EN%!jL$O2 zd!9>E3KVTDho7rgg8PmTvqFI`)YbqN1wn^Q{8W1ajG(y zKwFIH5b_@zSWB%g_Rf}E3V_Sa^*d^$vHK*ya;#MdYzuNsrq3(LN1rC)XfEZtCO0A{ z#jp^r(YF#SofgV@a6b;5S(;Qm?$67zUfLtu<|=GX5LV;@9!}%+xXSifCs{0U=%rrO zHjGOPB=WAdf=8PjG*b&@U2@CU5EUhF{iK5BM>>WNFzOhBO-KfOxug=fp0V}bC(xNg zsMAAlSfe$-CpB^RYYUiFT&; z>&gx9-H->9$mK36Xv8D7s#X;MxJTXlJWyS2e-JSIBz}l>E>u2N6n$!k5`A3JSx)V{ zpd+MX-RQfAx+)84ocgF)21egaf0zt{?E}+ktEb_C(pvV`_h)4s9v?;m+w`%;xdv!~ zYpD`fTY3sqM@2+jZrLoLg7;AL@hf$q^HFJ}n{Lic^@^)ti5{q0z8DU>-^LXxEdz|PyH@rVmImG{hq zAaq?GJo;`uW?k|1<~Sg6^H0h6$Q9|ouV91ywtKbrr#_Yl!OkQ0ewB|b2aUKoH2EL8 z(7Q}p{b9nork|}6V&+LfIZjSHbJzu~p2wm2_~Yl70W8jf<91VCEo-F3m&pJ{C=pFn zyS31m5*YN@Tp% z?JVdhL4(93@~UK`ty_XUCnxRm%A*_g-A3BpuRcU~*q}MIV&S9_?jY{1md6JCb6}(P zBIv-$YsPP0<(9XSA zvDeT{Q-~2k#Kjx4@Un2yu-H(Ax-K4LIHhS`FW!VOaf~vJdC*@xLJ4L(_MG#`h? zE!Nc}0AJ*fB)l93CLeS>Uz^R&Df{8OqC*Mi1yH{&(_I$C=~-WcnTc8mBJ2CYJv0%C zQsTC$;Cu(pdnwXKQu5zFala8iU#^n@ZGjtFpo>V6eoh$HT%(>eJYpf`qnQ<=y$4Ey z{+V30zk>{P=j|p*hqS2xjyH;4_en5RJc0fTk)#yf@p_dLN%~Aymv@|# zNi1)syRc{GMuj=Po%P{Ic^XdbxooT_i``ko%cQ{+(HNs2F5gTeWl+Ev@InY=!U3Nnfddf+MiyS*CaH~ z_=Q@S%lm(YaI}g7sgf8Nry5%$s6y(wSb-{CFRzw0$lITo%K~@EBL0Mg1ZQvjDl{|1 zEJiG;u8;5zvQIk(uKbD}9e1FtbS8BSeASuF+tz8wO7cSw!9;wSbcg{C%K`*Xu$Ou z2_$9Y1)uhdHc2HEJg?|7BBSgI|9LBaZArTCzc}}3WXX#%UO~=(K=|&PLQMEwaxdCt z@5vJE^}Sel3~l87a8Ek}Fo0L8SLJi~QvjlycCy?T7F+ikQ>TEeuX0%h`FTlFu;$Wb zJ07t79y4MDKehZ%(eyoLLH=Wge}rRT}dm_^}J*;v5_p2h-fxYMT6Z>q+h9@ znJMc$90LNs!gI9lX__#hC$jgAs1sc~^0BTD(|`~ltZjNy#O0E1!S!}X*?j%QFr zim7dBAS=m}_Y6l(FGF#fv4W3cDZDE;8H1q6wYjGfHLJ(;tDBo!7uPX+4aUCixkSkyMsu2__~g{=qFSg3wA zFuG9#ZUjfaQvHO@Jnh<#zV&J$`d;vZr9R??+b=vwhL4|R4K6!7n{n%GPy@yKH^K+P zmP`|g#y;&;9{}3Rc1d)n42UwP1BLUHx_y7(H-r=pQXgu>N?bl`Tx+kFAL7qi(f1Aq zl^DT(@I_?x4SM5T-*+T_kdKqAhSbmYTCkxI)yEO;dy-U;O7b8`lHDY;#a%Bu^kSqz zNu2BmX9#*{KCo5=DTW+QcSRw;n2ZWEsWNf-U@QXIe1v9lOb)fEMfS3hYnX1C^H|bq zvqr+7C4a&B(&VOGr@icN%Ja6iJ;%Z@R{K6Fb$W!lGDoAkm?hfp%+qYgrolm*r2ib> zeP|q8;Gs&O-6Nu83-Qdx16U{RcAy|v4jNnDte5G^$M!AZ+l0mEBC_ct=S+2^h`^=% zR;{DX8Ip-fzyX~gdCrQ9=mN zhg2@b04yAq`lc`UXRxT-($efveC~R3abfr}dnBV8_wgi%3DWyX@#y;b(#M6+L|vRk zx5?w&8x8W_nr&a?YOLdai+lGYJOUcgf_q9S%z<0GvnKAt&fROWzHL}xR=fsg+7Xl#j5 zs(3r-%5NLYQJ#h`{MC~UT6M!%jjO@x^@7s{^BW!IHw|EHu*cVuut4dc&yFgHiOwUu zL~Sj_qDe&w_Q{NW7>M|=0wPEi9ItShf-i2s3;dCzntx^(@ahX?WmejJQnKDi;wFO_ zsvKdH9~>0vHYLmrO^3Ll?D8BnMj*xt^KsAWTrzSyAPv9XNHUnWhNh&~csP9VkYPat z%BLxvfCXiJia~ZPScj$DfYSl78oR92ZfdfE(WACZsv*#w*FQX(7k!Qzm%D6sOK;vth6L;8>$}fI)6el6h^@rSn&O>XCfS%`19E7OrnH~ z?Wv-qjbABd0`__X?c;=vLhk>hkTS1YX0@pg@YK3r{a ztx(dnsaPQT8_za_o}^;31OuEy?T-eV34~|!dY6-bFTs)=_)X7ng5zBbdelU%t_+H7 z486x*WVP|7If#8R{n?eQc3-nlk(0Ya(kE;hRvt7%mEo9pTP&*>8QU%S13Df&tsfru z-hI{$6 z%YNh*V^DMh9wH}sZ&g)b>g-*1g_FQcb`q&5ms+vv2GtbWftma>(K0ZljPq>=Dt-zbJh=(LPwy)Z}i%(1l=vHE* z@WYH~6Lk{L#*Vq44nf1OOB>2-&spA9!Hk2;S=hP$Ch@(Ijgt{zoHBS}t%H;u|D~_q zB$k%eiR%TFYBRwlrmtg~pRoen!=2q|lJRF7mj0N*@yolHDXIxH%Ua#8#XK1N62xcH z+xmOsd2>QzqupDOBVMsJ6E@Si^!555=!wH}H|nfeqc*eV$FIZB&grg$89YN@v{M_) z4*tIO{I3YjmKzDwt!nixayzX#o)AD&OOiWw|7B6+`&i!xa2LpqW{TV=`bBLpj*RfW zH{49b^lD=wJ#x_5$4aq?iU;z&TgtvM)Uh!lR)${8886EJs%DQl0Mb7lQf+^ga8>UR zEaV@(2VsANxvrGM4X)wsd(0fTUN0F(%j7g z`*FP15bTICb7`4)s*l(>VMYYGNl$p}6!<59BYJ&byZ7zzqGphBD}TJQoL=NflUi8^ zT2D)n-wXEr9tH;j$2Pa|1~7jqm6(|P(O9}qke@BKhaD4-$&$#R*R(H>6tjUx7d}rQ zW5CoNK^!UMNpbDv*kI}<*rFFLqUyvTxj5+#P^CD)jY@eN`XU8kc)5he)eI0D!f+>k zMw;ZMI+O)|wL_dtX-9Y{#okI)0%V4nhB4pMW|@(ZHg!dT#v!uLtvc1UlYDZkviuIC-B9a`9qSb9kTpo|=#Ij}@S3|n ziL_I#GNTr3&Z6|WqVu?IPBMRtrEl=hpQIm6(9(vH{^GDeZRUX9n6-Jn(+>9t&`JMQ zeUw4{Fe%lhC@e(BUd#9GirYb1XYFk0XXvEa%m8;SjN+y+#u+3+>|r#li_n8B`Zc$e zH36fdk|GqUZ%*!hGhK-UMJA9Y?v%^r`zph%iOrQkxG-inr&~78uZ|vqAkygi#f~S$ z;P)xL>|zwMLqLh$%%mjS%Iu#R)RpSvwWS8(5zd40d*g{BQTHSD5_qk(gG5%w?}(d1 zKRB^WSlif4+0iYfZ(SB~$_zhKAtV?_Cnq zpH9=|%800tTkgNAq_P#&E7J1x(Kk4V5=}Chcqq>N9&JClDf@P#4R zjg_-fW$FSMbA(gnHY{8Tw#f?Pxn3t^K|7Ufha&bX*>HfCv_0$S2_HHY0JQKx`Yyr| z5l#y?;qRL%2&(>@oJk$&m&fJbo=~&W+ySGtM>rTF##NB<#Y6H^tt2(_eC5F+oR{t| z9jF?GRMOzPu>~xpyMwSMfs$uF)q#ucp9g{}X(=a?Q%Udxia_s^i&~(n-1q=Yk*@0- zG-X4?ChQ}2~@3QOEMDts={ zG~m^LI^-Oc1%(pZX8wV|93@2!hV|F#5CW$iX_!?fc2UPs7;}FQqIYaaJ%)d|zf%N8 z&H|BMI@{%Mb)A-f4P$7e7RJL1Ab2Id9Nd%Z)%QWdNfX(?bdT>u3yQ7j@FizXp?D1* z=KE;`^S|o@YjPCIceU1XtWV_sJNx{IvB|zD=x* zP|eH2@83A0gmYoEI__kfRi(Gob^euC)AX)NI6BsNuo~KPKsM%am<0XV*6xBN`JeDS zp!EN#jf64uX#E@0JO8pPWHaZa5bS*BPwx?zUTw~JL9>8k39GaL`=M4*dB4w7VWkTd zJigC1*k*BBC?L;XdUA2Xi12m6y#D`Sfb{8r|h5ki%<~9SLZlIpXk># z8!vsiiHNBA(EGz@B3|aI$|{@r1r1)cErF7tSTHYtts0lt9-DCN(hsTKTxbm2WYeFn z)bbdu+;I{PdPM4yY|^I~?gzc~@-aF%QSqFtv0Cs9`7+tnm>^}$!svNgpS#cCr!L5! zK&~7kkwk!)wPCUK-Mz1Vj$RdiQKZQbhez0y0FAE}Tw-rs4e87y#U@t$`HvKEd}k+h zF=$bLw#QrGrHt#<#o_lqmOG0t)(`eS12f%Q9L_Vd7 zM^r>Ehr8Bcu1|OEvfShKNx*ZQ8cgzz)>Iq2L~gYZM57<%y@ioc9^QeQDvyfH4>|Zi zR1!~5Ro-n{(dR396OXSMN@?{~Wiv_{>7Ad9-`VLX+#=R;5@mCIn zbfLm5$hiIWmJ$e;#~B#|EyL-^BR%FkD13WM)ad07XQkdoGQ;>XYcBdd^IG(pcctyblxPd=o*wrk%p~`BR1;2k%2rA_GkYlYM#?S@{FJ zk!x~O;JD7vCn)*?kavN&XBO?u@g?zGOH+`hD0jJ0AfGJybNAJkpihW%vEQpud5|ZG zf{jYmT}&G~pY62hNv^F^d92PrCu0(+b|qZW@^J$eF#7mOHQfSLm*A6sK2aLp>GuU_ zyMHgwep(Yq&s$;6&!^6+_1d|6)gSNMo`bzQdW+gm2A075wFP@m9y$lI%VI30qQ3MM}p5} zNzUkg8_cJ((6ahanKTUMXDfpLKgS~QsG1`W;b=Z1AS-X*Mu$tXd=45B?uWfZR<(F! zJKtk3O?(_j>v-Q)@gUhv5*!rh#|_kaovqOlAAV+@^l0=DESLD$i2W}E_SQ#k-t$R| z?4|#!%VHfwPLHqCKu4*bP ztB|d`>@4d7gEU<5d|U~4Po&EAk&)G29Ex5;1$ zyjQ+o+j%-$%v4$9;sv8o1%4Z*CTEkEADPx_PZ=(9KmNeN2zn|D^@>wS^w?pUr%?`6sBjv!$Np1rW1z`db*UnlaMs-*4W= zmxpSdWwLy2?N$}L=R{JdV?dXucq@-yBrkb3sNNCDBv0 z1NU?)G(6kRedS7l1*$q8C>HOmq)lJd(j~Pk&YE$ocbotvH`lALTw;)o1(rc@7xM+! zpUQU7vY=4};8mx`7~tOc()mbYcf^|6HFoc!xYO=NwuSo*amiMB6*1 zz8iz5s3e*sz3Sj46-~ZKGQ0VAvu!qCi9KbhmSKkWA?4jf9xIBPlz17%;4j%M2sgQQ zsq$9vEyu3YoXjeGzHYDvvj;R{vR9A7$x zGTm)rFbhmNqQi!_L69dxU@7Xp3m%#d8%+Vq+W;PBF4XzkBAx4YKF0EmjBoSLXqy1_O-~)6mv>4cT$yA1)^7^OR5tx-&j#)7qN}N= z?1JFLHw;maG@lfw8A8V&2DM^sR+XnKhE?xxuZzyk-%MJ=CQdHsX1mtns(K%=In?Bj zM<;0S&t6NINIVUMWHl^r5462+eJ#|yuXE+SAt94-eD`Fxb}Rg%TGnKVt5`l$xvj~c zu}=(s^#r7&#K&m7{jH3AI01CJ$qfaCY-qQL6Yxpj4Yi%l)zar3Aey_N1-E^5jK@h* z&l|H`EDWk1M150+oPTWpzE9Hx#~s0o6voSQzisgc(VF1?<|fX2jC`*k$Qb6se*RY@ zc)Or5=leaM1n8cb2NH(;dGsv%vx(ET)Tq-=(HvQc^A*La(pT49IRLlnXo|$kB(ISZ zwjd;r7tyH0k#9(UJooD-!@2u!>UwqLY5ugJqzQ}a^7R^+MFkH)1p;Q*Dl)xXH%t$+ zMy8iZn#W`2Be*6oR>uNpMI|*uppLe-LJFDmM42KBH{;bBs|{tPgf!vi08a( ziy264)(xi;AxOB?H5pvKZ!PlLdr1$OaBH$aet%_?6Q_!6QjG#1HXIS{Z{)1?m|*Zq zSOtkMbhWcOxld@AZj_5mo!ndIk{QNN%Ti1ZK7Ai7*I*~eQln~L|B04%uiQ8~e$*2! z+ooDDkNnb`)i4Y}z9UwYgB{CL{HfaKt>JtH5SrR1*KkRfV9Hjh-rt5wgg>2=bX?DY z6{~{Mq~SccMu{p=4Z8m@WIq3an#TMo$Y9^6DV3m_w2SrA*k!G)Z28m6REQ2Y%$svf zSm==>M2?7?vurNT#>yBfGEUU!=8flmOPEtpTU=fxx^;XfVp3;jpIiHlh26q!E|^j! z+0*e}EkRcmE0RHsg&SFvnfK4Ws*t*j<`>Ulv=cy|3jt`C{+j|VTn{;Q)#>p4Sx2Tw zxevnFHM1$XHQiigX|a4H$`O%B*jd-ePQYJ9s2h|9@dlT}*_B$8&tkJh6Kcd6#5>tm zh-`pcGyU&LGrxSh>+naXh;Y7>7| z=H2=!GNtD)s>G7Nk*7D~^-&ukXhFT|_@^m#j(;$o%|fv@J4<4}4MyS*@GUseQQXC( z`h`{pJiI=04b`5JUSUm=#XN(M43C(OUyul)>@~fy=ayH!ov_Ss{ z{y$gEQt9ApX~4n^HeXnnwxS@yo@5t zF(r<#53_5knuN+<&id`(qm$&TlQ8vfn-Gi{3)=`__`E*4-5$j>JoFxBrJd=9Eg+$2 z_b+Rat<_ZTcZcHSK5ge;5&qZ+jygi-K~x;xCf}^JdJ8nD@0Pynk12M;n%>$`^C(6k z>&>pdf=;?EWb?ws1FTAux;P8;36XG6JhG*C%YR)2~(#hFDHs*MD@S&kme zqL6k8Ew@=L={ZSRjFWH-c>@eDw79~>!r{4gakZ6}970BbvowBh6l>_`!;V?eTpfi6 zZb;Z(VxB3fm^FdCe4B-ep>qU)d^w{?2+oV?2sOn{qW?FPtqYNk+UU}McgW&-M(=pt zKr1pgit~p_cSMIeNXdbaNnp~tCU?i0OC#N6$=4~d#}k{C0t=TdnDS4)Lu$(GLPb!F zhHHGwv{F2oQqQF9X*S>Yz^s$}Gchj>%*fQX@Bm41&EXaAH==2@x+1Ns*cm_2mw_y!RKnXutNRD7Z9au--%zZ< zA67LKm=cy2DdDIy+B`Put$(pUd{Q4ckK;^87@GV%NDr|ExhT`k8aFxqBlQ=6fl=hJ z6?F<^O2BoKVk8Fi;s<%@kxTD8vYTmyT83L8GwbjsWplKraB!4Q4{5+`#Xe)l;N08N z|AZQ2nsQ-?XHmdkxA{YAXNJiZ$4ePGSkqiBs-og4vxkU9M*8PcQWJ}!8-p0la5cT| z?H7ruk7mOtyv$);y@~|17t>vC94ahnr}4ZiX=T$urtCDSf;Q5MqgzY0HjiRF1U~ZO zJWJ`-c@8Ob-MEw7b_f~B;|Mx-$*7#5e4m^ydq}7@dzmRd@+ejK8+B{|t?xsz7_&&Y zxz)voOo!_3ypG1vA_B7#a3|e~WYBC9jebky({p|VBd1U5``*>xIOXHPA>@%k|MJ11 zxKefd7q1NvUQPOI1)C5~{@b(ME6My;J12(%k*Eq#ZMXApa{!8pz!6HC6nfI)o2G_r zlif!Kv3U&6hVp*g_s8lMFuM&yY$c6FBee&A2?lNh#+mZ(DV?CYN?3}Lh?FRSS_P{v zXI+plKK`iz;lcGoL-H5hoWP;h`d5-pI*dJC4lwmW?D1=k98vBMt3rWY|J6v0Gs~kM zzn>WFIi8-90f}?9t)G$`=?UKGkT;A7s3@b%0@tQQqQ$WZh+=1vnjPNwMJ{LD(2^Ox z-|d8HZSLGwxq!Rn)ahkQ0FK!k2ucQXMG3;$Mh2OI*d8)dm{N2^l7&P?F(+?gdsm4J zUN+6+n)#2Sqq(D(zL?_dx=|K&tS-L_8*iqNE=j53lhfbBddWrn2TdiBWK9FRC zoZP4V<~CBXj@_{_M8v0u)3rNWzwKn=$F_5sf*N(NFpV_G47IGRr60UCIMIhC4%8H~ zy+Ay2%%XwhoAJJ z4DQ04WC`*M6=2Q`8AhBcZKrC8`DI7uu8HM#d&+iefxKe^)EmxZ!BS*fmE`!Jw7Wq{h1ZHALplMXgYa! zG#r6j$^U9DG3%_<*qZn11gfr0}22S-S&~ zU`xQ*K@l`9+#Uzb)DofjwZK-4V*G>(V1b57KkjiIjeTlUeAi*8cL)4&k)MAQ1)3!J zWB|oF1>t)4s-#@yr@SKEHP;lGMduN9@u=omx6gRmi~efmsvN@1=z*gSk9*-$h4xuR zmJinvA^;;%l~>&OX^cu1a!;YF-BI#}*c4W} z|1dEkm#7s~K@}PPXc@Ftlm7Lw?5be3M!|L!{^a@MGbG|6<6XkFG9qno4=&FP6`$x> z7#8v*outrd1Xv0+sM)@na`ON}@&{RWQO@yhXf89tls$veaP2%)cx9|76=f2?Z&{&W5ZX6&vDVMvg~Ukg}x zq`W*L_tQ&p4Y+c2D74%~+W5|KtEM-;SP9fUjtL(2Dl&m0JC$DU=ro|t0ioPzY`H8< zAZgB1cy!dA{-P{4zB6?y;B;P~b{^iRAS}pSc5PERbPJ{tl@(BOxRP3K7+GV3ouO5e z0%IEL{RB19cDA0O`url_m$ST!jj8=UbLR8@?&j{P4-dm1%RWuBF0;Mn>aCp7AY70E z{&pXa^%%yNa31DzbB1#8{LSPa;ZuY%GOH!*KqP!YH1TDOIn?|VcRppX^mJzXy^Svc zD;?}jSsWurbTTmmG<2NEB7;WKTZ$smUnX}hdC@9N)=Y&OqN3e{qZ|?bwZDF(Hnl@S z%Zt;%_*y{2p7{Ox*VE;Of{2wSI_!FS-c5wSi14`32A)X5kNpkV-3;#>IwN+^*-RXR zk;7p7wOD_A&-t|R>%JG2;7lhdh6&CP*L9>Jicvu3;5iPr_u<1uUNYh(`p$;*M|Xi2 zOIAV~!2ydXhtj%r2pTB-C*+{OMfZ11$^%mNfqj!HDRCN?eYb8gsE;2c3Y-I8uyb6jdnJuTJ> zEf}Z3U*cZQO0i?RonboeKuDK3tzX*oNl7rCLGVxzDP^TZnj>X`OsCb=ODin3I6%&| z)WAtZUiRN+Ofwxmjr^wks_o$qM|unw%N6eDe=WA>i$rc(^5f1m`>7XO{uDmydGy(q=q%G2ZKYCSFxN-H zXHO7s!K?J);tWD(TZw}}W6eZh8l+q*AWp1#{&IcijAA^8O4Be-*{e%cs^c*+`W`CS zq`m#}{pF#}IjxH8U;tq^okucgfMku**I7+bGB~USq32orFjHMyjqWv|@vw2?e)gL3 z{%~EC^7i-h;JjCw!2O!FZ`q54nz0XeNHqk0La`qeQ zm4iD1%vO~ zV1GYr;gorPXOoe~l_HAitBu->e$9pk-;~CT+GbQ?7jyA?n&h9tMzx|hr0>lSu8~nL z-h?0~$U;vU!u&Y2Rq9uO-i;oc6#WbNDyH>@Z}G9MXKyKjFl8o!Kh%d)LcGQbr&9_l z)zx)MTk*41=<8R1gIMlk_2vWk*y~JIrOYJ9ERmTHJDZr4JHjx?W1ZQWVgB)&UxTgH zlr0?}{orG06-fmnO1fkoA1ej>v`rPF3J-hhjGHy!DSo*9>2nRp>{k9B&)+-SJ^@nR z`X2u6HPtoTCz~vMT*go-C{d!KU_XVD(2mMvrD*EZi&vi}p7IY2K0-dB*GBg|{b zdsei&Ei#0DP$#8I29AZWa(U#>aCxX{&MU=uEb?XIBol-7F)%J~J@(z8U-!=X zUAvU@-ijSRx5*v1|NcahgL`jr76__Ogz@oM;p*Z zF`D1R-ym+dTvbguqxATK9cR3hPkt`W3>5R0xoH0H=Hh!k$=)_olhuSGHjo>eYuug z`8{zSUHwWb2t;I@@9*yS#Cngm1;;tZV4$DTBaSRfowVSk#ii}|Kg{%Ljz zXZB(H8^@HjG0@&^hTcGrLeetF?et~bl8-Smj_y$+=@9QlZ!2#IU+8X~P3eFHHO)JAi|c2M zxiaTohjQN70H`NSOnA;md`WCd&bX@zT<;H+fKGP>ymc(=IwRw`XlRKm)}WZ1KNGO5 zVEWoAQTz`RMm+Fe3!L6dB@Jl3CwB`}B#_@x2ck-hLhSO)wO@uaGyR|nXgv_fu788h#o=$bjozQx zHi&rLH~ShZW{$ru!DZs(w24aF896K+0{-{}R6bXt^7Fg{$h{ZX6MD&qvvbH0zoml% zS8XuT?Wo$f7&O-CT^}1hB4x|?*7mjM{xR}~DWA{>nK73MsfKu@BFDgh*FLv=3T497 z*^E6)Rk_#oyvL`s9n$x67oMw#fY+kl0P`g%O){EYWjWv6QymMGrw-5TA2ni(z8WPb zNqp{}So+Z9(Gx#6FlH-%#3+Y$=nj(}G)BfPk-0m#>BQ^qWWAE>kS09A;kjgYHHs;g z^Zp8#yzX5RhG6&&V|VcpP!M01 zQ9|_s?#x)qj8Pb=%9=NgCK3U`1Z6aH7R+44oc~}+_Vjv)D)e87FK#skN;X>ur&@)W z1%z43Ik<6OY;NUh!~C6a9iDg6j^_3c?0fnvwXmYmRj!#;%rMCTV}FHFIolGOr7kI0 z!pD~j9}`W{w$PCJf<}AVhHhMBeAjgBY+3ruA3JNqwfelPpY2{X%XZNG7cL zXN`tjF0zY zBA4c$X>~7D{S$w}SQ)%0eDrU|>LHF#DTV(SSn+v|$!nh>jR7KYGX znm}J7ZsRIqqb~ZV8I$sIY@ECaLi*e}T4fcM_~iRiXY!~K&VzP1Wh8DegQ??pHA2X?GT<~8#7<} zSnS1Lv_vzxTnl^34XOlR%wez(S~KEJ zh_Y2BA4nSU*wa3fRt^b?=$HjTuR+7tvE*9l2}U0`_gFIL#^flK!pw~hO}{83&d4h+ z&1*Hu_mKu4uxn5D@woq!NdWRI{Ma`2wJy?esUO0JJqtpgkA|_Ec+fYP+eU0oCs!;t zG~euSWz6d`rIUKyyp(C7eEI4sqaU z<=2^JI#Oq9j;qj>N#}%}a>OM`Krl`COi=;Y|VfkiX7r#zQ*+;%wSb^W; z3^PeZt%h@~Kk#t52mgX}9pxuD6{wq3eyTv@HC9F{`kuP{NMUPQG9N{Jv2Rq1nEXu% z_EP6B`T0p3tYp(YoPj2vb&5pTMboeGWP8V41VfF)3lHcj^7Yt8?e5`?=ZY&S9l#rb zr^X01fr#lOV?-b%f%GZg?ugWzkpFRlMSjop3ujXUUWJdY$P>eV9|0#Uc;bJiw6|qy znu~+qm=BM2)mx8XVR*hWGHT~+Rj~Dq_YUK4*$8-(X1=Vt#1_X(jTJkEPd=4`>ZaJO z_!Sj~(_B3NYXo=inGMq`_0sQM+U~oG>7t8W-Vof4X1>b3pg-QOY?GU?vMJh*bM5y| z8M=Jj^iY3PrL`>uE}I;ISaX@!d|aV`+Z%xx6grcR@{av9&|TTzwwqu_!)mXS9q{Rfln%|82;QKiZ59mI|re>eKl=PeuCgXFz{wUQum7e4CC75g} zj!qL|imexVho>d%*!89F(CsHN38w5dl*~so?+@RipKtP{F+t-17R39rE+rhLxFj`O?~wrCpon z*r>WaUgjD|=UpH?N(-00;y|-!!{$O%08Ylim+9!g+A`G0*&|pW&oEY18~G!7OJ^J$ ztu`orI|UQRfj|wDO4p&fnNd%4%FQJ1{qQrQ3s$1Gk?i6<+YVmBkXIIXd7BGg1aCa#!)c6RT98VB9$v_xG@vFn>*cLXDi%K47kZRX z^-0EE`-EtHTr}|Y3%IRnwL~*%#7CZ-QwyITpiy?MY?-YdLS}EpUTNQqQYS2+0We(;Q%-wK zu*aEGNB)E?q}yor+xN-;JlXrKUJJuL|)z{meqEU}0Am&RWcC1C%5o z@S)4Fv&n`_Mbe031~R|6m!d@sr#Zp@+gKN9CMjLL&7j*&a37hhDnQtjaryx>0rCag z39(Mg?S7Y#3>6ITab+H`W=`pzre#>2Vk=@AK1{qh`IQ(-7!9L|XoxKNr)dars>wqr z<}^(yu)CK`Qq}EM5wYvlI7VR0R>!(Z#K0{{IqEWwc97E|WE@o5)&5@p*G2Ct(yaZ6 z{BkB)<^>&APe~&v+=0dUlJ`!>VGk4h9h=t`T*Z z%<(_BGIJYa>ebV(ll3ycjyXBj?1o35&xpLj@D-`pqQyzI6wijG!DouyQ`TtJBiYDc zPS|kSkQpizBBzjFL@kNa@}NUOYtw*LcW4IllZttp`#5oW7`T+=I5Rs( z&p&6d$=eXn6@DdACj)Z|sU9zgDg4&@Rv&%wpkTWknQ9RydS7e*xoY`!HwwvTPYVLm z+TQ=2$Kq|z3o_(r^fT)W30$?_MG1x;!n8N+EvGQJ$jwu()b8#3Idre z>EYZqgG@z;<&5wIq&)TdLb+6jdYl4|%k}ce>$f~y??_2|ak~!heHE8c4XQw*qEy&8 zgC_mkXRHRqwFG)YUI|S_>ofeRFl$DDgGU{oXYB%-M*8I=ay@Vk>aWgKssX-;SjY2e zwxw5WWLKz995j0S&<&WIX?eM$v}SDtApkgpY}baBPmwp9rSdfGkXNGawm{!ve^PXj zoh|-O`EA_IcWXF~tJkfrH+jub&cNRnO~dqD8e2`3w^S1$ato_#nw!_{KU}|eMbY7l z*TH(lV-0*3uv7RjZ~Oe44dK{n%a_5hUeLc_BhUwT8KyviN}4BSYrCfZuGH{(P$R+~ zfd19hCy;)1{}$d|xcC3j4j5oL|+m}s=+ ztPs8wh)@mlPVQDZyrW{?0vfx(0?!V0XRP!XxaLWO0n~8*r6e8`xd{;HbZ34I;fh-;E}Vt z{nzVdMMfQtE_K|}2)Cbuo*UGG9Mz7>U^jXh^uU6lS$}8L3c};2{DLh`{_p?B7cVIP zK~29KSRfJ~ojI4x&mA{`_6h>>R=FmiI^OSy?;hXR*}V}a4*${s`~RBe9IRR!z9;iU zt&1oVW8v5AF}`_mRGfQfe&m1jf%=kDq3fyT;)??=+K7DHV_*zoL8wq!#@4$Y0EhRf zsYkg!85zNt!=PM4Spk5P*gU*mbH9coNxKOzYk?%rcYX_oZ~d~*ng#MnM1$5CtopTn zf4j_BY10H@uga3mjiWf(`&y{ZGtO20+kn6S6Yu^0cgZzvU2AG-r2ci&>7SlnAGdk^ zoA|_X3<4ymN?A)di@(x%#5%%k;mLHO1=KA%5L<{wy^I<&r_rimt5A%MiV?7cnx^pJ zC4fNtY6kzMY8}Ted+L_=Dk)wTJ>!zwy{dX-DFm-!s2x}>NNVmF$-Ue`W;PzerWL#C zCm?jy7SP%~>Nl)0q2h!LY#@D7Wwj%0(m+Ihvk2wW`i+1z?v`%C=dHuchJwPA5-DjKU%9aB`R29aPH z`x*J-9dzAv0$s+_Pzt6Q)s4psoEp-^QawkjV(~*$YETO5oNInFi;?=Z-$0wcGW8JD zT!M_F?#CWf);c=P?nwwZiz%62#?#m%?LZfWHsD=v>WTLO#{1-7z9)KWkN0$$^_Fwn z(RzyaErBf|y5&N0R_LJ6CgWbQS$4}5zST>g9peT*7BeNVgavHmwg$|nepBD!bPMxL z5uB{$F;fWyC#TjN*1i^wnTF_BC2e|DRWb24g!#;i+nEoSr4=}e(}wrzPrA?E0C(?$ zFUB#klQjpaS!s4_ddu*Kav^4S)z<5#u3nx?!R6R1Qkl*1ZAhOA_&1Q*jRm%Ag-6J3 z)d_nm_W?|0o!a9$*b8EmU+&j-7d#&8eO^(K!xz*!y7fN?vwwGSD|eyW=}l-Sr3i!a zCnu=A4{+hgvIix(3OMBxQ~lEF8}4uPZ4M(oj4iw}AjATFU9ui$ zO+rZ?KbhNm3VHIewl=SO<(~w$Cs8{(5f}-UtE}Dx8#Uq_w3e_!U zLL6mijk_tC-rQ#lHFI0&bih{@Hq6atz+qKvl}+6=0@r*oM0dd*nOn2ZF9k)Eg7k5nk;zQeDwlS=a{rJ zDhJ@2v`KgdBd#7}^u>#`+b&CAnR_YcG5S{-lty9e%Anhlh$RegMf%*Aj8sFd*#;h}-y~s~ ztls0YJCS1*?DPgr1|_X44uhs+hORs@)gDvmYU+@|Dp$9l_DkHI#HWdJUI#7~$_m_> zmT}90Cwf!)s%`CVq!)=i>LfY9COWRnWx~5kr8i9* zMeeE=cf^gq`0?FU*PTW0$Cf&^*oxO?@mo3qx96RbuHH%JbH(HE?97Q|yO? zUmWmdrPpEhJEHK~uZXC%LiPI=%Ztfut)sfK0CNPTU-+H=h%=&F?;WtdqJA65ik2ig z$hmOMXH5v=1Lvdi*LTWVtKEgBTH=rQE~B#Qwk_gg*~)zCULj<^p+77yx(ezWf{GY! z{z9KCx-I~ozHSL7ynbwuxC3Q(k8~UI<pZ%1c${|EAaIG6v8i7HURxP6KRm04k(d+^^=%V((PGVO)p zWzD&Uic+bRC%Ef%>w_P1mH{QbgO!!08W!PK6A>1dZAP&TIK}k8uG@>l-I+b8YvLx( zI#wUdzp%zLl?h2#O=#(b>Jvhvc!z*#fefLHTYpWN#>=cIDP52>M)F9NLFEyZz;BZE z(sg`=h7R5e^^lZ6W5I+{Lx0tTI9{6Gmo=rvxgedATUU9N1vQh)0T7|j^4M~d=5Q2Y zCb(y&*SfPHXOJbw!bBqR;3u$BWynkA5h8-np<c8WiloGGBa;l$uiW4P%FC zXY+1Rsfv8xAo8d9lI4R@&U84-8taLsBEXtU_76GdJ66)#>->tSO|7kS z;<848l}a)?tsdXV76zm>LA{&aB=$MgRm*oufCud=uD>O!7xB-S8VVhS0mL$8BF^m^wW zfA{S+j*lDuyJ$U*%8F9WCZYIu81OLXuq>DUz=kNbL4$(6e;9+Du-*2<3C^!CebSFaPKjSr-^ z7rt^RQ^a#m5q@Z+I3G8f!Sc?6AI-ZkxkY#+^SE-lE1b^==PWrjQ=x^uZvx)McFkCS zhCJ=s&l@?RN~4E^BVU6ltx_0&f(cq}V@$n=ACBO&V%U#0uplZQS(AfNi^^~Z4G(v? z4g3!(Cc57ZzY#XK(<$AjM|(@2`H%mhpS24vkV3a{l%x^j0p#{m*F@DrhtU$~E0zME z5kfv~({2|L>;TS(JKlt?#iId11WB&0qw(UeTQv0mY<_NjkpKo>lL9X52M*g1e0#kB zVlj$){=LE*e|DW)LBEoaU=gg7=X9WzTm=fxU#!C6hSDSou>`Lgxhx#5yy-Iv`bsj z5_q=37@+f&&nAIzoXZpGws#~;yihxf6cQ5Z92>Qd4V$?AC)TA1LX3#5c-07WG(je^aP(_c*XRz*#I66N>%cYMNSEGpNX=RLote;e&<9Q;I0lt1>;39RBaFJpR}C&r%wDi*m+X6XG<`TFEHcH7N-S z!shKHB;ewTIh}$!@bMYVy-h`&KYw73mPB4SgXM5RA-5Ha#$~ste8@H+g@9Awd=E5a zb`4IvY|Q=k7w-}m@6l}7vn^Haw^R3B$H8dih zX4cRRSeCpYxNNc~Qm~3>ZP+7gm+2JUH;(Ed@!_9N|@h`skI`(r@y|i z-)&c|x*6FFdyxWwS9k`IYbHS6kGA?_G%1C zyWJ-tZs@LzSJ(2-JR7ee;9?0^*WCe}-pI$*rf%6#)0Ujhm*ecBL`CTo>Z6Tgtw^L7 z;9R?AtikM_Ch5-PqR`!j6!1nL09gpkJ=M^c%>Ip-aeKjciDbR0Flb<`-R^l(zgw#m zf$AdTyj=%Oih`VMbybAdy-05*qABeujQn7|jkVhPMaN#n(hLJ~I7e279!wGL|Cw?8 zZpv@x7T!uD1VQUHido;b1Gi&)|4%D>T^fXo;DJDmty*{uOm#xKa#ds}^5puc=9AK@l;TteB!~~V-cd18 zxEw9XbmL(h4~p2pnwLgm=De*%S=W;}Pkn-L#KA8re=0W9X&;=GbWjiv1*u|#z!EDS zWn|^~Xbk^zAEVlUq+M|J5jb|`fAPAT=ttD^9m5cQH2}b^sUwv`ZY@s5+qd{S`oGn& ze?Nb#h+urM7DO2>wO|XZDIY=u4K~7032v=Cs)nDwLhjy4QNPzt)kl}WqHoz zy(c}o%BPtaCnn3h=kv&`4uw4J+NVa3`}54Y@HWf;RL2{$4|4tyKyuhfT2n<@M#-G3 zEZ6OlSX`1=;?mR2+&$JGDkei^6k75CErHlkt0Z!YgYg1gAhnAcdU;Mnqr6WNX z1gVP2DN_s0bmOQyu&rbb={gEHxX$X07h3{XDF|P(puRsO|6SD5CWE7A#0K1`HQ&Jm zqG~lE1xx!gciCc%xcubB_&)OTEMh4fjB#0r`zcMkxotli@Ja1+zsJs#>AzDkp2Ryv-&rD}Sfr zFobPyEC-GB6?M(h%t=s?R6zPSyPLmLGimY|r_8hCRqHnuc_By?lPOa}Ck9lvUo~a( z@mxuM_FO3_01Y0efH@j2>~YG{fXJTEzwp6W4`l1G-m)`_(sVjDQ7czVfVyVrcGr!| zGz=e!3s6Y=Mq{i;$LEbEa5MK}E_=V5K}whxA<>`rclsk|btKOeUYp>l;B*67Md`HV zY8bygiwIoTp=E8PBO)FL!V z<(I8TL0RluoS?$|zD>7bm$2JU*>xD+bKrOZT8tv6t|{3X_ENI!Dg?PS19pZEuOUDL zDlA(2n$J4Y)J+ihKeTud9A4j=Qq?3FHlDv1t$Yr^Ck7L_NMl^AP;b@7g|KRm9=4Ir z>NkU!CA&JU30yEEQAqlZib4R-FX}v^=5xesOVCUR2B9KWT4RMZ0OwY(3!mrpz5|_2 zpP(kx?)bfi_Dt>pw={?YwS8G3e<+yv!{a#yZr>3K!mJWNx33zc^Oy4zo<`qtksya? z0fZZ>VdifuBgltCsx0(c%eIAbcVNrE54Y(ANx8wtS$JTe^#T3_y`9wgA0ebNAL=+? z7JofRs?-86%FKS%7?QwiDWemKQcimI^xnSFbX5ij!#}HLt73)NfN2dIKmBLS#j-Z| z^&v23u8x2rqB#Ld0s~6T2ws*LetpLt4_f1uWAM||zpX#Q{?Y*&)$E}nwIu9|*^_pU z8RTHgzWcg+R^G6OZ-w22uiFDfO6HJGvW8SngjnJedLb=V<-j<)@^{*>6#~16yIJY> zcG--z)rGvz-I-Yp`RqrTXx8u~K*t2A4%C9fmsH_)^_!v}B&L+aQ--)tOIG`vgcS&5 zm`29PAtdCMy6KBkbBy=%yMxs7M5>IpH_$@&FH$$MC%uCnRKBMv5h^cNtF=Ei@~h)5 zf}#&8q)CiY2q&iP;BStQA`0t@49enCcB0+XN>z?%x zWEO$kN>OXgh{hjTKm84o@|(tux_K82>jMmhh*dubtr#$#ZcjrogP!1#o7oWJ+0ZOaT_^Yhf}#*T|Xi}fsQ zQAiAx2vsa@2|(y_e7K_gE^I=EUtsX4^c6GH zz(=J@<7uefDe^(yIYnxzloX$UIp06ikA5Wp9tha@G6C9--evZ3YT44M9IU|lQlv-Q zk;{m_UjMSOUdIkF+Dk}1SZ(pF3KEbAmlsJc*s(`~6+48)HTPF(VgLP+9@>D&&^yhV zG!b)4XbWrs#`9-2OC$KIsBucVUbdv?#i?f)>Q{``_B*V+F+njf@1R_`JCQ`Sn`WuC zUN(y)%mA5#Zv+cR+zE%#fAG(%(}`2hP;{9eg!GqIA@ecGxjy}P#MTTz=54dA(i5FB zIot6Hs38ENk(~5fC$wzi;2mp1*eV-kBy}36iyi3YxDR-;JrD zIDl-(idWROc+AV+*fw6t0e|ld0Tz-Pxo;^!`FoH84i1(a3+vsLp}eG?aG%W!T@q=0 zPf>=%lYYBk@ro~&BEzC;>G6yGxoqw&nCpr|v-A1w-fUkpd7CXWqZ#18Mep4BtGd3K zZVA=Wx>~%ls{IWYUws3&E~s)t&*w?=N6(TngJou_q{)FN!3=4K)g2hgvV=;PLml*J z0y#Mo$Fzb#8q(Gs-5vRg=lnwIa3t7SPIaq%aZrvsLF23dL9@H{0PRZq8WTR#le!94 zuIhu>OwouBgCIfjX==MYkg-w2ZtI`z6WwB~ehmZRje5n-g{O*TaEa=Ms3j;!syj50 zxfkLamQD!xG6soPS2Y+i>EqS0bPSQTmOb z(4(T!lj%LfqQZnH33pQqeG9emG5LS2N&m$#-BL$@+!G2bWdAjWxOqv}Z1eVEP_Uif$jLX+oZ^nd)YFkfg{cO%j6Sx1t!LA`fu*3H>w@5W*9wV6- z_4c##&uc=;S1NA#JqHLo*&bxj3r%o}~KLkuZEncj=fDrM}hXg8LQu4sK~@~%C;Wdhgz z5)hGZ#LGGTloTX=5WBcT-2Ar5Y=J__@8j}sM)E(9G{^uG;;@u#*qNS9!m9?ZdnwMJ zb}lg9yq%AJ>u1}~28l_g55UI14IBUqvmJ@6@@FYlAE%hL!NPaM*hjma0ml0C*y$($ z)fI~A!2~;27(2AR)#wM_er!Vi!#Ro@GP;n?V6<9rir=UEQ+T$svcCEJcOn>X z^wSG}u+Cr#yR%UwLZrw_LW>s?pF@0?Lehdb(9N=+?*rRsFdnuhTOW{e`;omu$^)Q@ z)t4ZLbn>LcHVxh=T96ts>d6OBfIbseZ9MO%X&H*+#(65n+f}y0>JEg5LLWF{dT1G;M?c-NDa-3TU_=TvmhfopAQc4|gVflJLFQRPKrY;YR8fMT)EaGxfM%^7 zTTjX@V0Oa8gr8Qpx*>+UKAR=xVLm<+w4DqaPNh};$q=n%9Q$c&PAFm)yfpt8!`^=# zKRi`$H!pPu>88n}i)R)hTPc*|t#Viv$#G z4BwQa1}nuK75-*R zMs!8MU!XULJl0i^x>8o1k#<{s%Sf$gnu>DXt5-g;tzJ(EW|#~JDlJ|Rc{FcZ>uIn# zM0734v*=M1*>Fp??F7h}>nyttJ)wnUu8lnHs+yk0W8ow9z~zgWl{W0g&{!Qf`p%fi z6d_aB=ZEzLKN)_sxx8LT3(&Hm^s_$f#U83e%f_&-Y6u=0;3ZM`l^fITYs=<^fG`Y`WtN zL*bcA!GBu-{2Gs$t;ecal9}2E`F>*0XM{fDaC|nI4?S1ViO@EV@=4gSs0L5*svth{ zkjTy9Bco^llrW2W5Ofgo+pVoK4@sE>YOXwe=Xeeowziellft~n@Nxaf7BM#-P!mM= zQa)oh45t_tNlHo^FjJy2=K3GrFRT!SO9Mxu2$Vs3V7eGe8NIQxwSR^US#?3}76F1= zPe)-&3(FcC5oFWpwm}JmJ+uBpk|Oc)Zj2IMe7Eg*pT3K5G2Q!mCDT9>(4Mo_mUS5j~$V!cB=Ec#g2Bas&qD^{>QQ z)?Cn{OnDqe>1koCtth5WlP+a)jVO)G9e%=85)9GSLiyCaL z+yUM7I<17B#U>>7#KqX<+LV=p+g|*LX3~U;W~3dak?QPPMoPXeYQu1d{d^eIO`~2;^~jU^)JRH5YN=BmcK(ZP;$Wd9iYX# z!B?~2V^QrVl(0%*>%=<3L4Kb#dT++ncQMqBhx~MLC3fkP)RO<3cNHRi+Qw=;VN1sM zWW*&TLW@f2&HZhosmV=H1W`UfgFb#E!Ucv1166rQ*ksozZl;j>e{}WLVNo=C+jN&S z(kLa}-O@@oNOy;{>>?oDDX~jSgOoH&NOyO4$HLO^a=vrU`&{ogf6p~D*W^9FyV_ak z3nfW+G3a*>u%uAl>7zH|%Y;f+IGquT1l=g;U$T*ld3J_|nQ<=bmV!K^z6*5?r+ahe z`4y1)?_KloD+Mf9i8XY$pU>ob!QI{6q!M~Yk4KRd>^oXF_Dw9@0EHbfeWW7TE%DfU zS(w!fa7KbLTQ8dx1fXqa)D4vr-NO&e4_oro)!%Uewl1#~0TSR34JxhT)PRkUCx#!r zBIo8L&su4IL_n751Qa024~Rn)KTfd0M!Z@O>K^Qg(rXP7wVe0jSIjq`)lm6e#ggc} z{nR^OpXpsTL<2gN!A5iYFOX^HIEh=qSE6{k;66M)l#WU!{&6V^_VT8#$#oZMH@qbAmvZ4 zzDw-i#)5~CY;jX*e-~9PiAac9SZJa@fcCr=lug8T&u<shA)jU!?y{QL)uqd!92c24C>nzUGF<&Xo* ziWE7o#Uv9!Gm~$=64!;@I+!thyww-9)5o_6#s#>*-pE85ehi6+UGLF_HApYRW@~lic+#Ho+cqS`u?X3l?sMbx&Zzu3r#G|*E4burhBe(_iHq`pt@NUcS?r}@ z?gPG2uZ7D@mj%5AVivg$eTMqFQmm8;ti@x!N#lTu;ZVglFWJ<-9qo_%`7i{8ek|Uq zI@J83Figoq?KU)X#b zKk-DRTY`dzG=qjnZWf7mbrq+F?yvFU5-*>&4ZXn6>@`#jdbof%(bjjZn~e>`Xk}mZbk4C_->`PjpaM%HjKrE3fm(@+l1O{2 z2jP64@Zb(y@u}#v5)!sx1TH#w;IOMMdO)6h{ojn;5z19c7EdNdO&^~4_OL^gB5E-` zV4aR!_Zj#OU3j;DhxV(f7PfZfwVNIv8Jsp24ZTj}(@w%jc2ACJpi#;_4lAeZ@%=EW_eCydn7jT1YQ>Fx!xQl3BB+f^%*?LF7~|}$@vhoM{Du%( z)@TPvB0d51uzx9--spXDGe(`q!&jxDTiC%4H^&Nj3lCMUt2?k_m^_Qo{cX+J9aIdL2|wAOcn zZ}Ih2saGu?(5G$X<&D*KKSw(57oN(BJg#@cKAMgSS4n0A0h222%Acn;(G870)Ic6G z?T;jy``VwcY))z+`gSI|Ye#LkoMtbq{fyn5FMp75+My_<6D^R4D3; zTjsE_UvV&Edz-9TxG;4|lEuu2?GcZE{6qm%q{$Zh`NUyr-_AMYK!4zKuH_(MTRRCJ=@)@RYq*U7(oTOE@-s@#v7z_qEV zl(2q}de|_g`U8eLjILLv!kfIsHtOMD-0<;-`6h0`qEA`1>EDanCR&!L#H!bfpKTbA zQnRC2(;EcQ9W$z>){Lz4`0kir=ZhItkY*C2EZ9>`nD5Lm6=L=+Q|v1cB=#(s zq>cQcqM&Bw`5Yo{X3`m(^F&LkqNg~Jg>7_N19^cqoK)N}*QS>=e8@6rzeL5Ix4`{l zNH8(I6M1MujTz6?KqqVp0_h&Fwfl{%HghZH6f{s55(v`qo%~tbZX0vFT&?f&PwREU zmou55lgBE@i>7Baj9dcp2faVSe?EmV&&E31V+0ND(9KV9E+&b2&rv(^Jh0V-OZ$@D zDs#bS}4=Zp0)_6NGw*Kj3nNX=3f*r zFIv_A1Ac?0%Q|@{%in*r;#HVzKIjwv36CL8B2?ePlJWi%zJY3>WFsus4~c| z#?dbj`o0}ug6B)MlyQWue?eOBc`0~Kx+d#1+1gU6pibY+m zq5&?6+*r53u#!q~jf&(&eY)BkEdc|v;l*ymUe{jVn9q7Xf&#Mlr<;CdM&RyvR^iNs z(i(koIa4-s3(^DfKe%i9aDZ{LH}OzRPV4<+_mD+|0tqTQkWxYEBJ8xZ2GwioC0({f zVKB7Q&3^;bBbnJsSZ1=9S_nsE+i87fc& z^MqXdJ(WJ;+bu-285>0+xVBID$*t1U-lE8(9CL7K7)vGue@>XVcI!j`zN=qC0QxpJ zP9r$-c4nTFWM}_A1*=CcsOnMQDkuG7lQaM;XxE-BsM|6AG&!x?6|f7Q_8<6Q)$^+* zSU|Ojhwxrosp-8^!FvqCeBqVu$sBGsYOuqROw_lJxJyRlHM zeRn_nRriuPgEy!0Zjt-6^x+gjlW0sqz}I8foQ??Za@nhNmkjj%p_F2t`8kfOPhb8q zUUUd0IZ%A>*l+GP=vVKj8?=eJ&A4;=H1oKJrt2F@2(e?htqJ%~r$aDW{PnC~-gm+a zE4e`ANa5R=4$r)2|B9Ax6Vgi#6_{}oio~yO6}R!MU2to~XifTAL8u`*rWm@jlH)+? zI5eeNQax|<`9|qfkL&!&Q>Ra zhGNg%htV?*YqiWr{@lyw^}ps+{b7Bw;Ck=En8sUb2J$b_*?*Dft5Y*u1MB{Pkn zvg@i6jq1CnCA!PU?GSGi9QC13HW}_p-S6Z1QULml#LRgbAK9+GVXl>>HSTl`8Zm;7 zTZAQOD;K$d8l}&Ad5!3Mqvf7-*(IAwlgzW>^-`xJ1%h#I;HdZsYr{~cbV{o$*`op@ zRt=!i!!IZ{cSAIsAE2~|AYI&|NF*}+oav9jcAGhR!$;IT?*7VFa+@r>y&w)$BT%Kn zTwgl3id`nrA|_pfvQ+w3E50J@5;qv8+bnl1Lnzf<%JnfMX%v$9E_j${L^Q0~FP(hr z(_AGvqm7S%3TQ=5idgdg;5{i&=U+hl8v-rOAHt7k$%;J+UzEwXlE>#@^5umQ`;51~ zq?9N#P6Mm_W?x9|kFO4nW`*SVD+tpGnj(D|*aA==q$!Na)eeW@PFL&X;lE_Q8bWz= zW$c7Q4Y>rg*jb^`25C%4j?sAV&QH2oPG%oayq}J4_K3J{&CDn|J4cZSQO=#QN z$F@ncVbfoZ_VDj|Wi#X^u~sc!lz+c?dM(n^*{is`gVJ^?%tYtTTah3!Mt&eHUl{s9 z*ZE!x3n!7({-M&4qmv=SBx$$rxtK}Fe0}+`nH{!}J{7$BNSGc$D8Yx4)0 z|3K9p{+@nO0|;JK+ZFs8v>)WJ2$-KNo-dg4bpsDsDpndYUJc_VV;D;hRmmz{~l;!*z_a z-#?xk;OhHV#cOOqa3Y6W#V;fvEFS+UKWBf*Nrw0!W-)!7RZamx6D?ICG1TkWyuo8t#H6;zo-R4UquKgk8;$fWd5y=O z|4CczxN@}ZT(o_*Ib+1ge7y%!tX5&abE7#=w7j3vfN7^`ax_P?M8{J>iv%WZ0TdPt z=jlek(w|fwg->VRU}MkPNJP)^JGdkMXxt)iZkWk~{)A}4m_k0b%m&plH}TF?BBPM4 z=w;}p!AoM}bZlQ7b2`a8U4&CV_sa#(MLZn^hpT*@Y>kU?E5CJ7<;c8GR((!0y^+C% zH(-KFZW!(|e|IGqry)8AbP19&G;6b9d7qdq*>WVfZCy?BC)Tx<=winRul z&#>YHRvO;3UJ@r-CM9J}?H(sxQhF|rvH1jRXJQ9^l}0<18Bnf@an?cD2FS2Iy)(OA zunNjwKe8I;i4Ksh-y*urf09y6#`F>e!F`m+m`^qrA59F`qa;j^qy9#n_ z_^sp`7(RQ|W9PJKo)lhD1lHas~{f)7Yg;cN!FQ-&r5F#)6|J}^Nc;SQG|lx z;S)sfuVZ#}l$F@Fi8ZoEjdoImz8IS1heLpi|$*W>y^U-^Yp#o+dfD!<1+f0%eT zb}1WM$CS&h@zo+HvZJ5TW2wB{uIOoC?$5lkeB?>RSymn71xD8LC%TimwPHj*UJn@Y z)W5G#Vcl7e^K;rXYwBxy_NiU#ZSXo_wfWR|`eb(Bg^$LEltW=rx(mS}ImPrg1q@gI zaw0GejVLhz-?G9YSXg7Xfb%N{M?5hKvRqa&Radq~-hj}P&SSN;HF2)$IjV*7W+55t zik0V**P;NxrYzvpb$s=a-xH(V1I7

kvD;X(D%Sx5VQn!{rZb>+qDX4YN>HoU)}uo` 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/k8s-components.png b/latest/bpg/scalability/images/k8s-components.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3dc046c6bb35131c325af9051e23a33e606967 GIT binary patch literal 16585 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 XZkS`eu>Ixy9e%K+{IkNR2Cx1XA^YG8 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/keeping-up.png b/latest/bpg/scalability/images/keeping-up.png new file mode 100644 index 0000000000000000000000000000000000000000..1a6957f3e273c896a4f41d6024be3159a641d5be GIT binary patch literal 14536 zcmeHuXH-n9&5AVxcZ@qO{Yi951UEN(>)m6Ky>qnTTx*{ntJuwy*7OAq5yfzjV z4hp!hBg6;3`?SFlzy;e~TTvFPVt{c2_z`1msBELAhQ$Tk6Jp_G<744sNU(5#FUr5~ zv4MMftSi6Tv9R>98GhfJV{`mVA8L<<_cx6VaK-#70Ux0E-&fph?0-kh#`%XD2bGQc z&plQhrrSpEiac;3a#1pJ$HF3^!hEo?Qq!*k%W<~XHS{o4dnEP*=FDed1+%o~^Ko{; z^um(x5d&_WtvxJQe4L%2?qWWYw|-HG0r!|@&@Gl#}D)-1w&_xSGJ zk|JhdVUcjNvJumkfB1KI;FshrI}Z;RF%Zbx+ndi@fDh(o3%V~VDhj&C58~(N1t@sk zeW4x}KDVPS2MsrSYd|6x#-#55&D5W5|4A}=H zc^O?F?41mP0LHPghG_p-|IW6@PEJlPSKm-R+mOsTF^AwV=RA?Rhj;GF z$2cHzV_5;o+OJo?JjUIfZ1kR8M$V(n=Em%XRJiTy#N#r*XL;G!Lep$py$2*uW(AJ= zx__ED*VHRr5N-#Sj7307;j_6~c@Ou4);kR!;9wJiv2e(rV&PfJWLwyMHlGQVtaoMo zv8m{4uWYk(o!?5yhDiC!Zz`4;0URoJ_1ZJh(#UWYtbg0Ff?LVK8-pZXTp?I^zaM~i z39}E^qJ)HG{+i_10~QdT=Gnos3>DTt`p1alaG;u=sHtIi`KNyu33kF|>*FHrf0)EP zSdPL{3EDN(q54e*^gzmD6-a|7OQ?UXgHHWL%vR>nF zOcdlW_B*PMbFkW9^XwUp<5abEWb6AI0ydLHS#XD~iOL3ST>MGl8K)LHi~Bjp}k+6O*t~JZR#JBlC^omv;^Rw)a`OrFdt9=~wv%~B z5?US(ErY|^rOy$n>D*hr+fy~=juRDLv#y;}(3YLmcn25P4kGr1#7K9{RBq~kr&{YO zAqPAaSb|V#C@Capq)=@&_UX&Z6U2=FUYo62s$jP-O0WD!^HxPo zihynEeBAlC32Z9GHghB5VmV&p5iSlMW++p@({`??f4zqBm7;fD7DMP#FNOduz@jCP zuRQnWC8wSxoBMUQlsYxcdDWvY&u4fWW|6m51AOh(CHCdT&(`yt&ki@dcAM6w>t~>j z1UG%MC4t6nKP!u%r7-qKd=F(3_KNeOkSYhC=^)#4*4G|}`?=p%Gtaj7ysvGTMrokoW8NC%wm5?l2d}-4v>2?NlZP3XcU$)AN%$Jy3&ZBO$-2!Hh%d$WTA%c=ci)M` zr;JO6z(qIYKntgI<~|>olU4hI(B}|{O^eq~K#CXzvhDJ0i`KI)Hm*{5ySkSTo}C>W zoNwOd*ImEaVwwy;DuviLs8CL8>7VD(l$p1QO�xr}{$B>%PaBjlCR?m2?>}Tm;3) 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 p`3h6*>^SOLQCfJu5M+NU>z_N@@y>4k zEBsX1(W3SuU&w^6=i1uTukh_E_6;hRy^^bZwj-+MTY{sXdP# z#eOxNBcrIR?VFHPS$mw|#gkBKM1lH+-vaXHlgwY4qg5>UhrNC*GMZ1r>Pq4s+B(@R z>5=jLW7d=yrhif$2Mn~z*x#|KY8niNfAX6tmXA1F-n>nR8zQXBg9H$@=X6ke*SvXo z`X%@lo03efmTJd+0Pgr#Qa8$r(|9ske%?Pe4#r{6@Q6d5O(2fnMX!9XL=>;{h9bvC zvUpH#qJ;Z{G{mkz=rOdsje&ptitz|AaIEJd8LAaVc+_q35v~NJ^tv5`hOm2Mz3SBG zrm^zW8*)jP**_dDj%W-_7jHjX50{gVwL45qRd_c3PYR}Kgd@LK!qddKeA`ds8p}i# z7xj@`gnJ#iW<)?8Ddj*n64a1As_>H4QfYHPChIR`8W7Uf#bXWmJFEq+ymh#b&3Re^ zS|?6685b=W@}<56NBm8e4W-}^rW!BbT6OrHfndT@TMSGs#iT#vA1*K47pKpL6RG-k^2JHdDg9MeA?h8XNgOpyMYoBnr0c8egn?n>YUza`haYKSrO szXbm~rTuq=f6g=huMsTAzei(#BB8uQt$v%p{0pD5g1UT#?Bi$u3((!%)Bpeg literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/node-saturation.png b/latest/bpg/scalability/images/node-saturation.png new file mode 100644 index 0000000000000000000000000000000000000000..17a0c0e86af9295c3ded7765d5412e84fc6754bb GIT binary patch literal 16438 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/node-size.png b/latest/bpg/scalability/images/node-size.png new file mode 100644 index 0000000000000000000000000000000000000000..2821f5a7857be39feb610ba8d593cc87cf1093e0 GIT binary patch literal 43566 zcmeEucR1Vc_qXb%=&-6)T}G`?tF=qfRx3tqp{PAuVkAaYRcm&kidaR&-o$FPs;b1^ ziO~`(f{-A_^VadH&-eE{|Noxr`noRicDvU(_qoq`o$>ZeTT6q9fs28Tj*jW(jqAE} zbbBFmbbC4u9RONff>(Kfk3Al`8Y*=8ZKtP!U!L0--L$=PhfWZ9K16q5&jGr@q!o!he3ZZ4vh z_uQ;(M15S`cSh04`^W;1E;gQ)XMJ3pT|H!d6wd$bAqzb3G=t8c{n^FSN#VTF9qqHK zZVznEN{fn#ik(+vID7W2{DXV8vbxvRe-8(KQ#fz$>FF*D0(pCTi+W3lx;?N1iC?{X z6(n{UbosIf&_l$-*VWU~N5s|R!mmmG%yZqw!}@`PyQhPj>)D-oEv?*Oo(kvB?=1As z*ROqgI@tbQ$<^aGSpb2coxgy@Ma4k>%nb~c-)WWAwefIshV4wR@9N;Gcv=2u=l^W} zyV|c&Mt_GX%KRC#yYW8<82{e}>~8$e0pJG?HULLoOlz1kmg{@*=*&m|AqIgnik^y~D0wgShm$RH2; zN0by9bjIGDr=wG*yLtT@#AnYO?qH&sO;6KeiN8!ORYf-F@o|+ysfO2NZyoeKwuf!c zv3)u(n8VKZJo0?bd@JV6A>NBeRqpTxE#rqMIO<07H*UU!q@>p3Q{@}X$r2s}3N7jR z+yJ2pD|O+hGToki|7(8)sS7-x=#%{7A%ks`s;N6xhx5UjI#wzqoO?(|f9UL=A5zCF zdnyFUiL>#hjc3%GdJ*E5Ns0aPE*9cVe7SMXOSdfwyG!KHSx~3zkfz5Eu6-SB(ljkT zHhaF^X#eF?vmy7Pf96tFVEsbzxJ8~DThqgSHSuL$Sflw0mb$XK_^BjwAnJHpBWl4p z3svJys{WsGNFfC`a^kdaVph~j4M7Xph}^epSBK7OyY1f^vtutinl0vN-W-oM3hQ07 zXjpQwCMVy1V~A@GwH`80EDXYIi#%%`;k67v-!wt#9xkf6dH9`7cFu&=vEPRiw0=$u z2Tp%Q*w3a#5ZjjT)DyYErYZsn(?2y*KBeFIN(H)=rXAk>ssAAC9Hg&4PNAo@Fx`%I zgnGDj+e0$_CDluj1VZv4W;l6~$?%!=%kt@~IpCVnfljg`wnCv`86rvE$Rap{q3IX} z^!__db;A}4YOSlK;=%Ek1u1?p9#Y*wu` zS^)G9O2CPe+4>5{rZs1(`G0umg|M&I`-f8}5iHhQgk-l4PjlgfByf6e(o&@yB( zt>MRU>}@Rid>@D6ShhdA5B^6s`#UD2Y@C4X>h*3W_rT;{_@Fu!s-|Ont!J16-QN7n zV2RoyUqB+JCO`w_(W8mtg&cx*W{3-iH$GTTbkH_i@y<)dLc zM(}eQ5x?xfruyvuqrmp15abLdt2gr#Oi&2r7t?C>6x$JST;ps61NsG9Z{5}M`53mz z98{NL+9N@1R*y+6Dcdzz=g9KmJgSytu=l?5SmpIz*`rO@{<-q~*YAb|VtVv&Gx()p zydG{O)5n0_F)9oPET7gYz@$}J5!N96+yOG(omsyzgY^mFg19eCqUoUdR z`2A$<99<4@8C}wJwy0OOm8r!TJC;M9XIZ{Q!WgxBGs4A+CzG!&_Z}u18;;>eqaZ<< zH6wa2&>61ZO=`|-htsn{%APjo|4~6fBCM-91qFLJy9G0PvvU+GE+Q9W2#wO(K{3K@ zEBj{zeI60Gu-iV&RKH$5+`K2&z$#a3wVlsWcHoDAMGAWfqdZKh=Mc6;A?FmvORYP^ z?R!?MMSASzvSJbN7aPUR8oTb76R-Bsn`%6K_mO-6I}NA_ z$LVKb$@fB{!^)7z5`~^xF$NexPxIw?N~GJEe)@XSWYraE63-T1S~_WtC{uT~h0Knn zARY5M@8_IK{$wzGwediSRSV2j!{BA#r&#in_Xa0YQU)EnPapat5-5oB{+1wQoFQg8 zA^sWlh?<8t`7n$PQd7U!DoNLP38{0ftr!i`AUUJ_oB|3*Fr zhHdJlLd1(t*rJ~5*34wPu(?Rr>CeK?a=cS1unt@Hx1XRSBVDhHB7EG1dZ1yP4QeW?agMHQSBf<9O-E7)qi||&x zzDk-xAYttZaLcCIb;wa=l>-35&^-^>!;;;gRBs%(J39Zw^ilk5Hn`!^kCdk{d?0MR@YX_1AFVz3&wth!o5{^iPLB0{Cx=c1y<}4dE!5at!ik zpuIBv1w-?;&5KM^v~kEW<&^u3ehGFglCCH7ng2EAjdRM^V(6bX{;{e*=~TYFhXH-> z@;8k?bN^gV_mH-B2A!4ozwGAo+YcWJ#vdX7v41}&4`KyW#ifTv5&z=aMc`81;``|L zFWSzA(Cyb}ILm(F4?y_2k>-5@sF%%RJpbM5t`qn#SN|)k|GifKRaXDitN*oD|7#4Z z^5(Ir#NNR(&TAfsw2A$_!w+V#&+hZxF*sY&Y<`s^>d!{IF9bm)Xag=HS}bioW`B`R*fxwsv z%S+NrLaVXITW)BU9E;z~bAq2Tonm&QNp0lZElpN4?%%vWP(4sr7f=yV-piL)MHLgS zI9wOK%^G0;eIqgbOKF6Aezh&740)0my#4N_FU4ofh=y@?Fv{aA@7VG!s0Xm$3blId z+i#GX@{HlzC8%xfW!ZkL2TL)zcZ7#ki+Vn*ii5}L>(WPp!L;vv?oF{kaEph^G1k^^ zD^{pi9Ou^0Z56LX56JQAeN2PaywN!(aXu%o6fFg6W$FsGBRSW%$_;kbe0i$U*pbm1 zwY-!jJiTcWL)05$0h64(ZMQzPnIW=T1x!zSt<~mo&xP44_5a}9D^dOSL1prg@$5Xa zT6q5SlS%%;qoAj0?NtJLjmG9i$k%d$btY~V5HzRWwVuXserRA?kU{UJ@z?xm7b43k zHeVR_~7rWf&>4 zF7_@npxn8(qH2-J&fA#2-8;C{aB_afp&KVD*KoP( zvLDV|y4pUTdv-(va=TV%IYdF{is)&LJoEH${=P6GAAegYocFx~WMyV{^xi)%(U8&9 zYv(yWsziO<3_pH6t>Lvw8Q4!r|;Cvae095Q+dGBw5N(Gok9yp&wAmLb&O$0i&`l#ni`+!iwC43lHK zYw^0ROrw?&iZ;@#D`Eo^a$SQxHaOkjmL(X!k9-OFOIX3v`gA~KZ@;;(udl#rnn%FL z@V0GsfBWQ^w!=_*sl4;r9Sw|9jc1I58>&s%ZP2io0@grVUh~hrPh76hfmU=MvZLW^ zW$wDaox1jJAhy}qo~IbGKKgC`+{Asi52glFN@<1>XNs(D?!RSqTR5I=8wE>4_)2=H z`s(<_^Brf*R9f>lm>JK~_Lf$I&nft!CR^-yJ?6A|inRASpkRWFoIJdVIrEz9?>x(4 zSbGi&{+U7Q{RViCd~U@Rf2*vCc{Y>EGmfx){}~Z?Y9%g|S0ZOPWWK{hr>?F0cxErJ znha^n`(cF2|cG&2~ynn+U3xnvtDa%E!f5H~xn{zah8~w7syc zvuIcz?oHGCMrKbWSmmj)$$VX!w_|`=YDRp*4iv$T$MI|BFq*PDN})N0zV_-T#w>YA z76u!1Lye8`U)j~}uVscdUQCOvnlR^dP!5j@;E6X$SdJ*D zCTk2Sgt+Nfg--d%S}@@kS?XnOQPVDU-zm19{5&mof%5WIEL&!n&?T?36j5jE(8;_r zhy2J{m@|n-vi|zD3z6?fYUKub9W)-Fq;f>vG%-VkCozQ91te=*U8m|hAk~+01lf6o z>+Nx><)!i~_Hcb7xFyXXQ{QGb?|oQp%kbA#zReoi$dAVz2Wjhfk1{~R$DMeBz#-or zM&yr?W9#J2R|BTbT>YxCPBX?|8#^O`3-v0H;|niW46~>%jl`YlXB ziLsh77hf5u05?JYwmh&gs_VEgYjeOON+9xBG!VkpblldciAOZa5{C zx(O;BZ@9hD(u)9)z9)-rc&S;Jy>}SXM2O|x@Owi}bqsGhjf6T1{KO6`T)z@Fk0<8& z=e9qc)Th+Njc9g@yI3kZX6hHPBi+D*MHalX`QZ_UgBL}OP2->K>|0bR%xm?T|@ z3iK2fD|Zq9_8qOvWPM5CGflz4u~s)It3gOS&4W9(hyTdiRGocn&`uMYd6#3O^rFx0 zK2VU`*7cqO^0@OqN@O4U(!$*ja`?BGg^z@8^-X3yF+fUBxB9(ViQNA|bw6qFz|b-> zJFMCu{PlsCS9&$RbV(FSHjJJR4A3*Ice_Db>nAm>uVD~EuI0^kOl=F!IYC=TGX0#0 zO@^q1#Q9C#Twx0y_4jhT-q?kjT!IPIdDidZhkQl*Cswe51Bh>?v8-I9D*NLPe67T+ z-S;Zv=DG8XKeK~bL~J_vs_^=xx06jnZY};O zpKWk58;KRnwD*DiPzjm&5ZT-rc5_M{MMDXG-aB95(WAY>)uCo!k$yU2|l@ zNNh793Kxj0GlC|pIf8SlWY?C!#xrEgz8>9--cx0_9hBe;`3K(IU~@d&h4Ru7&!FXt znr|=gu~2$YaF$iEDNKD%hLWa`V5a2T5o|B+1cNZQ-TgJkYR}Dd=^hQa?k@-ird6>_ z`&)0?sMn+zYDcp<1s~x-TbJbvG)2_l`H&aMF=6ijE0SA@@t+X!z*uNDzRst?cqkiT zE8vio<%sM+ggDwRF#EZlxKvAMp~dl26QIHPCwkl2$%yeP^cxdxOlNp!Bvhn6&&5+1 zKb!ns2JDg(Ncep6clt`1cPF4$wil;33GUv%@{w-6IPA zkoWW;wO-#Bko%R3VKhYg3Q1+QpGQXC4zw!qP7<9I#)%7kE$kWLvSC@>TKhe@O;63T zServGJoKBd`mn zr=Xj$@Ng&^(XuQLiadgv%{E$ftT%NuT{K%Y+Xg_b;db4Lw!hKqqK5&a7A8x?1Fy9g zQ$q)PFM1}wV0Z^fwZ2Uy*y{5`-arfz-whfN#D{c~HPM?nPc=^~r=!15BBl*ua1}*) zGnK-$|ACcvaJc>G4lG{)J@5J_R#@j06c?^2g)3lNAV;{Zen%WkRL9b-(< zVbs=^nkk42SKS>V!?32Lpf#bC$UlC^PU11r1b|;Ufwg9*cZV*!Gl0k=bf(zt5BC2_ zPdBhuM*(Ybt@O1t?oOO4Lm9NSdoo06>bt20_;sxZ zRc|i(ubA$PERXSWl;clhRtbI+^U zaSc78o@AlZ`XYA_25&h0A=fgl^m*vMLE|-x3Mew*GIx=uE@_Wk&;(`dM}fm zvx_IhAY;_J=_Q&t*nLH*kPnwXd1$JJn1QeZ$nRFCz)Rk2asxs=sPx;(d1L z)%ejhFXs@|O(>MQ-lS+qxD)bq1u2LR_+k9xWFwQ}Vij;)Bw$F_n!d2JUoT&()ol?? z9p{B-9YrkMY4Jtgt$m6x5esJBHZSrBZ=x6uu&3#PYIwPVtM!Dr&#~`_j zTQ3;I1k^5US~>X`%dC0TFUXI0!~?9-2L$Fh17o-TJQEm}P~E8qCF_P@m=wq2zh@g1 zqr}L~N4egQHz5VRx>ck;>*eWZs|1!~mm%je&(8^g%g*YvV*&y2Wx&f8A&5qY)fI&( zEmQqZ7|d}eOl}wLW99p!)`LFty=Os05>IV<^`*zgn93I{%uN7Ss_ZL72I4n7oBhbK z$8=YCl;GI|4UgpBXot%og<#j9NAyH`d>1;XocUy_Tm{4flHHueD;pWqPgY zCR?kuQ0@|S;;@htJdN<}vG48k|A2DIolKWHC8W1uVt9_GeeIpnDZ{?Ifr4LI9evS) zo&IBcku(HaXk-x?!*ZPdT`_5X>j8vGRx__8j4P6 z8KRR-Yc}xV3pXy>FL=F&82$Ga+pEy8TgE7#)wx?1sBKuc7ZCi5;bs;o=lR7uH$FyN zOF%BFiFfmBEq#l!U9Fz)>y*a@0%++aERPlg(hH*IX0_df()B#bRJkO6oSOIOR-UGX zk9yFU z`Z&Hn1ar|lJvo5W%afCV3qty*>d;Y0J6}98n-OHbc`WAPzNFB*jGau#2Xpmny4;i6wW1$NAmDd+v zfH#0T8hHkntVfytbGQ)|8QEGP$RT}puF-K(tQnXHZhSp1i~TO&=x2#rizLaV#cG ze&l|U-OYwQp008}Z7XIk#OgC&P1mJ{eT+iRC{}(3s&phNi`^U3&lunASaC?l33|>Hzv&z!3tc^!Wa=5M#~YrL*z+;Y77;+q z-t=66XvT+SKSQ#GUrJ^($>_eUwoAJl1B9AyNzEhPR5(TSv7ryzT~|lylO8pg&1WV+ z^e@xtg2W`Hj~qH%SoMCdqEiOp3=(7K_>y3UG(-eU?^0K1--}^4PW}?(l+?rSEc&Xn z&sQt}`1g$-(~SHp-#?#FK>*lcYVZH!J^Vsa&*}EF1v2kORdhjIJD}!hRO`Q5_b>=< z9r;Vl&Xd#*sylc3KT641A%FJt2NO980N6|Qiu7(sxCcljuS)!L;eRn(8$d`;+?}8N zb1`=QuC2Xj_h+VGJ3^)IP%_qkEfAvHu!)R$CQdI9Ef_$=!(Stn#&gQ0{L6 zQ=S0mQtGj_#BLO*e75BLhc7X4afXRab~}Fv%DW(zPn2>nCEPf@|M$v{sz6L8-rE$yB9+-0p$Ldwf{R_<{s)_iIVBIM6=U)Kc^c|+rck6?a?H1)`iXi+&6d8$#PXIY*O3-{2j$!8d#zm$ zoE@j>6CkqKc@ZC>;dGb}rLEksw_IAXBuhll)aBK!$pKBZ3N5Dc$4B)?BBJbh!@(XR%ry zV`A)wD|cum0)Yc*L8p{yd^V6T`rdccBKzfGoRdM1)Eu$T%ZDPCV2tVS`&RhEcyF#L z+|*RN{IXf_>94u+b8D!%v2t+l-Pw3NelSCZS~WqjTr{M3b{v#W{gJcUAyKn;eDUf9 zmx^y&mN=>TEwyPgM6r8f>m}1Oy{BRanzUL5y4KfV1R%#%)5%7;*KviGJhaOfiri5) zdjg{cndcpRqgGm{SnI=V&Bb7?uGYa4n1M@9+qQX~OLOJyS%`Dw)`!g18Pp0~@%m6b zBfd=H0kx>>0X596!2eR;YquLF+L23-t~co%i{-q~b+BIx$R{*8kxC0%VxOoTyvJ0O zld##|*;VIo1SeV&dda(W#!ku9+fBd(l43Tpv2P?GVO6xEbte7KOs)_ zajD5TImwQIZcRRUH1j-{o5<1{RaRQ+Hc#tZYLSR$O3;R=J*fFdKQo#B0&XW+mEe9X;D|je#wx1KsY%@kwR4C^y`Eu9V2;!FV1WJpaj+Uii zRdZt1JM}a>5AsUreML1A@*j2Jmx_nGxjX{!=VE6?!~t6D>PHr?b7m~iCudnXKCAG< z6^NKO_*yg6<$gtXZ6 zYG@|`5l{&~!$^f;m=dFi2gfA0;}9ZeIMsY(LvAxkdmsMo_RBIYCtHaY_Mzh9vef-E z4Ynf{!fr2y2EuE7)r97z=AhpjyN4R}YV;lb1Q@E}IfDsX+^EJm4&Q^JR*tut{b+Hg z@<52Fn-dQo|uWqkH{@gs}kH-Mzer2S`)(-vXrg*cd+C1p=iOhOYGe`a( zbFSQ7roK8oilvec*Wx)&%)FJU@~jiNG|&&!K=!S%tY397Rtz&2a)W(k4tX5*Z00e; zGjVfm0b6#F!+BbvK0)usZ;7`@XOXps=R&?#zC3BUzP@4Sm*kS`q;7gD=BgMghw5ec z6Pp=PAJY#)mhf_s5+E^m$5>mR%4HB+5KS^YSozg7;|%rOKu=g{Niw-lO;fdqjrj~B z9$G3~8UVZD<{(mA1}-w}O7r`UUCcL$68Ge8M)zr@jML> ztG_dqEux6Yz#hcm@0j&t{-lZ783!2hj_}&x{30T3xh`YTq1jpQT85~HW5%;KFzsf| z_6@4gon=}HGx-rZbR_4Uc2O3p`MwjJ$z#(zi)~^y*WW~wMCs!@Z9#P3EX#-yB0s&qEKTSN2wmqit@#I5|r}kwX5eTl>>LNkM$0 zxZ3LoKVwoprs#Is;scO0Ezu7EbzgFtFARUnZHw@6(mn<9(psUP8J$ZVGtZJ^FfW@h zha`^U7P`@Cy&0Aw>u)ee)$`0d#C2==nZ;7=)Uy-JSQ{sJJMQ^_E`gXxT*E4@z z!!_m*#yaJqis66D=YyVzEVP1am}s(Ze++<@b!NKRhyx9WDNP%Mmt4Z47A|qQfuCeE z%8F0;vnt>`-W{BnCy0oH*&-`67@O8>)xI~pXC(YM!#Us5Da*1d;KwzQk4Z%ou;zU2 z4W*TM2I$x?9E8b4oaefsdVzSUP7rz=b5LDGzXRUmUogY* zzYVS0x`asg(XH&8n~${%{UDUKiR!sEzu6^Ij#eY5Q$Nktx#NP%bNyUOpL+iTadsS+ zk#zW0h%GI8nd@Sz6@-h1sO)c||z^C)7^W1jEdwU?qU9TbGmwH4=_aR1S8Kc^(T@VDMk4tV}6m0)GmgeKMA;psBL56W~l zmG+u7r$xHoT5$$BKHb1lb9QJTd9%AA-yxs|YTXn%AE@);gaP_TMi~pM4$kQdjGsuW zn9x8BSX*9KAue%)E@t^&%bHb^BRzBnb^wTn%8Vj9Y*G1x+?bhETI&2wJ$BzXb=Zd* zhmYZ@J>b3CrxPR^B!8^C^JHk(VO-f@JaONOlWFdYf8TXc{>YIMf({A@#mG3m@SdoC zU;R4!x$cy&CRbiT`;dX+QfLSIZu~gQg8taM*!(TUg8ee#Bt^=R0el%+~{>!B7+%zhI`PTYKXy4>JpMl=POyhgr%)jsT1d+6HdU zIRH+dxg%seg-yZmvl^Kg;*Nu$+o(Gt#z*I&o$@f5(|V=%SwHxJ4l({p@09=Gx|bR{ zhvw83>YP=x=x4*%f>RM~%g&;{C?Jc&o5QQvjj);uYF1kD0LvS)=`r3ie9~}p79YDE zreGi@eOguRb=|32r+dl@KJoujN9$^veBuu#CVJ`}Y+s42EkGGO7xKNifVXzqTB)H} zgVX+6ID%wERans4VXCwmVOXveg^|`+sk;$~XH(jNxk-O&6?~SPU zcFdP!Gw5WZs;J+6ICQ%M@GQX3}jN$h4A@a@6U9)-M5>ll8S)=S5?O(O~oerS_xK$*hQL%pZrU{7M7!i5n6fDa=Us~{=JffO-G88wLm9LAj=r#{ z53+x3FdhAh;X~2D-4#7Qo#YfGBakJ;)~Brdz~RsH4;a1SIz`M^L|Ttuy|a_=xo7P) zXI}Ej=Jr3>2dK<)0X(?6Nb?go3U&=7i4xlGu9h_~RrK|4Isg+-6#fT?E7u-RX|bqX zm%VcGA3X+ma`rcNY{~S{xY@t_Lh~IwpHmS0>aPI>yyzzv0gv~2ok$zoZXa+a2Jiv@ zJMqqin2Axgt(85cb>KIDbQvN}k$u0yjP~p_+?@roz-6$+s|^2~3J~;=Q~|sr_0^0A zH~-295I=$e=UN^mq4Dbg?&chRXZlvEs@jyssC2$IaIMpDfgxk(J)~Hl^q&&?~*N`Jrf=M zf3jiSRm$~~P-(f(0o+ge)2q$yopd-UtrS?reRXTSwbwyF0uHyNP9pnEbc~B8gw7(yWAR&k9 zJ|s!-1MfdX8Ulfv&otZvn_mp;e?N(vo4{?~6)9PAcDY~2y|mRMZG)>ho1X6hCcz!v zY<0zL7ZnL*g-j1G3nTni8)GdD?h*XG;zU-?3x`dftn%6%)th@NT5XbSn?#&t3MbYx zHVx_P@l@yvg&RneJ%!4S8l4&}u8_ihD>^yLF~Dt6Yfr`cOVnxEoM@GJFo$*l7w?sw zzq?tR;o{q2f^chuRC{&?mlxj6fEE!Cmm`L*S#}B6Ys?KCiwl`XOxCz!Mb_O*pl5J4 zkCQrP=@8zHtO>Q2*-69JAg4H7XMoa#B?7T_FK5Pw%n%#88EG%^UW-^2&5if1EPK!t zZO~e}C{$nSl&N6ZIFZpa*!2A)sMxGNkhl&?E!O zPYt>aZXFR?HmI~%^)7s854)v@gl;GQ2i_Pmr{3V`HPcVK@_GzcCxg*q0>rkCV1B65yxJgccvKb0oe7`)w?RGucmSI z>1!-lZfh(EdDLZmznVm~^C-*rPgvI7n$+?dGV*`jC#u{nB8P0jFv3eAK7 zujG-Tj2i}!iFbB`tF>;WMAMZpx4!cdSU9aNlt%eDvR(#NoJtT47!3483OWO?0CsQc z%wC^WlbcWM`mD?CHZ^4dU+ifxKLxX?oVOnemLocUJypL^kP(-q@7p%0q2v3^zn(0b z>2y;*y4h*+iHaeVa{}EU8TJY>$K5M(NvMphSl@!ShBv01AimtwbiMjeRI!;(P1Ga7 ze85hWfq>{2EpzVJ&zl_tKUY{^u_SP-w*QJ{gT-8{jfLMVxwFnSY3-4MJjtbnLO&II z&Ti0^cwq37`Ss0a#)txG;o?&jN(!ucCk)yOm2UfY8*mg<40&H^dE%?%d9D7!OLho> zvKCPD2IKejg8AJD#*n8JnL;&hw=yor(1_Zv%rm90pxxUjcaim6BeP1u8pD;#GJ)|5 zirYAMmI04&#X?AvTq#*>s5d&tN~4G%7dLR)ZDO$8hNWdG%>(KXw22;hp^q$~EavhE zg)J>TKzwG*iZ;NOins6$1Z{BxlKRZ@VPyVQ7Z=O1uZ1(uaMU9tkdJtE`NevZOafIw z*qPj4<2~2e%wm#|J1N~Aj_Zr{BBPNIMby7X-MG#Lz&rZCTvm@@S)}x+ah86yEkU$RA-$q-H)xl@Ick!Nqkt-XY#fE~v1U zEX7@awdl?C>ACO&f7S+pv_0n<2u6|8F1QW*`*}5n1Rt*F)?X3`Lqt_<@yF^T70g%j z=K2DXJ8vphHa-=PGlEfG%-ri?$av)Vj-|XquE1I#w=|MLhG|&`+NH^-a950(6Zn4? zzy23MxZfx>C0s+ z2nVgDYs{YD7^E6(I5ZG{@48}AHRfs0MOoX5V$lFnv{mmD-gD`jr_BiOY%bau0xko!S0 zc2(hSl3z+hz4LZpZ{NYrc5m+j4hTb%9jktPEbW#|t6!Vz=1hp#`LQxZuJi*L?X~)S z;J~k%5_#8vmm6IeFS>ab5HA!d{U)G)hJO9r`tq}ifo=9c)+qnm6)(K{w3Jx7G6F1~ zt8eSsFFf|tB)h_jiO$*om>|_kNPR8LJM9l1cIHb03Lw_9VSNfN1~tf(=)@3PdqoFUj1W9mMll?g@^BB z0o+?QVe9-WxuG0soh9Zqc1L9Uh%fR7X%!uNl7OqhpmT&{WF zMb4MB|F}hho|!)g_n*#6wb!$hupFs>^MpOnq4~PpgN+r-l z*Go#-;Vs=VENo|Hu}!+y^piZaU|QbT00mFph+aLJ_X3j~xeEr>=sVy<_g9hRa|AZ7 zXYRElEz(~!1R$t4<`yQLnLq$5Xpp0S$%4?mb+u6Ak8JM^vN_E1qem6a!sDIfk6E8} zzlgIdF|7WOis+AkF@D!@o7mrWLGj}HIzzCbaCoFwMSEc7_Hg*q$@r?&H=SZL;8pD( z{NPn5KOT-d7_4jjnx6n1a@}F{K<(_64*THrxByp>=-Z>c9pBN*??(p|$8jI53yy@m z_R1u}e|U*S>aJ!M@I+Q-d2|Fnma-2{8{XDCXJmYxP+Pi?5PCvmR-fR*v%c4lKQI2o ze9U0#iu73Od%eE4k`_KCRwPzG$$!dck-Ttl*?^r3s9eibxo}*uWGcZ<*TGz{i^*K9 zw#FwdPuRo``0Nn~+K*pf9d2MzsQ?p$0WSn|Oq+2dbMae;XCV&q7z~)4_q`{stjD)* zo8#dcgd0q1Da>1WXC_rWoLCiLpd2lyC-X@&lTdu!vdZ0H4*8f6%#y>@;tC#9g1P5k zgSug6xIa;SG#s<2)`D3}VaSt6Kzz`*mFNQv&LKg0S=+|&RsTET8(SC38vGM(z~qw% zT6r{|V-*dy>m}ua;Sd_iIYA^T?kj|EsC>$jyV!IvG{@F?5|hzn?Z5Bn4Uxh%rD51Y zoaao}U8bEA4BE+K@;sh7wBQDVy*4@sK#G1rpcZLJ@Z0HsWq7&L0W)L0VNk{Q``~{% z-9TSfh-pZC@V}CF);meNh!MfQ$Ga1$rfLrf+AeIi%)iRJ-h1;uk3+g#*hnof-lD^U z{0_NCh8gPH`$yXM^@hrBH)w1oysFPd_ZaWwaU~r9tIoH%;<5PCtVbG;Zf~5cvRjsY z@8u-d{@`-)cpT<^=$7I(xq5Co;pA=}>1ml@t>27@r>hgGjq}r(`EiMul zeQ*EVuQO{(3s2zjUy$GaF+IQcNK1G+*_p&V1O%|5H|s93;g$vm^e%{&ojQ<=X^v4+ z7(Xso)MUPBb&KVheks*Xi#R7@@H71KeiA5^ba8Ds{fj+ZrSFl%14I5F+e%7HB>_PF zENQ8uRobhu+x-q=wK&wfsvRyhYae&y%I7ml+fn}Iwq8?sZ}+UE23a@J&0(!1pAr!P zBL{d2@p){mv+v^I0hfm69bX&93xGev;<;Z{Z9$|Pqoqiii5EOJCN^#`$hx2qa0(i+ zKX7b%bEDLP(q`I->$JnP*93qh`&qW{0a9_yEgl}Q7z*4yb*CDAr@5~Vi^NxVzBXKls`zhD3|h`xwqbz!_>UA7f+@qb>3tdta&tH z8FyjuNTD8L-a6F#jB8%;(p=8*r>=N)T*9Yb*^(y(_njSZJw{KR%O0i z9lT>cnPzJg;2C!;H9S54KIKVhf}Fla}Ny?t-}2cWe>HUl8wfbvj-;fON`*W>7m$E;A?DCOP{g1W0=> zgYuwWj0l(R81oxa;RPPRLEiEG9=BaK-l;2>*Q7{!U&yGEV_MoNTDJ+v1PhNoWQ9zB zvk5GJP{hoj^0VxZQU)4W7^O8|(F1NdljQEQ7h!Cow({C|n#fVOXjl)eo#$J==2d73Uz@yYfr4VPMj-mA-Oz%1lh(IaY=J_*>*D04C?UFqbQ~ z$_)j2SAWykm*_&po^+vp3&0t~IN!h&eA+)TF+qu_p!Y9@XGR)JH@6YVn?B;OwbvRo zA@+&ctC;(=E|_dz>8Vc|2=~xB$7?w_UyL z?DlKTCz3tJ82hs%3S#{t^Ov@`7GzTfghlQvSy7GE5l*c^NbPFE!Z2 z?dNEl_*v^E>ADA2ph;~|Em|yFnuSh6M_Femed5)yH;RO=z<#V!ZC5X=n=tZ;PwGP4 zIlKPEU{ZPVvaDF{tCSB<&(LU))8?2ar1*l+N+`#u-*3@)} zy{4N(*QOl{79r=!afHzaFu8pEg^eN*Z<1$z(g32X9>S;@PHb6WoKxHu>2=xSh+7vt z@lz0hIL*rb?lirbZRS9U8}JE2dq?&AOG}!JE~zYvsRGoErrbEjJ+-4O67X+d2Wk(wDkr8&skl$-BGSV`#@>js_+#W z=J4t%Z6e+Y! zT_6Jcd5D>AGU^oY|M`SKUzEr?v>dWQ|un0oXe}TQLVxo<3L_ z^rci)%-=SZ83C&9Uq-DYj`U?12;xY~PW51immI<~X;~jc)853?U#yER@NZ`%ekaNhsbdDH|XA_hGs%K4uF2E3NE0>i(<>h)Z>g#Q%+?Z?ocFla4& zK|C-Z4)rd%hR@In*1q`pE>8#P5Ko4d`28NkXW`QE2KOo6+f?%l%a_(=NSNlO8Nc=$ zfl!a30VrO9rsz(|r=w;#9UH41COuL|yPrPpV^-uHzL1H? z$)~zT*`y|c22YTHS_;;Ej%M01YZfYM6TAixljCn^Ole=_x%@R!6C~0f&5TCLtsTv3 z@?kUp@kmSc*{-+et+%XMlvpqYPLwYA5`2z%z1hx??5y7VZJ_YmGE2}CX@CD|JIlaq z%A)Fa3uO*}aA>H7KfzT+p*i%XOI%L_-#Sx;e*&zW37<69&$3n8Z1JGa6;T{%FZbT_ z0{ZQisqN$-Z0n&aQ!_e$ztD!|6H>vO$;|>%h4Gr^N8hQcGhCheGF|AA<)*FZ_RxU* z`s5{dzZ-pp=RvbuA1&5}7$P@FxyKM=n6SJX3G!%XzS)%)E#+yCv8c8e=vJXG2Dp4b@m ziDy=!y+i#<-s{FwBmUIHKBD7xp5by_X0MKg%fzEcY^f>eHpOnwz~@R4+VPw``RkVz z-FO0Z{krRoW#(ooECBz9{nh4VzgeI`Qz&Aa_q5Dl9l|_n8f3QFShYDt&I?xJ-O9j$ zSX3L-XXpCvqlmNn`+M--CaRd7Zl`c**=;&deS`1ztlD0^i_F$_?c2~^l&>k5%u`txB6rgyUlV7W{`SaS*1%}A$C>7V|(b}lhk@0AO z%t!k`ha?q(xHup#oAJjS_jkHk*8x6aC2B=m}wcXjI+0+K;~y(O{`ni z#!%=L+}-Wr#jNt2iX%ycJKqIS0eC`tA+CNi$ftfuu^G-DVp54;N|4K`j{a0|2iw}N zH$qsulNr5=lFM4@2Mzx~haOSiAA`AieLH0eWSA5lb|qw8U8#0-vz=``Hq{R9q~F(m zKBHc2W%x*AzO^VbbZ47||K&k<2J_beXI_yds{I;p-rKh3It z#C~cqYh$EZpf`rKpNtoA?UUa8_!R!E@wLf=HY!1K+C1xCs?OdO(huFhE3Q`GDCTDl zM%Q-EQ?7|f-p0U#UcZi6yUPib4sv+FzmP(=>Ow1)rxaZ_$MwZ~Oh2Aku+vl^Dcoe; zaRenxX}YAx+xRad8~rQrsYOsk!;LOOSna^B0bruQt|>NdOnReR*G4CEZ9!cXyYFv~+jp z5Yh~D-%)@6?|$F<)?Mqa#bPnT%)IA4d!N0Z{XF}exqMJyeScSRYG_O* zmoEpT-OAiuM&in$;X*_}G2wb2o6^-{ep2i@KvJkF&l{UF%#eZ@SPsmsdKb^cEq~@2e)GR{Cs9BF}gA zMcf>)dCls_+a~+I>YtM0e9!L8;G=_C@0duJ;fJWyCXP3?y|5sVA4c_AX{p zM?_d~m*Ex9h_u{=3JfQA?_&oy0oD-(-A<82PF zvz zdNJRPMilL(zOu+r`fXc%My-7rpyxUF#xPSa$L0&~>~33D9SKEI1tOQ{&@?Gh2DXo* z%l1^iu)x8M_}`L_OmPh1_fzQmYPIx(^t6^vI?MMeDNI$7B6aEwwivM$_t~YuzS@(a zk|9awXOJED!4`LCcQn{`E`k`rNc0k4A4oW)=PUI3+>c<2OZ!@ic)OgxMMyb&9GW9Z zltGi$$nA2mXA4jV!6Xo8s8N}=UhAn&h`NNXIlYP#sVa`@@f)qe8du29UhQSU<*E{V(hV)A_f8?oTKW+d>a~T{Mz)k32}t6>_)J53kiSuEv?hnHi_~HyG5|veil!UAP&XE+$8s z(Li-}<@l=M^N+IVxQ<%jGKEJHU_)q4MNpZ@ZNoQ}bi@;t>>+<6zlzuVL z{U7Z7(|r9a6tUr^yCYFkXX9GVJViAKDMK+rf#acQXPN(Z87pIR!8Euj3(LL)`O>^S z*2l>7>+q*+()!HjXF1VvxxY?x4+P39g2IjOQP7p!_KJ512pS??XJJLB;qmuaZ~jX> z#=dBe6U%?JVD^;jRmTz<#y)SAJD1EggQB5xYGaxCjT*4++*1DkMMg}%yqRHAq0ruV zbN4Ws)%W|Fc&ysmJ1|qmOLD>zvfdFUl70dfNk5oZAxKhvgKVBaj3IFMxZ;a;kcc6` z+uORDzaZfpETy}D%@66%GPHMyZttxwxKZ3EPj6*CX``UzpGhWFl6t*8v92;Jy+BqUl691nX;>{(dlvIN6ISo5lH zaWU)(Fa%0wn1CzKg^;t*GBxbt`4|BDp!%G8iMLt4SzwlNZ=OZQcf4ZHj{zUdIw%0_ zGWJ8!Omdc_nYd?993T()`11}aeSaBN2vB}_Lt1|k>&=l@s#TIhuG{P5+r`m*3Iax z!G!Vh0NyeLtKj$nA&A?L5(alrYty7JDB9(fx~Ftoe>aJ*vZ9OF?nz6&_kC%U~qRrHJ; zy!Rzt&9sQG;_C(Hk<1iSCMG5?N|c)ZXe{1;+<1SJ^s@b7oG!z0VXp0AyP@jzEAq3$ zm3_Qa_jTURZSs!G9cO!H?HUD;UV(2!g<;*ct@qm_pdh0VL|1)zo6{@{qk8-b-muO| zES1xLD%01P-ne0_46zbBs-`87ENK}p)kMBG$P!qbYqy;K>${JpCwcE3XWHrqmlHs{(}E&Y*=qNzcvELYz~d*emti+76(HLsT) z7u8#e3hqmtOgU5LL6zqhCEXQ&wqt|>Drp~G%HMXFZ}zBVEOb?a;f2gA$H(1<_<<4a zi=vD187tW{;o?fm*nS`c6N(5-@22mdSel;6zHcwH}#O`02%+rNPT8b(HUvln_*+0tswNWm}_jAFLnk)a3_yu<4^uTeZwm&t~r=?4HI8Gd@{Y; z4jAt3rk~xn3yjq^wQ=y`mX0>7%rbRMqP=9}Ywp);P`D>=sNh)rQJ!M6*mzVwpvA=I zaGVaXDZRW{jX+Vhkd85A<(~zHI7%!Y$_OkP>++NRQh{yTIN%y{{?i)6q3K5zRN9Vx zfEON|{<};Ltt7q`Y>n)^Fc3Z@{lF7v(x85S+*3;-!E(>%w$ESWdfl=TkqT$uN#e5_ znK^!QQZt}uMogTQm6U{cmH*mO`dmav)!vtW^at2G*LwBfE9ur(lbsZ;ctDfQg{%b- z9?t^@$#|cv+M6}aO6?}U%Jo`%wr%F?vXvmMHG#R;6adM)7CMu2ijGmThx{(wykI$} zc>9)q(bi=57kzE&{uwjr2?U>Ts>ag`fBC}UC}de;e$@JI?kabz5p%x$2!_{ZvCHeS z^d~#?mUNH%jO_Qh5LHVY=U+7LX@r3#oL?JafgQ5<-z(J(57rvBM9S(=$(H_VuY$&& z-L~+<3I`k&dtBbJD_gMpGWG0rAq&)qh57O4$t7N4DRLGO z8Z{`uUa0$r5P|$&hp7g%S&Vc+$+o-rmB8XojN9AGt%vKQceaW2*U%}Y-&+sW?-sQ` zV(#+|!@$R!Q>Uvh=?cSQGTuWD_B-DaoUSwJYjcplocF-}pl82o)& zCY%v!^;y?E9I{Z)6YZ-~mXnK|!-(gg0 zy&>k;a-)hD;`*B8lY&0isyrYIwYPo@Z*Tlq0s+Vx21b^K#w3NBVoRJzViD7jMwHltj`*@xsEiD6D#HuDgm5*MSE=8kpCw-a|#5eOyb}z}zu0OK;6Sy^K zXFsLU=hA=V`Z*#l{flX~qEmsPY;2ufUAEP$oYP2+Lw$``o>I=toc0k{0!1cVmhsbk zUTvolp1rO`7wwye(D^O2)yeRUdP7i#Z{v~+pbz{1nrJEm4!|2QL$9t!a5CcdL9j)1inLr8$0c=2$1+ z=M7#9a>Ox8k_)G1@b(3uHqM(xj2eZj*7=p?3y(>VIlzT`y%7`wPBl^flU`Qa1#Ja_ zlo`^0fa$$LF#qUD&SZtxh0NYqBvqcl{%_tgtl~Trx%`9LXY893na(L zi>0|0bqoM_oc_cp@=Xf1YqYrXYlIl!%>;p6wr#5P5BFPO!o@@NuEv;Zb=%@9G8K{d{e1rg=U7lC zRVMG~)6C_ZOE2D$3)@WImE%lL5B`JO)Lpl+J-&_3jca#P>fuh7h1nT5U&C<(ZJjE5 zq5~F@QC8>53&*pQ&$g7Hwv*!zM{Bu@)8eAntQf_tElV*;CFNY=b@IQP`8&o&SNC!# zoC_O$>NOu{BWQ!PkfLwbqG#@>YmWi zPw(GjK?N?iD?Ltj=f{;t5T5e+9=?tY@eWiV#ToLwyFbeW@m<=k8H^!=z_-w=m8TsQ z=RfaBFIQTrnz?kkUa`JIu;LATf(i2To)40%nXjrczYlIRR8Fo69HHLo95{IaPw5vJ zxZ;UCS#94fW>aH)xpMF8^9D34p{_n1S9VV5I|>@(*)3j0Z*e^tX3s_L7^nVCG`oKr z;*qk)J!`R!3mTnzqa2M5VjYE!8}-f#(&}V_e)qKeOg~(BoILL`R6-_i5Ub zuC-dXykxAmBcFpqAfF{)?>59MAsSm|_gr%qLb3VD(~^A9_B&BcUIo92lo{z=tVbkf z6G(82-;;Ydd55HQfj&|()GP=E>8(~x@uw{3OJ9fCf&F5))>g#qsc5+rBYgBJT?fPA zXUd}AGz_yeB*%!V1kAbFUf9?~&(qZ34+{sM*=T!2Qik*`{IXO|(z1Kbh4tX-kA3bY z5F_%;Puk!(FmK<7)3n^_(w*9GUwSRZ+oR>hT8q?Y1j)|`)D(W;k~pQJm)f)J&3GV* z-wDTgW3l;{g_)j}md#Sp?7zEq7df?dwLPxzy#gvHHW9|2iZa}2L_Y(4I)rOhTr`rk zvb#+s`GroV=n;PT^GA?$4hb~7-$Um{DrNVMn90Z{2K{%F=6!$T-U;pVCI$!FYjY>P z&KSp%wbSIRQj@K(+TiL%6#g?7bbfH@ggz^pI$ZaQ$9LCGLS`4fx?VxVcF+hE)Og>! zEqQdSC;88k@M+P(mF>C<@855wPDF1B*W29;l@mChwrHAa{cbH(^Hp%iwn3zLt@|e7fxX+$v>0jA7jbP zkgw!MB1h{$%7vZIwK~P_Ssi6O83c>k#;!)y#-0g9jhrcccE;RG4KpM$FF8Y|qB%=8 z-3k28wzzC+XhT*t-NJ&tvhZKqprW7LC$duU$-hg#1HUVO_`wz_I%gG&X8$x6za0(~ z%UN(Ak zeXQ5VLct-^Xl*;MLPF5^#w9BCwe1Grdru5fymMB9uLW?P%~3c0t_unGkQOZnE_ zEb9d{+wGcwo*x)!@@$WQwVLd71Ez!6>Kn5~&pqR2bD*R)zFqk1n1<7(oUfjK@9f-2 zve3NV8L5%${C#+5QbGMah%E@kkIUDiQ_#sidvGCd6-AQLu$VrtbJf$E!C9597 zjKDz|*(T@4b7G0knBK}m1yKBrKFD@@GZ{2{f?zqp25RZtFP_NPZ>z08p1sr~6C0}U zz2yLXt6K_0PYkImZ(cONm-E2r!#H>KfReOxNep=&$zP-66qjB$Nl?-NqJLdE}vw%%yc5WX!VN?hwJC;@6XN$1Uf|zr85wFSNoV*)N{?qH6%yp zRn;(hF)9#Rvg^)GG!G4%*y;AFfSZ3~CPVMXr;Sa64IZi-Xr71#cFy9P&+y-AjL~}t z`$vmst?*+TP>^%{NZ>>${M?$Z{%xvEk*iA>GeUyCc{qUxR$Hi%GVVs5`Eh# zJ?c~b(CIt0mHxhJ9t)l?@z>L0lg&<7%sC0m^z%OF;7rqy1tV=$wwPh zC@|%P7H?~f)iVUQ_B`3Gfy>0Wj8)!J>_i<@QRo%##9SlcPFc#wO&4~~PBLuv|E8d^ zN1ZrTiatj}&{rYQor75uh<826 zWph+jOPdaNEOoh>%*4!=;tEB1m6?gg1&nAo>yVb1D;{(0C;JVBM^ zf-lkN+Qte|Pzl?|6xnGt3W~nO4S$A{$qgcz-qZxGH3qgTU%=8&Zz5LxQ-mBl&kViU z+oNBH${=FfgAYi^b!p}q9@h7t8(K#v@%lU;D%_?1I;IqgVs;v(El%Oz$G^UQrl)CD z;knINf!t@(WR0_9RtCDWh%3$5Umb9F&NM)$CP_T=?cBB(S0aQ4JEwQ`f=cu%NeS{W zNaOzwRuNvMhQwTu5 zT&dD|xt|G+PMd`-FS{)iGCLWTW}`Q`50~&g=&)&gB>~S>mZJCJQ5?OTo>tLeZ6oAM zjlIWKX`E8U?uW!odpwK6n}#<$}0Luy}3G{oh9}tmS-LU)9@>5Vrb2kK4ty%pmes&>?Hlk z0O5aAj0#L~o-I+K+~3FhC}p#+v$j(?b>KU5q!+3fbuzDBmbjgi*-B|m>CEe0hPUaT z&!Td2$p^!t_>Z_JxFywjLmhvwF1dycr_oSV$)FvL;jvUch{LFo%UrnYC6`o?PIsJ9 z?ywp~nBP$EdOo)~!4ex^Q;}qy$TB2@?88aF*&mcI{ZTYYG>Gzxv~PTMJQ)TzYJQCj zG?CNrD^U=TFL<#}cV<#B54Q>ayI3f;;`Tm2NbMjNNW&l!!qPBGi5-pE?C$j%=KCS< zV5z7*K;MD0CBpM-I#p@@xIVU3b1MKU^O;KlKF{I#H(}1^6_(MYKl$i0La>;D+Cy~> z+1Zw1z2SE3^H5Zo*P0>?6mTz6rht>-xQbW#0z?_OCS* z&5Sd|fynpbFQ%L;^K11H zn4y^0zt4WVcVy9z&BkIF$tc64jX7f*-_qc)iT#>@fs={q#mgisXa4}3C9iffqC{$=7Sou*>&;{B`9Ss zBOV#i()=Q$zaTml%p?WkBT17Eo%9)Zw%Xef?FX$9-3!OcRHnLD>Xd98qcc~#8LJ6- zp|2gzzjP*I>kbvRaLGE6D$5@^bU%FhQEsQZ$isDF*37X}c%G~arPv<1KU&H8Uhgn7 zOz1hn$z&0A5|#$^0yFuJ+(*qE#@(E99FBF4ec3~t!P2YJyKbw`9l$B+o zZkd`Hj$Y;Eb^H1-@BsF+R)x~#pggNaEm7#BmQCR(3J);ynIzA&ON`oD6aaqG6bGjsa%q4OR>qNHqC)}Fx&WZFa<1@&529dmU7Z#=3 zOI0FF!oCSJqvAYFyQBz%$YoM~I3?K)0S<1XWwvu|>Lxli;iL)03o}ZpM81b#kll;;eS83Tx@zW2|+?l3`^3h)R)mleo&*M-HxBC_C$@1YV zf^>W!wZ!iRLhw!e50#2QcR=jZAYr2f>F?Trp{fv#!ncKzMvRbg^ zN^p+A&(sn@Dp6xIgwEFmieiCIg}*#D*T8v2>&m6~Qhk#(wEHRpUo^K42~M2H4Z~a@ z@@HAz%$C{=daOZcXxe12E#A|zIlh#ygBa2n>wMC6c6J^_zwJEQTxe>3(41GFC04XA zZ6O#9<&nmtsZ>txqncq>EmvH7>YjV*+R@yhbh=vdnYjFLEJ4$r!IMr!G2yXk)5E^v zvl$`&N_$92Zmrz?T(~y1=6FO%ABEy-1xqI2+|(p6tAj!7U;bI$U<##+9)SvVCjIxG zyG0~#rNS!e`tqQhp*Pr@7ctY4R&XwQE3fJ?rf2QMeM~QC-_fxnH(a6+go%l^&uEMkYiW13wePMpIQW^VclIK3SF$f_ze+a!kHN4jO#VqVkzy zTeW~M@(!onI;7_#xA*nyFI>Q2eq;bfu$LHx`?mxQyimK+0ziE1&H_^h!=)TQMP0Fx zxzL+Bg?L+IEN^1maD!vMu{!EHD!ljb=V-EovM+(tRqBbH#8#V&+ZWWY@Pa2RWUdW` z_U+lG+Ql>ljSfu{AIt-i7Gv;&z#))3i8SFu9v6t`-R+$IzycUD zcuV=ja#S_K$6Sa2JE5DQzMP8SGsS#k^dLwkDt$Y=g{xRJ-5Hf@lGD%n!=}rsBUISh zG8H`Y($nXoXPg%o6793XWv!9wZPgrXh^_jic1Mv11S6h+r=O&|zM{RhZ)WEJhzbY! zcGMC(3vZ6f35uVY%Do{DI0j}Tipa0)>go*_X_V|AkAyiT5`qN>!VPjh7UEHJ-P^H~ zv8i^IIR*q&tSB|hnM5`5ycT+lz0aX;bA<>(*dd`YHtMaf-^y?b>jp2ovLue&@<-tN z3zE$R#^0REhG8DB)NY+LUnnk)C~yy4S!XXF2DwU^07VtN5X;)&ZXypV%^ped2}JJo zIQq1fYYRxc>Y1ebg->?}%})Z1JU{GnY+5tTw-Mz>uja)BSdMjy^IP?sC$7_u7-G}V6 zjv{Z;ME)EHTAy06Il*j6;4tQjew0&p;kt8?- zkGehFTwN*oW|4NY>pWec$2H8m3^Qel7edzbz7u8A$)lZOiN$W{9cRBgw7r){$Cp%U zqgy5&EO{dEaC)yf`tkCL+r{tQq}2*4XU+U1hU#TbCR#8`C=0InD(m+`T;6sK`L)Ou zi1x&}_Vp~5x9MN_f||ie&#PY<(DK8wsUUEcTAH9OQsG|^0)QB)C!RTaOgH+g*dqt$ zNaj-zSuAkJd>P-*>_D<-iXH~_LK`}jCYB;+-sfS|JJvRp*L2F$EfOUq&A;v}4vMPT z^{}5A8O^^e&>-VA@YkyTW$P>x%Od=(vZjz#qjj4=<7xQIook0~U(KP7AH)SX>mM`4 zp%>Hy!9f_7u7fH@+VySIgfFmj!6ue{rc7$|iE2JP#CjKh0|p%ZmPW@$bCQ^Jw%%Q&%v!##_79o32`=xd{ox_0hm zGnXRsL}6rfY&ea2aIAH?y}FZEl=>px%GC=-=P+8`H`VcBh+Wy%ucVMi%BXrH64u~r){|u)iB;#@sMw_$vJ7i z!8*E|QT$p>0=v4bJ5WdzJZKLi#{DfUxZq8Fy#d{(+u zw8fs6JoodqpHPFe+~%RgFWAsDLE~oMvGPScuyG)1sFW4iL&gA z^TbD$kj7iCgy+@ov%M70zl}DC>`;{@^+^?KF1yM+mQ}=fmVW^m)ow(`Q|o%FNVY96 zs@>)sm3yxax=EpoC5#QHGo&AXW&h%Jc#AsQ*nJta2#dgY%2nF1^Fh z_B-!z;hQMvJn~ZBW*4%#P z)QoYfNoT(xY`^k05oN(9YOa1OC%bonEPNZb@M%ns7Y#q^u z|7d!(${d8Djp=!|XQ@0NUz2<1yc~^7UpU$%&t`--2;k&%!~Hi(rAbBcwH0qoO7h++ ztS~*s*Ew0mfNn zxj*D*Q|~Fq9a{u7kzuML5iz)!SK6#F-?j6#gI7l`u`GiQ^{q5&rrjZHx^eo~)h*aN zLqo`qLptzhPnf-9h*c|#7dPIk@xQ&09thX8vJ?*d4#0N5QhjyxLON4)fI{60)sYHI zH@9v$a72R*nTi!2UDeeFouy`dtNOITDD_{Kmozv+HGob9wL~ApE_2Cfn_d)QYAiea zDq~m7SqtAihPG+0zGHZa6iAqz;k=5s1*C#_#bxbn+&~9X+WthS#!3Sdapa1Olu9Fr z2Kj*BUTo1*RijgEV_G`#l~2*=5VB7$UeWf>UC5v|gMN%Zuwx$+j_;~e_?QiKeufMx%#A_#s-=(513K9r=e!i}6tgJ(S6Ud6sXs?{ zvww`55csX@P-UpSCf)Ye&jjIn$*S7VRqLxb2F8nbfpa`>fm-$J)>*p%$>rESv-8tH zgna>oP&@xM?8gnA&C}-H1V;6KO|K>AZ?&#vf@8}dgj&0a_2i{F-8To>FDV6sBeLU9 z*UZ%G*cq)9i@M$l;l4c@^Cz24=6V&fyan@wIto^+puw+;@XQD|0YMlgsc$2WQnK9Q z_!{m*CVuJhlnauaeB9*F+~~XT{rEN5xBd3K_c-eKA9U{W$?JV2L(tL4OTs-W7FKC9 zy@HfQzrZFT;-vT(O902x(%*-LmY@!7K*Z|6asqRmgCACop$2Fv*Ze*zM3N8v1Vzj_ zSiC}kopA-aClk9RyBUWq=`5C~QEvJfK~h<8ePVA%b{Mugx%BC<%tVO-$%58q^Eoxu6>Ll1Xn21S$IAJaF}wC& z?#1C>fKR>U-^kwVH$%;O4fL^dphBPeDyP)vQv8`7nwFoP!f#vo2sb)YYY1}?tkm<% zyzHq^Kj5b_-PbIYMx)r|37ciz9M2AO34?s7Qgg?GR&Bl-Li9o5NIK;D)vO~@(OSRm z8Rp0mXoBjQN0v{(@f1cJ(5G9LKX|O`?l=cTOgcPvQ&8qSW0-0fOjew_qgi-e5x`mA z_iuGlv09-g3eX>A(OVD3(_B4@GN(J%LWIPBXIyhiAUysgljsF1QRz>=DehH~eU?Jg z0`>$$Uj&Y1$|DVFuAeKBNgz-lbrU2JrCPdkUYTJ&+xo`+&bnP}y}LkttMaDq+~gv_ z#i$F{Q1!<)UN^FH+WUjN9P`e$(p&aHzHDP%y@*H?g}F)(0FXN~y>6H}ZgHQ6Pz2Em z|4e+#wT_^>`B5f8W1>nq7pc9Z!c*H?0E;hf;(^CX*Z)>fqxw>pM1 zAQkcNlugEhtUmx`8*pWtc>5o8gA9@YnrOwbmJUj3a4e-DmwK(O>b6XaD&;F?4ZUI(cB6yyOIB4m2KTp7hi+shCJ*G;4vDfr_Y%^9$ z`loE|1gGoNS7AiN{d2^|+a+|xfyh)6P6e)2pGDznm&PBvVlgaWB%k%632#-P$$8=I zze4U2Ax+iXZX#RYGd}>)huewPyR*%JbUucI^1!|C&)s#2)tr3#=97kGo+Yzf$!DRp zt6+zcolO6=S_{_^B)PnMeV52&F02*n0h?%fNEw}J_d5BEy0gr9RW1evTh^jBt{LNl zWZ0Oh?;+k!b@pC#gT7V1kNjqWzirlAdwH-iK4ItBPDDQiQC<2^cb!DSx3jPf@|895yb$Ol~W-d-t9SpKfzCtUhgRu;~Wv!S%VQ|?lB ze^mU!YK$nus34EDo-TRf0;QkPhpNT0{KJcD0YzJd1po%~_$u*vTF* z+=R0cbZ_mVaJh>O3ia!G@`SoTN>oUtG5dzU8>>SqmgkB% zuO+`qeUx@DC5F}Fl<9g8-B;6W*{>Bm=#k(v0vZ*?BWyc^L}=Tl$$w(T^}nO6k6DXz3B z$a64gw2bK!hJOJm;|o|#1PP8WDiWD$PMjSQJ)Wx9=K5I=fS7GH)5@Sh|@zavs z1Tl8n#&<0}8DpqD>B2gCsIIGDv*4u@)w3O(mzwoz z%S5sr{Ea``ef@lSP}1jG1ii$Ar#V7Y(cU7`#Kz*kF zX*hr$mHFiA-FgbGzhn^i+F$ExFF&K%kBuF6i3Mz>lRkpZ2viW(EGAdP6#c3zg>ES z#&}$Yh% zXLGw;%4%4ux`yi7b4_~+~*(2QuP!St5~dxEf)b$Wx>OsljS!W`nwSjDi%APy3@hM zmqp)&^MgY~wJ)QkNyjBcNBq)|+K^3NkdKr9toCb=dOq)h(TDaSj-S!}X969qx*~6B z8an5!N>$JoOMd!v z;HGV(0urE1W}dB%owu>R%%zRwwB;$x`ixdNv@8UqK$^h6RT|ZXhYjWTHgcXy>8b0y zdLtL5VT+2sE{!5HNrJI>l7rHtbUl{|6aF7rKUry%G+5WKy|N)nU!C0QvB^?RUTCwk zt$G}%0i>=!0z(@@9H;1wD4rLRa7znERr6}cP8grH(7C=H1)*gr}C6 z!cjAgiP~}PdI28H!u~y&45mSarEn2%vj=$PljxZ)4|deK*V2)Wigpc^M5DA?H#k~7 zGJ{MprhWwJ25n;sy|=@ptTv=e3P8JMPk)y0tDX!C9|JOL!MM>^x2=5c>bZ=JmQBIq*A#>2mT*`|~^cmMM1PFo;n4db@e z&|>J=P*7ObJ}Sku$s+Pv-^TJTUxGc7wg8NpiRm)Ke#I4J!9hL5|JN?SZ}E_>e_E2W z?FD(Rnbs5$#utwMbMZ$`@OxgxNV3B#7TRE-0U9N^y=ux1SdiA*}VJ^CC%J% zn+!61W3TgUuNZ(XiM3AbOB?2&hga&_UXk*0OIt?ADS{7I3vAgFC>{4F7a{Jy9AW=6 zw^RV-VFK9WvZ5`6aYv2xh*soEP_7D@3=%3CK@AH6tSbNsu6 zVwig8qS|R*achRPJ%oA%B2D(G)>Y%!wajvrl#vK1kk+(>qs4YIr}g(%1$d3*k?paC z#}Z{z9R~J~$v=;7UUJwe7is;Z5I0HB9u9JbO@sk0f;bgzpCZyn;{Sr2UziY?DlR!? zZb;jQoA(j#w3i(eFQ^_HkI(wNll2g6{IHu&$baGZGZ7c9<~>KyZ@539VzQ_Z8}GZc zM0AxlpR`#d4f-t88}=>Yi4wr1D1{Tcn#m6>*OZrd645HzaS@fOljtpFc+of>fy3@nOYRF2!j>kmWDQ z9=+G4_H9O0e=ue*IY1wB*J&jGTX+Re;6$gKH%J?Z_GQS(5A=}t_nO6d*kz{Smo#b?W!^7JMAu` zQMx77cX!Z*C&@xIp&MLkYV46uR zX^LMot8$=CD|5*;f~r&>Ad9vug#(mEN>S)+=EyHzsA<=A)|&e0HmJ9MxRb zNEpZfr}yFdgP7&7P#F$Y=>Y1E%GxzN6pgo9uuIQ)&11nXO#|HiL1(`X`Jbum;-IP$ zbmUn-#Si3JRe4M(lhwE7$*us(4Y4he6i0vxFZa^9YD(lv5}Pyu(ql}0uA>-iI16q?|U1mONZv@5SsCR>M zRF;)!QMCDSn$1qG<+=we7xSd2ueOTU@^zc}~8FRJ2QE%&AR>j5WqQy-ynIaMv&tmcam84aUBoCTa2+cVCQ zNL_NC>LJD$v36kFn^97l2|8|7R!N(CR^`b$&JWA<-qbgX0JAGg3ge>3JVz4$a?vqe zRj8C=#+ET*5lU4RJ&dJ$%;43otwVJ;^l)r6ulQYUyHVMXr zd=mgZ=k87K{r?dAO1aPBvR0w!5s%5ZjtQDY7FrRAsD1*B?vfWO^|!R`>gV_on4uo# z9~?Oj^y5_;a8f2zr%sD2SJv@h!^@yqgpu1=u;KOJ53Bw+yik-n*ZRSzgW023Wls@G zyWY;g-0_lkP5?GnWWRiaJBq9MEByaC$-fl=NSq&nC ztt}?k{*)S@%t9}iA+A-1Un^If7``Bfq*NKBVudN?(_6HxZ+l1?48Hs}w3^@>(Jc7q zGyV3(*J^8_VtCXU8_ES~i-#CODrRk(Wkk`iMi#e61!Kq(X_NNkxh&@7x%F<26rf83 zx}gQ_{PTYSk;on14*d0XV-L0eR_hoTs$gzb$u=Y@y(MdYQgk85M$Oo#o;ix>kTMG9 zpOuFXQTU8Dz0Pio^`ACih(am0b;GFaX}Q8>f);OiXcY%2XYUl6ng9?j4A8{$&UT7L z=>qrE47R0SAC}=)8y(bse}v_3pcy6q#9~}&T8Z}FLLdQ4nj}Gfzlzs!Q+?pWfT`q% z-azt+t!E(Hf z2T1{s$~A|$#rTpgM{G>4u%(iiHk0%D(k&iHdLLf`5v+QZbTsOpa|VljD>IL-bK#ix z$;ee6Q>Q8vy_)KnEyX%2)k<`41_OXOhMutWsHL{F7pDXD8vQX_GdjDv(EJI?n}C>xn`!aQ%FG!>sFiDb!TDs+oExj=}1E{JRt6 z4b}us!BqdlyswU~A+O&x<^&VN;g%$tA8v2Gp4FHJsIQ44HBlH{y#;f0hYs8HzkQES zP!TA9jZc62u$7dbUOp%voG!3SU2L{cIg^rXV%Zllu`o|d48&{z=9YY{6ILtGH-@Yc zOw6ezp3Y_Q!PT=q0o%;Y8ejIrI4U1KQzKEnQUn-S)DTT$1V6C zgcB@fY?iK-er0(tUB5!aQ20rohP>O*B2|-uGf`||7m?q@B1G%UJ9R#q=OxDF19yZ{ zstgG)hxfP2EM-&a&4=S%BcOR`9|Foo9^>ek`^^L(bSnKtA5rHuFN4MA1GJ69wU#lb zd?{`(Nw0_CtXF8;Jb!V1u2(L&nrdUHk`~(NnKS{|BL+|XC@F{ziwWA%BJbCBRSf`q zq=*9PUM`0#LYeAsap#wf?UujBr8HBgjvLeYRvpyT?@fIGo*Ds5y8|sQ2sYlg&V+~+ zE-*2v)y3OXoF#6KBx3v!8O(P5p3n2P%U3F@rKqnohn3;6Ne}HA1$JU6wDr3vYZ@(;L+I zD$%CZr_1evOBZ&Z^)Ya8>wM%yk!TX15AY9p%7%^1M>Fr+-1nD^7l@hRV%Ys&)BX9@9W zo|)-HMfcxvMs?%CzebVE(Eeq8F+99UbVnSbSNR31D%r99oE#?1|~L@|JMxi^o5{kr`)!J z#joH(rl#))!z>z*TU1M9quZB|1`JfR3s8XPH}xgXr7NTtTRkmKk4&F%h1)ACn3YQ& z7P%1-E|Fh=FBWDd_*DrPOYfH)xmM^~X0K?8OYf5mwuQ+;BX(Kh0Xi-DS_XPha>;|` zj8WwywD2BFbN9|^$Mvao%pQKXFf9;T1wee>mVpucqP_Vaooygv0bJI+l-aEFXmwB@k3XcgtJP~XGNQ^KlL-? zBDmV2C3&8VuAGs~f+SE71&D5&j_l_(uJRDSYh*YlmT#uiU8rVzRISP>+Msa# zm@1lwTy2viygO+C>1$ljFeEEW0uNd2rx_#QR{ode$l$R2n$Kt~ z+|Ke}6t54F|E#T}KD5w}q<7{DsIz>6j#4IP{^6qRS$=`eHNK%fF2b?!bR4|URwpBd zH74D37xq&r(LM6n4u~^pstg&t(2WFyVa8h&8zG$Ab4OsPtSQmoZlk|Yf1>nW8YBN? z>0xHaOSAlaY{%}|da8eszaIkm`twxmafIwL@(ps~P7zjojqtlo)+x>e3u7^qt7LK_ z&=LZ9wPA4q<$~DQ5Z>~|$I~mp{fHRDo$>&4n%l zx_BSP=+ICE;UdNafrZha^}WMP71n_Z=>7Pel3bN^Z3h_l(g68>tovC z5)BgY(|Su@=w#S1d(l{gx)3Q!W*2p+*%f*zojFxX`RS%0^$UWIid)Q9uD8dRS9g6% z^b*{J;NwGp#*Fyg_6^y8xXC~fUhx%Uwyk!fOuBli@aHgz-w~bw*?1WMQUfRQ85oY* z=gL6IDM*Y(#z|XW-ju{41|c$A{G3#oX_6orz0VBNmuN4z;!Xd(v|OmWhfZum*3d?o;bponLa!93udfpk78 z%Klmfb`>^sHQ#$G6u__1UM7eRKOMv`6RwgxE_PSYV`!T!x#~A8vJ{lO4LR>9Rcl>t zP=A&ooLXW|S54W|^y5`b!4<*#fL3K`_FVis94^nF_<)V2#K?a7Hn>{ptZw^8|7pV( zgx?hTkIvwKn z*Cby({|Ua-bDo18e43v|L0-Ckl-MEbWpEXtp*kq?^6qFHm|&ofPL>!r5b`T8m`eRW zJ*gc<(9gVxFzrQvaho4PxI{Bj)T`nyc-4uf($yVBHEhOQAtsA$xqFrMF!kgP&H~x& z=fdgt=sR2IlD7hcdo3mTf=s4Qr+;~Az;QooK(dXl!j3YwS>gYaxpZKetKvGM_P@+U zC-&q%6#!7&YiVl~H}>;Ja9L;6Fa#-!1E6;5!S~(ne`!LXS)THV`uE*yXipCEr#>PR zyppt;kBbVIh65symK`|}6&<$!)!li%HMMPBTp+X{5K3rbCIqyzg`WgqtTH@+~`i@440- zWBx`qXc!deXn5ahMxBE|q0+#-c45f#FKY}FnMi~89pMSyr95`Br)|Q9=RP-T} zgzVF#VaWWI#+vr;_gtc-#mem02xqLQwvj&zL>C4uVWl@gI@ z85#4kB~C5uv%&tkGA|ZI@h32#L*~%w#UECYJJajb4F$_&@2qnFNh=?BK`&vcC_p`PA_Tvz7E68^?qudq z9NhrErRBmHVYfh)$ljjprh6e8iE+vq;6F_?_z{3SB@MVMPpjH)Yvf-itXJHF z?e1H0cT$XnRrooTwZYwVT;xx|Lw>$Jsu6XjFh00K=;AeJ(*_+!_JQQCJSxJ0)OFIo zbH0vSY3Ugl#9iNuF(m9B`~1k(W%j|IN_!BL5 z;zJMCYK|i^_X2su?_q2h$b@md1~Py-uZTM5j@!nWRq=eLjIqy7#4^4s>qwUWKfK-4 zzs`I42lwNnPvWcC{KyW+18t{<9#v2k@G-{KSOC`jhlQZC1@PIVcOMcXRRHI{{SwBwA}%R!-i~R&u|<^GQ8} zdU*cJw@xMlR!PVGU)P8yC@epZZC4Ad`ejslb}@>k#v>=dcCJ_}223FBQ<=Z>bHW8Y z7g5=hQm-Ua2wfYS1k}w%K#_5~)q%El zCXgTsO3e%4JpydfLx-h&QPo}*^QFfVx+Sc_428xf-IiP`rQ+@)(fx1qUz%pajx>Kwg8S#AkMvpuOCSNW zx*VnEA*F9E31*Qdeeb!VAD=k6<+9^O^xyPLY|YaSqgbaE%Ea-9G}-2SO|mN=4<}uF zS6FdL?k%t7IOuupNR(Y&dI?Vsk^c21%0cli*yPb}rG@L|mlL;Vd?raN$^Je@R;zWc z0eoD^QoKDiqueO0%1OVPbKk?hx(gQ?XJ5TxT^MN=>gGBJINMM8+wtBFD^K%WQD*Tn z7BVRzQRtg2K_o{pb6~nL$H|5~HaGY|?P!v+UhVz(xxPYfZ$K1*x{aXLaG!F?zpK+( zTCvL?rM7AF1*!e4kph$6ANTD!LDXW^G>dpPplD{EcSmLI&z8TEv&P~`G*1$B5|_HL%VuvnICGmvvDrerPv#6ZRXw0qvmZkOYUth|J^;a?_g zMM35|aA^mxnEjD}l#ow4&2j^U0(JkTM~S8ZkvgkthKU+_UnYnXVB9O=4gmVE)v5Z;UAmhk!%1Ie^zS~ z$twX3vjwq$Z$kdot9R(j8PsJv-lcdB$yqlmzzTzxQ>2M#noa)fI6 zH`7gU&LKHnjo@(zB5da;Hzl3-96cj*Jx@g;<9V~J*AKq~f& z>d}23U(y3k-aH;Hr4^vWP0VwXS#VOWHhwmP)e}7{^a+I|*QDmX$KhzN z_)d;`e%hZD{IgTpUxB$SyAK8%`**68)n^cT)GClE!_LI*P*%Jo5t}fvid$)RXQXEp zrcg6QA>+=$r@p-wWj5^O%#4CJ*cZagCgItp(tkANUYaG{RUDz0a*;kGaA^nM z=4svzFRfdEPn2ysH{s5_Y$SxGivo-0V*Us9p}alEcWJbV>9{Om`mASulBW3GaJfa% za~f3#b7onzTGQ&Bd^C9cfp$!~jv`>6|DJNbw17+@678x!i&vc8K#!ZwrigqSdp+pV zgZ7V8TCJMmC=NP`^jgz_F*3y=tGBhb+=QcPCt4u*@u_@-frV}NxF0*N>h<ECouZlsc_@wc^1XTQ|Km|cyUX@wfPtj!_C5Yu)VWlbYD@FPO#d$E_$F)wB zhIvX=g9*7q&q}kuC&N``1KRvUr*^NUwwEqG#aycI40SBbhrsKEXgwT`srcvS1u+i} zJXT?VNDVI(x*2}I{iVn>iqra2<<(kYS>FAz3B(Y;N5}{n5(W6JXZyRCKZN95wqY|G z3^w7__px}>JHg)TcFn*`PU}c`Y`e`$>B%v~g3q;&LF^0?!d5m}7*So_2GYho3HEu7 zqMtEiG*(BKO?*4G?DUEyJ&AK45&ASdMSvm7jdYL9zfgA$p4-d68Yoar_nc#o3-agv zPB92iX6-_ic?nDZ5z(rPk?Y>H7$#_}fWr6$Gyo$blTS}7_GcYVGuza>*Jwy}s?yoP zQ?Yl2zq1}*o4X(l!M#IGLs(k`e$n{Y0KiSm(6yC3Is^7C6&1WUgqfM`#b$QkRZN)5 zg$&FKH;*DE1GZG9a`T);n|eXxDov(1)T29O9e$ou&gNR5{G0>vQOCZqi)0Ge24$BP zOpA?2h3_(j)ZZhr2kk{ijGa%v>m}m8{L8ObN7*mzUfNrkfVo~uPx|kc=CJZdGNTeK ze63$y^He5u`2Ed;I)>lMbb3^$$^iztnNw3GsKdTfoYpv-M=WJ*gZ`kei=%!|;z<_c z@aeEG5m9!@1_FVb;2Iv4z;&ib ze)dOm%>nx93Wf4)YzxaQ^Q3q7;C+zC*5w42g|2Uld%&5|7-HzOdBxBH@?eUcad|VL zn9UAS!5dsK2TKu9kn)x0c_itt3gncv`sv>-sa57l*by2%c%*cwO8|YBkO_jRjLm>J zuX5m$fUXXwM$|AEAZ(xCzW%Q*?E`^zeFrctsr#cPoaX}YK-IDmSgNqlCSk{xE7IDC zP(6Dg7{pn(GH;c6tS@sX1GYQPye_VSkDY=vp@fawslOSk$o<aZhWa^UI{vn=toPuxqEG(C#$uL@1{>4+-4s-IkwdS7wOlO3T~AO z88KkE0UeU-5V|E&9HbscwyF5JT8&3FU)eRhqwTU2Jtb)w}8Jv}R~Wdz(7E$bE1BQ*@0^pXkMljx>z;@5Qr=!%5yOv?i22lTlvi|z~YA-N5D zkZI^*qLTgjkXyHfGNvVcJO!v@wS8(Qs5vC~_;6riAIoV0<~j~$r3nP0!n{b%d z8@WagYqh}EG*9KieLVS39ujuQQ$z?+awkepuq#r9@NLyfHJKVEB)h7M>#?TAkbRUv z=AjWH3Zxxv9sg@kZhwom##ZDJ|JKJ#vC5}&ZeIl{d8Si@$<2VY8vTDAqyO;_FE2qT ZAq95x&r07FJpKyuDWGD?!nkR|7wnIXfF zX2=Yg+n#gw)_u-z&n z2d@((CPygThy+JcyvSZ>ki4s?uBu9^E}<$Vr9#>iku{%plk|ph6Au$pJZ1PZ2~x}( z4C+TT-2MHiDR`Na68zMl9iJ)~A6q#sGg%8kJ+&T&O01HlfZhgQ-TYAKVAW5K5yQ9U6S?fX_I@1A;7 zYgQKLmtb{-Av+ZV!w4KkGEc4$11E;D$bXo6NY@tGo#-$GGR(i`j8Z( zHznxgt3g>qzu)(w%NSittS0Ea_cIroZ0{((Tu{Bghb&Isz`_`MfMGM^LfYJWLg58^ zgz-S?8G*19_Lu94UofTL+}3!5*+1`7_!zJGjo{8BoXC>?vPYPF5@JNnIFt7usNAYh z!IhbRSl+@cfEhPW2K#i)1w)bpd%y^Lw)x(NM~^@GaNv_l;j2nI;?aHjIQgjmGs$Au zCz=S^r?e7W;S_HPUww{#^gxz(`2G3kWT}1{&2X`0Dz0FKN5$b`OgPz@k$EEDLfM`R z=80|u+|KA3)Z%%dAF`T0GvrWyTQs;b9WiLNh9UGxOeWX@n&_>Sy!CDHqYY2ebF7KOq*>b~krk9AkTkHr)5V z=6zQ@IIY>6hU1RIP0A1SKT`1IKGVO&-@`KfB>73B`9(8^QS?r%?BmkUWK!S^a?ap* z2|dZDv?#_(yxPy6t@w*P0aB4P>){12#U8UUr$j4H%L^$8$!{=*M9xN8zI{=OKjllI zL>$f^+0z-a%)RWj_t4dkR$4Vv>y-zSNB0vs&Xq^mQ4SxuY)p+y9MnZE0m^l<}Nz5azBf=V|p(HFrJ~3yoFS0e0XtTd!9%dM3-+LZS`;FlpdySrBg+;=e{SbLZ zlra&f6Q>Mk(WFp`TuGEMq&254VbO0SpNPtejJ^`Hq zg_`er=Q1ZhCoUH|mkfPCBv~XX5-ZX-Qs%KceQws{EQPEO*`?V}vX$iTm)JdZiWO!F zc-<@1PWIMQ?@?ou*Rz8Ug?AH44%l57>s6+egmh{oYF@ZWoMztBZP#W{HOp0~?WNPM zE2u0;vyR=mHWgGFb(fw*hjp3tsg{fNf~TOml5W2tC`7Li<^;8Lz2&NTLUdBUhge~J zpoQ&>jfI_!ZBE2Mln}@lxEq)qX#OCrBzy8`>#?)o*>!ihmr7lV%#vSqzG_-ZYfB2s zx@I~A?a@8>hAl%covog&Yby6zbxfC6rsCyc1KEp^Oyb;1nL-(4N{ye}=Toyo=R^DZ zmiHkcV`PeCxV)r^m5E;yc@wKDKI>2vN)=w{@K>nXs38TAa!7KaywC)tx_++|G5rrk zzC{vM(&$hs{Q(1Zwc?kyT4~wa*^R1=`d4kVV=oqhoY^+C589eWA9c-t`Ef%MOA@yw z#4p9KIJi8-MLI^hDulG1t$i~@IM^_8EnX^#f&*&R&2z{Hx1P2+o$7@tSd3fq85O;w zvTPVQ$B~I#>S12gt9+y-pjA*MV7mKbxR(pQ7r(Nt;ieIw5u&ja#7iv0E>`W*sxy^n zrEeqpwxu$l{AAXwQ===^O4sD9RjDo17SajoHRuuharyn?F6Ir)bjkb{VHx?3icoze z0Y=T->$wKzScpdmY(xiJH(LptBAZ%KPLY*fE$j{`6(kHtRrl2H!^mN|BE6#HZhAXe z?zdeuT*P*Vj|kkH+%jjWW^3!H*;I9DwT4kQ#86_j9#kjqj&n{gmt_w25AzS)H*D9^ zmgWeX?rGrte^DNv&-NH`FPI9LfFE>0gJbmy*x|L+HZ_;*vIS5Dm4q?}kcL%+!XF6Zo0Dr2^OJ5rG{nE+`oWt1 zWI;be*;s$k`jzY}c`iXgu9GZ@=iyA%-(MM-9(6Ymr9_`cr>pmj!oR9LS6)cxd2FMt zBUAI(`I_OtVDB-TiNFX$8P~q2hTZtC^{(}^qr=zJ`ISXvy2#Q~f8Jx>I$pS-oFKV_ z-^6rrp@Dxvkj_NCfvM;0>5$$8?DYQV{Qz>WS&Q!_Zbg~t*}`iN<*zl)ze|5+q`iZyyapBb2&^KL>(fMYyf8;x~rFEuvmB6Z*znFeYa@&$bbo^Bk+Zw7Fa zsmXAZr>ho~RAbq6TOU zYxl^j+@JxKf#sA0(c053M@_kjW#}ZB4$e|Tos28$efD9_cQz=Mgx$~q>e$fHfY>tK z?8zl4I(Np!{z3gq_^$g)w888^o%sGEG|ht154sW=)36n)iSvv@`JV8p!F8kD zg-zw_sUi;-LPV~3krT?9uF9m!J?%stWbGmC%8JzrFptWEskQxR1b5U)W58AAw(n{X zVdKn&m**45cL&)!D_i*)6I{icv+;H7sYfYZ=X@u~-r5gnuI){6JFx?gdnW>XQHKEs zU(d_N5&i6`hE)9w1N}L6zOdp~82*A}gg17+;k?Jc-BcG~nV-F1gTzhw$VBF?CUWJ2 zsDNv7-^fE=ztekbr+Lxf={FO$cbFWEf;W&Du0dC;-dZ}rB|{#pHF!}B+vetmJvYLI zu8G|>H#a{T==T!)%o}8xR5a>ZfBd?m^+vo0(n#XW0M+=e!W%<7v&BiRmSq+28#PR| zUYaQ?VgSw~#vP1n{+1Xwfvs!6hYa{&VBCoG!@vao696BnFW3J#iV6F2H-g zX=CbW^vK1=8Uz+{5vBdd8A8DJ&)w{_kN$Crqm?MFmZHidNm~cgM|^A?Y#g*=*pD7P z5^;EICiF^5`d`g~Z=$poj*fOh?CcN-gbl*YX6sQ*e z)+zswCJ-ln3;}uV<(a;xff)i`gZX*$-+d>N z`mD^sJL~HvFJ2ou1$_$}^`U)q{qMd9gRx{6W`k`T*!2JI4W+)gU4K=rIiMsH`2No4 zzxU=b0h;hHB^Aq)T*Jrvd+)r|_e7|%vXO|t+m}bz`{IEneaEYt!!Q1}{Jt?h@^wGl za?JX>efccG%>XpvZaArN{JVX@^Vz`aZA$-$iCffglal#wtLM@6k%vB)7iSZCOIiy` z%wR}j?rO98Uu8ZT)O1|3G-_5zq8G#RA6Fh+zLQ4{Uj|uz)DKV1zAafyIFW!c;7rT~ zci2APEPjgpiuCWxmzJXt-^I1$EWc>a(fh@7Sy$I;%{~>(-^YQ%t?Q*Zso3F8*#99L z9|lQ@i!}x?3;Fr;gQvX5tSYxQq~4ng2ZiskZm5et_|J#`pU1IcBA{u-)1!^Wzdutp zUPxf0-6CE?|9*%6&u#vX(Ei^VX-)SOPd6Ox|K{Kf32mA%^hP$E@5!U#RdY2{W@+#~ z{%wyU)BM7D}+Lj zE28e=Xa@S)?Wi~VK6D8O-AbsuS}9-HJ6cn*Svvor$f~Lc)WgdC{K zKpQU;OLJczWKarN3`XB94EWO|NyOZg4t}@*BKOc;Tq7P)L|lT~*NYUB_yQblc-XF6 zB3sMJ`UP6Xat`o3D<;zofWnw{J`6F7nQXK!#(e$ zhq#A#ZAjKnQ(YFZ_?JUzpnDI=g;B>#ZDKN6bq|BWO&Q+DHt8)oiO# zZs_e69I&XyT14mJh_X18e@=FsUy(CSK$iU1NKj$$5%z~AOnbR5?smYX$!+z_n7haE zZVpce_-^cOo~5mBLD z;l)~ZoX$6klNFT5f-eayAvbM7r6#w_FamS+(=H+G0zJ3wheN(`dN?zRtULo1z0TLL zoJxAD^Of`Cc4JzyQ0i;u;9Inqx0ZWks~&FPFe;}$^>z1^$hIrS(=zGvLh?@3*k*>4 zGt|2scB@s-G_+SzhhxJ?m>$iHr_$bt}Zp51sg9;lWLcaX5g&>gs=d{l;s^S zTbvBekCyvvRq=fJg*yDa*R@zvTvroN6NX+k@8WVce?9D{n|}8xHNI=O>>4XRwXC^m z5d3sQSpemN?x6POfd>_|#Po4^4ja@a1UrrTWCara(aWDMlaFQC&rv-qYNf#2Zdp!X zT5E{TP4(#32Oo}kMUHbn=8)u}G)(2eo$;&dDWa$GHD+yF*TRo~{$-%XbFZ$&>tuz5 z|7gDig{nn4qjgDE{*PxES82&kg!hv*~OM`uo?w(UbKSR7h*R zn>lG-ZdEH9x~oqP4>b*C_T$1rXOhdGNxEKLpqKd8iFK6(8G5-3ZHsGBHJ}93*#6q! zA?h&a0r4vj+IqEICD0+ShH}T%A^p=mw5Yi` z8U{*4R}OnQRuG9@ZS7lx?g;PU$PCr)GLUyfgpuews`8(lZNop~(`B5%uMo{%=Y>_U z4L3AuiCE9#N1a2WZZmAZ7g;&woHW|QK-4JSMwu|KYb(m{em1qg$6l$07O-jYzF;B4 z)uJo$KAPI!XXLV=3zL8op>{>?5;6cYwjCR|Zt6Z4TaN z=kRW$q4Byn)I={}Qdg6jB@eMy&wpSWBcKzpOsTShGSpc&obIup$21KES7j~ut%N7i zJ^hb6I0}7x)}||xbluj^uZdMER!}B!%TDKaBhUog*@;z0A?3Y__vK0M+1AJaY+}v>S>v?1Y6i&Nc#Nec%ymkP zlDqxlV1FPK$7*xDaDR`m8`;C&7<}b*xo$pDX+u6y1TP3x(xu-!L8Qqbq3jgM20m5N z3RzYgi+*8~QR+#n?fU(15@)BeNw)UZ9h5Fj*HE>#jq+RMVjeCpeT7w{ z#Yy)AObRl=as3a_EQE}`b{_>d#V^MZ3%HH<1XlGq znUL7PW#K~`cj|D1=h=s|Amp36<)tw3&HUkANlHDZXwKlpdK_im|pTBmV~ldvZRwXsJbOo z09Jq6&4N0z0AUj5lh53Hjw*2${zpx=LrxdF>a@csE|a42Q&{`uOKy zHVtjWm89$m?3X^6RG;t5dWRA%-;s`W#E#Q4#^Qg|LAf6tm7G>tK#k)G7@jcJ<^S1DMsLeH!y35l|RO3fmaBz>Gc9x3CyRRwSmR|%FTf{U zWu9Rr#9nF15ZlA*ptgOv>(KgnVaTQJy%ZU__{DJ)VAVHaolKGBHGJ*13U+r497|p- zHJBp$Q&2F9vSw_9nk1OUImuACN)-Tz;=7J}TgUI>jJ#7F z`o$0wGLJM65RNS#@LI%B(fIsk< z)*!P7?h>U4!x?%Qxh}kP{lir$RTNg>fJYgF?^)HH7r8%Xm5$<^v70~b`T2f-8PIu? zE3{VK9O!+TPdSNn1Kw3V2{RN|U|xd%;@-%aHjKLQYJm-~*vHotw?6Y#yV}+t#tJhD zfx7796h`}~N1M-5cUBtgSS_31|;%*ZQqU7pK zoPVtjY{DM9-FU^O%769HfJtM!oos`%&*a|Hy?|f1!e|gi%6DMN=28_2G$!)ypm1`e zy;zX-S!01&*7l0eouk%s)0CE5=&IZY{ajH{bHWs6oOpJj@tZxX&u(D8ND0M{jn*C3 zpkL!bb4$D|EuriIx~YBO3NM*)x(96W->= z3EA_%$gBJKP4=NM$h!GeYC|NJr{Jb{xL?P`gE&LfL%ln`c2^?iBHS}a+uKSam!Ce- z1g#)k#g5`lGM;^=gP)QY*mglzM!ozT7{>#D$qumnJapGLWb&ygk1|2m$87Wp-ycy>bqU)V#kd?6=|GkhO??F1Uw{B;LDlbHi9V!$$96tkA zfqd6oUAM2%cn7Y~=-)7tF?<)=K!&%e%NozO#p+F7SkF}2ureFqgb{6upL4V&#kE$r z7e{rrw0~YWk=y488JrZo#ESCUJDIiqpQH0-dbo&4SVJN^QG@7vwc>7G5}8SM-g$x{IGY{%Tj; zanU7gnSdpd|Bx`3d4}|jY?8yzwb7xt-r(GodH;adbg3#T#~OXt6FD}q80wPv%r9*_ zGKf7i7q&M-wn4hL`Niq4MhpiqV*QOhef88S%2{^ZYeaPD5dPV$ooiQHKR$a5LO;Uj zRR!G6T1dwlYnZ1b zw8JaU8kZ$>mRoTOg=k4wKHV%vM;V)(7j*OzFy<{uD^j5>51W@56z}ABNqk{1)TwYF zx2aPVQC>k0>7lfEf~m#D;#N+Wo}S)iubbDdRKdyM$6jZh>KFKd2 z7${p|LGHeq^9*Aic`!7KRoJL$XmXf*>kx3X6DM$VXaoDpPdD;k*rZRvHX{fKvcF;- zR&NBdz}w;sj9&m!~jMMCLn@%>>3MYKgBhtKS z?_CgTp5m!t?Qy<%SJlFMo2tw^OcZSg9uS2j$JjwSQGRqA3v;~!~CLb$Pp&ReX!ES zguV1*D0)c1M_tHlK5hhWljTLkO_ET@2-}7ezm_jzigps(tYq8o;6gQ*7Vmt37=^wx z9dj03EDE+fq=@QD$x>ngLffy57^F9in?9Z3dz~-HKn}+=1w{rFRVukHCM!0hsWs*f z&uVNcXN5Rz=WK@bymIWQMUFLOs-+C$N0Q@`T_M&bE3u)1bfj;;RlT)Wv~7r?R?3`d zzFV7MmdadoX&l75iX*ZnQH3^eXJkX1AW|VoHVp~7?kSD+1@SCDNUCSV#68~?aUXXW z3O0*`erkyR#S}=?-|@JdLZCvJV3q9U6{{(>vjPE?ghoZ4GzE3VcD8T;c&d0;Y>}AO z;V>l~Mn%bjg-AhfI~V{85@A2B7}pW*SMD(0DXdxzH8rh290&W$>^mpK@a@|T%r()f9CpvGIw7?z zMFEB~1_z9}D=?@+g{;dvYZPwJveho`b%H%j{5!a2z%o?q>DSKt#heFR6NfZ z5UVCsH_o2gp@Wu(ZtAvwEEYcPFCX>w)B*^ILyW%j zlquZ{^jzRGd5`@Ne##s78VV?xD8$}`K8<`x|mubbYEDu_G zPBesul(H|IQo1x_X@g}(&>6ZC8^juSH%8Kp*k;Xmg=EG*0;F?xRxEy{fibavNtCad z?y38tz4Ox31XM*&hYK;37Q3ozoXQ&ys5b3(e&YA+n$49;<(!wl)T>Fxw}?+zYP9LR z%iPg~>A{WLS?0o~U9T5Wf^ycU2(YIqt+3P<+n5TVm3YZ5lN4ootq~G+K#py2s1K zzAnGyx;F#P3NK%20Tm(3%*7^F4_5AV{*YTX)Q)f7E8} zD1HDI$4={+ZkvqUW`TGftc4M32lShdl+!y)kqao*o%IuWE)0lYY%v6g3)~o8-(LHC8A|OHzh%pJdU%UOXOPoxwTFUI=s0QDZ9=w+6nh9N$+_g;&c{GF zUN-8yij7Vcbze;(42xHJ$mGhB=wD26a+*}U1ckf)I3sv+bm6(*$8V_r00rpykiK`3 zvx8#u5;zXdzV8@#>3$=+n-~~15!+_72?BrQdh#Cr!3(xr!We?(6F&! zDIPX`SonTP*m-NMI#;$HrL5-?bH&+l?rnQkeAc*jX~e<7+O<_yHINUQ3~O?sCkhU| z`x4No??(1t31y3S|A^ER&4mi7^}EVuq4Ee3-!p_sM|(tyd<+;7PU8wrwWW5|7ywW- zkixRae2*S@V8xbUysvXsS;{Ca7KQlgM0sJzWHY@S2ESQWH2(h9jG)ZM;(_6YKS%x-JpEnLgz+6tk+m5!$i(GT2gC5*O?mLk zx5IwFRz3A+^9%k|-NJ#Dk5%L3u)vn}d)+Kp?7I~c28>4QVMc3!+ehvmbhd(@;k6Dx z&-4%8>8^4SX`ien**c?NR*V!A6jb~A=h!kUegW|I&$S@aS`~>p-#S!Eo3kku!5J_8~=dR?E zr;cn>VR_}qxxoPylQ(%nznmO^5ChUFzj&3O4vCmsUaZNbHuk5~wz{!j#T%*KY%X6v zJr@a{g1NMWgsxq0*sAP6U7CU585t`Cbur~$2-}D);DQ0K&sfqKE0H~mi3Lw%d%ayJ7yN6zshzd9oDSMIi)$wgJp1Z* z7Vn1c5I1lj+QNnXs!hU#$CcTjvozT2P02BrkC+U&mO4V%-*s{GmGWWxay%NtzEOio z>G9qDbUl}F!q3=SkLU^SJ!WmBt7Gyn6-r>VaUer=KJ|a0j;#lXFaUl=CfnA1URY){ z5qp_z25^iDpQbio*+KgV(##P^dxH7n(644DfCEtISC||z5Z0?!IkGd*EW5y=8mR$X?M2{>1%4T^?#7&(F@tX(%iI94$XW8)~YYe?qoLny8WR zb@tCi<>!V9GvN1+g{>wqkA@X3yKYQ7rPpl%BuAaeH=`VVw#V#^2M(#FDV9CGH1F?B zQo9dT1TpK49Qg8i>Q0}qjFIHTq?dPN@lNSMs$H zbTSN~l)|6_A`}+wFH@Tr)ATbWeOD5>a;_|TsBX<6Fw)E2HfBUs$~&$#0{5OHD&Ada z@khLVpzLDUyzaacEVGbA9Ps&CsBJ^a;ut7JuCdNx-1AoBiunFk8EjZydAE+SKAzJm zv1COQ4MXxxzPVwpz+?i@t*F^Nq>gOqJ4uo!jVeO7v&@sdq?>o5>pn%!xg`~X{drq2 zN}~Lckc{W`=vk&2N_Nh0fwN>VfiwjL`eK>+qM-GfqFrWsYC6N`S8xJ zrXoMg+z*eA`F=`fRbAd`%}C|_9M*^wF!yQ|J8eOvK@1E|df2M0*$R6;=o4T=k~VC| zr_B0RN@DPTxZKAtRossEZ5ZrV8!#0xQyBpBs!!b)WQc0xResmiIWl=a7=9&xIO0W;+j1OC4ch^-g^2RWI4ZS@_{DnJstg z!Z{?m-)GzI?g6xK`?!#cPtrYrwU6WTh9UW0R4>nPTjvx4S&;S8-#*Wn>|a-qg53Xgrt9k#LuteiXPa-FCR@o<~rYh zcQ>e^PX-@N1yqvQ^f0En(C%T+HI-IZOlS+I+YKO(%}ql?!PWF}I$RMj(RYOY4lRch zwURiZJQ2a^8(wEyNp~Ln^t4~J=bSO@#gr}RdPGqdp90wIc+depU8+&U6RikH(7hXC z$MYXyUeh@;RIZ<9EOS##K6as{LmWs9J?v9o2}7F1S+vX3Tezk!mj=W$tR8ZjY7%*Y z7F*e29n_x7RIbbTGXA2`eSCAUzJ)%)IXra7#=)~uFLZA32ir-KAF{Ofd}Ul3b?(a* z;EZ&a8Vn4UJ6wFr{bkhvi$9tK@Uqm5c=^;RO{zn;g&Hn!1)3P+ZE3WWjoz`<23 zeE^`V+3APvJmS4h*O$r*4txU$M~&zxxbs?=$?7`&fN+0tF*mW0#2)R#CnjaT-77_^3p zr2r3?NAz$s3N<7{br>Y8p9U@xB*cbz1!Gd$y;*+U0JR$X=ES3n=s}fS$&b@NWeT#= zF=~52fQ=5zxb_1;GAEHWGe!2t5Ce{TcwU#RM{$^mYL!+Ele1p`xRdj)EL)8+LPqMG^_V5&+OtinCaB ze+RX@-gMC@&vgBaO{2c?+-Qxs)`-8u;cHD9&v4Df&Nt-N-_z-8G?|nE(0j&WDP#!| zdM0~(S=KMW-Mi{_wS=xK&xuwkHqT?`9Ip6_BOy@%_<_z!7i;g*QV*7Zz>9vO%v>40 zRW`uD{%O)^69#EW}$mY>T4X z)vgMm<2ofpn;{c(c2)POl0Q=^&ek8z_TU7>X|LTSyft2}+8_TTBZyUJNt*5IviRCeX&>4JfVE>sn0I2yEWq{x0{>gYY4Ksv`=D2$git@kKAMEXxCA^xkTr zHv+KQgZtY8B9RIUN(pCD#FDkH{&igw}r@lHs+n%i^;U_~786TjOTf(v=!fQgIIQGcj3%Y|&bx4dbe zZkp3sG!IDe?gR6clHPwHlYK(qiWHZT*=XL!t5aybYt6iDpyS$OYr7D8kQ>xAVo`K6Vl{|#Su zK${nP@ATOry7qKG)nhU9`6ieMcI-m9 zB#z=I&vHlaDbTnxsB+3|KWcA0!8Vd3t?d)^iKf2In6b8A;e^zkp0bSaY`tQ3DU65Q zW(pg6iI`N5UvwK}aK&pk;qED|&L#Kjj5*%QmPIle)$fSd2Q#Jl9vK$^1&p68NS1uJ#BbUy^_lvbj|1Gbo8^OcBQE>pC6nZRGUY$=G%H} zyu#zLY)5Y7ZQeHTS+bnLT-;M)t*4~4A1wl|-2_$7`tDciO5Y{~n0M?d7owuF_+FlU1=Ket>!l~6nq58Z zUmk#^^&VavBNB4ejJ*ZoW7>G_Q{wcTEv(&7*9*|v5PgUg z59aOJt(DGHcjP+g^J)#E1>aBTe%LlXGrG8L;|b(|vqPN+;@DFn!}gY4|Dw2>G% z{-pQQqP5sxo6(m20;&>ueX3^NSO%Ua;+ghH+kA6qO(XB!J4>H`nTZ5q*{*P8*3yYV zK}f}xLk~b@*0a4EIRXReBTL~T&uGrJne>Ehz8l+EGn2oO*d^S?a|`L?`zj0gO*$;<7or=Hm*?Ba7wDa_5Sny^iLzy zrbB)>0}+*q-X=#==3z6Py%S!uw-B{-VM0%e?~_sKZeC!`6f9h{>^RMTc~%4=670T5 zIgC;qFc5|BGN#T8^(AdZX?c=pJK{suP2-?|H_;opNRMBt(yd9mASx$ZIqBqkCLmS^ z8gAYv;<}F0lT>2L^`vdo%`dO)uett-cY)yIs$pb927%5jJHF3hD3rQ^kn!Bljx!Ll zz1J*`SySYLz;WnEv-@BLppT6#C7~bJohA&oHFRw%MjOPIu1EWRWEU#uq0}QjZMM_P ziEbEe{9Jcwn_zO=i?nV0?qMx5e&;;v?Bc|(v2mcA$qA>2B=&`yi*=z1mvhnA`ee2} zk7Fx49{(ROX7J7NS}qrRZt6}(Rg2bGRe>HTo$?n~L=rnri9tUUtL1XYpBh@S)Lx?$ zVO*zM1q!9U?EvHKU|4lea~ju%>!V>QI!|XsGiNCu46OIRw?wzq=3cJ7!o?x5s?Ra> zI%)F+LPpfjv?Rn{vS3XrP6Wxh$bK*3z}UlNHm9hQDblqpHjzA+GeWlV@bjY?Tl+k@ z=Nn-`mtJQ`$ON++m5@^+f2uH-dLYRYne|^`nu_xEB|6(pKZ~;Q{ltQ;mr)GRF!9q) z&%?usB9qahBo=IXvF*D3X;g1)xqF8PSG!`o01ZyA(lI1MC|f(wpON12GE7`4!R=0q zdfm1pbY)c+#;a+VBJ1TcIVi$zEiPGTW6@aPRscY^^Ut_W&boH%HVv$n@AGx; z?{-kv?k=^E?MI%-!4E zeQNadvVX?5qo1H)>G4o@&j*lC|J~)_5fI?IXX3i7}(`;tfyD>@G4c`X^ zpS)x@@BI?Fm(x}UkU&0|1J2&IZu{>@dGngAJSt#iR&9N6%G#xvEHH$uM;MgQdi}_7Na)x zuNf|QK9M)$Z7;tvrpYnE6WZ4zjKW&IEpHuYSB3q|4;pr6{w>|{&nHXd0XmU%fE;TJ zkoX`G)EfKCT>a~uN4^;QfoVXX2J(HNsW6qKU`(|~7bezC3EnE{qMRo9JzMji+dgK` zfszL^hfJpgT0DGX-h-!~5mC{%6-DkTH&O9!v#`EEyU1X+IKe^LG5_nWtIskTnh+jHMz2B(s4UK5p9T;$uJeRXHY+MH(3 zZs0>k_x}UUIRDg)bCn*+-=8$$w}2T?_9c(&f0WLDRJbKl{+u*$)`?qxf6}~t2F!q` zOyBPP7yI$wJLqF3^K;TbdYpdz7s>rGOaASUHePtM=-t34f6buy-@5i?3Lls>Q*a0U z?|*;N5Cd}lKdSlvk7~^FIvyyeicHm?@AW`4NVMKun*gXk*im^6SE2p{09PX!6cdS- zQb9HAFo0~`&?yfOX)8ZH|0`mD$hfl{r3?i6ms5Q}f*=S$Op33tlGaGQ&Ua*9;S9pt~3dlV}RFb!J7uBLRRK6q?Kvxq%jTc8{eWNR* z4MkUHjaT4%>cEc;31sSeUmU7!#>5^2uxu@mtkC9pvJ$t8sdxLZ5FDN zE=)lWMdMGg=ytS~AUpCKOZFL9Hh`4Y>kuGqtmBrx%YrYETN@WP!MO%=98p|4e669~ zcArAv`%x5cB*Cor)kX4NfHMLpQ%cAqJp)j>*XVAR;%eK*i*eS{PFhe&8!;FNzACMz zN=<2PiOGTTRp&5~z0W^W9$=*A$q_Fi>`C=7Cw}HbLa~5?311R}N!F590#J60h68e@ zYG7G}G1=||Igdqn5+Gqpqze)1>U5$J2C%j(vHH&15I`4*egGvluXW$9=bvo=SUuCV zaJtMG2P{D6?4UIu>z&{vGfd2ZdqAWN$egB!1CS_EL(9mwG;m>R8SS^<1W@LyX7NUT z$5lg_GPoVJMYCKWSoJaFJy$Y%3rG_sX*4-KLT;L+c^-XJx&lzMn*5@gCwv})$np^w z3_L&?*8;WnSXl6q4^sRP%}25=G2-*MMOcq%_v*1SqhA z0i`N1U>L5aH7pBlM*ze~=36n-f0|iYMv1dvub$1~M%1j!(*2(WL9L#*?qyo0?WXqW zJUOYHgnlKl>6|cdXDwpv57V!8cKV4LZ;s?DYb%8tdhGiC%z0n3$`%bGWSMxWOKh@Z z%=K=R$^Y6L!RLlg^TiAW5rF%jms5Q711MMFG-+4A7k1?Ibxyv`SHn)?$Tn+jnJGun z1v>dYIh)syp8cJW7z3rSbNSeZp0BR@jyvdSt71KUm3Uo$fjF(VD_?U{yP0RY+UH~E z)>#}ZGU2|vKGcFffk1_zKTzsDEu0hhr<=lLeq&eFcCPB+ zFA^L^P1D2c0=&{+V^@Ge8A?MO&v-awP84E!&ugo4283!jL-k~zu-s*<{vv#FFaihm zZ8A=j_kXz@lA)#)Cv+q$Q>h-g5?uUD2YaBYhtJZ`g5A$IV~qk78*(4g;u&MzcrYxF zI^Q1%!xh}f%Um>f-I^>BY*RUg4JK5YW3SZF-c^6D>k6cV-uCyANxw!)`}Aij;O={K z8l7NVYaqWY)SOdsP1)q}a5hfF*+bdY6lF@)4d3B(N$0tJ**|^@0Moy;?iHgSP{-15 zQw4Vh9jp!6M+l>;O_Ub;F%B7$tO;0-aRIWz*0?_@6mZ(KK@rd_L>Gz4F{rmCvZRFHmR`tk}1gbL0ef+brbOPX%(0>Sduxc2I{Jrq zoSwtWehj*gixhqY2Yqaf=X>g=!UzdwsmB~d7h~8Fl^hyx=I_uCKf|O{w^0>Rx+zCc zy;a%+>lfbEQ<+k_25>1_6zMlikUTWyLR7Q9(MXE@rW?4`05;s2eg8vFjP^^iMts`9 zEan+z|2!uq8&Z`bDI9_M_sONANP+0%d(#dVUabM;b#g2U^T1LOnoC2|k?M|0=&1$< zNBf*FkEw9N!@)+NoI(#Mp~Sap^)=Qfln`+4eRAa9uW7m% zC#iy_of>wU@7j|O(3)nieB~(|w!Q1uK3W!DnzC;q@LqNHBd%DyCgrKpfhex{`OXKV z!l}K~$Pcv!6?fISYLRj|i<>t~*YbHk^yKAXC%9Mp2hOrqPG)3aD;D;qAMzPIZF~F9 zfP`l5PPSGd-fZNvTZAH@r#JJmE&uvc1!H)R-m(QUW{ulbk0m!6ba1F}+b_0OyNEC= z;E3!<$S|3_jny`@H&1cW*us~%`DB$zM$jfuWLy&%?E*Ztl!ogB?E2BRT4v_VOcUom z4>K&&^>T|P)|vtCc$V|cr(|%yV5pZKG`;%5&Db}TgvMd3q@%_`M3vLxyLsTw2?0Kn ze-p6mr*N#zyIu@JLgaJK}P1a}E8 z!L@KF5W#{555YA+pm295Sm7Ed+~qFzK4+hO?m1uk+JB$!!`~V&MO(FM%{j*ybIdV% z?`u@%-Mf(1ZXt|e7vT}IG>e0T@&h!DCHuPNFr2t^b?0tMk2-S4#tN(2yhL5ryL4VR zwCNC3KY`}y?9dnO=`k=GMXt7MYA@i<6i6{l(l1-egEphB!lZeP2T=2b;Jz`kK$nB6 z-|&nen42&k@&y>5J+EUg(c{UU34Xb})9+_OI{h^V_D2On?3$LdguYt%`C=dbJmP5BkI7N}!3=|SRt_X~l+I{FD!WsC7$N<3y!N$wK1+SkZS9CwHA~>bK0c$7 z?jhE|e8O8TgN~~rO+V{Z%sUv3?x%1S&*Zs5@Em&;4iKJr_eoO>cYqpI+?*YAy6Y#4 zxTJ$@zd-Ky=(7HuA=dT`bgGVsHD{9-lXfVJ7Wi0_+irQEu$Jeg?w61EXOUmj)gS#No6R-fyZJ0ZfAnHA5`Su4?c* zi){D5o#Di(5H@_+Huiuj{J}i?QR7SKYA5yl*4Z}Fw7T4;#aVG%vrDyfvkpGivdXtjH3h~1%f@DP~aHCGF$g} zbTAYTb|V1=4XUT<#8Lgu<^X5R+1(V(8W9 z0sPuKkPk}I7lNSkk4>4*WWmJwjt2z=nC{FkJbqb_hPP32HirA+?n%qq=Ms1VcHxXq zn)l750{S6wbW(3|0 zt~}TbH#Q^6)4Y&Fk(epGjm4TCfxOsp$RCHeKo(?Am~t{Vt+FwdYYgt~c7U2JuLU0M zy4s5ztt?8n0iJF}mfV;c-DVDH@yc!8Eqb%Yn6U-qP})ARt0)kvs@9dR=Xd(*$9`s| z62U0-Qn(@$IC0mO;1RX9IadRA>&&aYH?VIh-<0O;s+3BxN+QIi@W0iR$-a(oMh+$? zywU`1Jj*qIq7Jz@0Dv}5oEU6|DES!ZSv6>rL(%BFDjPo!Hs5f$>Svt*JIci9a%=m~ zcQtC_&ADQ3Lg4`>X@~4wdmho z4&Sm936`We*C&OTnk?4agh)tkJXsHx+9GSjKd|fZKB!D-*arRcTpQRW5#WwM=`|}B z+J>AHVl0M1HcPsWVb2oVoBdvIU!cFY`#Co#1~ouu1*n#mczs{r%1nYFA`!iyu4pcs za_h^Lir^mRIbNfM%!m=0Kr2Ot@NUCRhqY1;8(*_hw5R!ik#A4Y}Mvec9_=@;pOlqwXI~E@!d<|*LnrsRN-SuP$foqR`u00Mu$7c z_b`ATbGzHMS{Ka+Z(y1439h74aSGYYbn`!Wx`=<>p zxpg2~fL1OXEmsT>VKZ&)Im|78I!BdvMRC0>NlH1VghR+%m?~v8;hE0RGLr?{Um3z) zl|I19!1hV-w~d>(-#Yn%9Z}mHCmU1M0&;wnG(rfEsDtqc@4afP)fId)fE~4W!X;i1 zns$3Ch&qfmYT_i!VtK<74L5Hp?c~o^+@3Box`{PrC(3z#?WaTaj~b6WVaua2WRBs0t_n=Jt_x~(il)u`(}cLn%-y-P8DmHm|h6NRH8kf4eA58(};%@Igh^Y%%> zLnZRL&iv@#ADj{3TVWyJ)Y?Dyt8p$3w61XS6t7+M-kkyErLFFKVb%!s*+TgE)@#ss z?jZvl{wT}OA(=hO)4GB>jDflQmeS~cr2=t(;it!bT)AFjd@PWa%|s)|#ZbD>w4QE_ z(w`LrQjnI(vgJmJVs&eopHC&HLlY{EPtg4~{cLS%+#{Ou4{5OH2YgJ{wz1a4>)s~wjF%g! zY%i!Y5>&QG+SW`$+nUzGUxIH=r;VCvw1CzmRwBVs-0oYa$M8EK-D4>wwD#oV{?OtA z{)-oHMTJ~0%zPr?4`i2mzN3Jk!FxUPk1{KhB9-(H=3A~>Nut-wH5BvIQm za;6IBG2wE@;e4)$R;lsp-sft~rc?uyP7Fl#27Kwvvt?M7BTOA^9}YYwzW7KqV5_R0 z>uQg^szUIGDU1pmvB2V4io;h_U?GyF>a8xpwMF+y`SWGf`u*_m(fl~st(|9CB92J9 z!i0A;>biH_gYhc4<6LZ7AnD5M{miPw&DJ3$qwc;lk(YMO&AD7shF71NP85E73M*oe zZQ?=aj+X81$MLiUCfRuqvsA)JahGEbTQ)qz@6mFc?tZ5w89}`EiFBM+DPR8bTsE!K ze_6Mw87_|^Shcise`lGT<#Zsbk?4XA1&E2IrK&&P-!>$B6XshT< zsMNmYB^w+(Tg&q|JY8yv5!@zzo*9v*v|TKy4p_>xATu55IR31d`@UP~)RmB85e7`X z>xrta*?c>k1pXA_-&l4F7wqQMG#h4xovL@S-Cmy$ub&tEu4-7K2pC0f^GSdctoZYJ zT5^vVz65#j6rRilYEgs{zidL8uHr|9*{sIWBZt}D+<7G(I_xes{cNWVbH_d2Ao--* z{8>j|A*oih8WHUVGSWsePYIs_^m!whlA~0P+0Uw+sUgB4yzG-5E z-nEH$)tm3h<)+_sPP(6<>G@WWe1o_x%aygQi!s>2)z@l^gy2abyGkpwsY$ zcC>mJI+Bxi5bp>cMmpQwK~Po}xx2IK{#D{Q8X3>d2JQr))`R)13>A@Q$ zNVizAf6ZLhyMTK&)A9r_NnaC;M}lj2xB<6VGYLi@L|~!#x$5h_FJh^?Ro@h`J{7#Gp|I{I z!=2p>!KW|w0b}JGHwK&|O?T-VOjhRJo22s+Eke7qU=ZAELP)yZzQ>q6OWno4c5(0A6ey*IkISDd?eq_A)4<}!neM@7zAzpme$6lG( zl!DJ<8Co6%8>GTe`+~^jrPxwoiDafT&*#R(v}S$Ak3##|>rAnXgCyg92r3N8LXkA2zM6hCI196K;zs=BAU}-oiXzXw3G)y?`@{Wj4pQrQzkE zb*aWYzCbF682YD|=jU%RjL9-KFE}@s)!gCSUR5efHySp1cdAj}_|5Y|0HhCAfaH8z zt+PSn_@Gr-4>gD^4}BFBGP^0t?eO`9r{6BX`HGqJl`3&=CQtj3=os$rNM^J`*?BzV zB7TjyDkzyUO{bF<>>hTDqQbu%GQ&2EHDBx?ELWX%VHSg)(=)=gMF{NOm5^vXZJxzqfD*e0^HwT7;w0A?hyvEqfN|e zv1y`SkyO`Q`0<YQO65jWwV!py9++|6e-Z@&I!n)m)h(hMcFCeZ{-zG z0)?>Uf`8n&@+b2~w^GAWdd`w`Nq%y&7gY4r3?W%8e{5Y!_7AQII~OuoI~F>@n!iF~ z_+1ceg7n2MiQZNB<^!GUz@ZfvlQmMZ38XOtWQEo~dbrXR%=Vi-w7Y7s>K#x|=rokS z(`Wd-O0^t1gqxdufkJ70iB?1EoV$qidM122HfOy1^rF!&Gx4ulr&7|Rt}rl>uS9)U zfZ!h8?0Y89pQZ=lq$E^1)#O%HrWEoGFlcT`;3y-ue@HAR$+>6m__D1SK=Vy%VWuirgk6kK13xJjYM;tj*E?p2)c8XIpeFPuOQ^D7NcJ zM2>veMD6A9B=rJ?0;_?D(7)MVzrt*$+f_M#WTPGzTV0;g$i_c!SgP=-Z=qQ;H@CfL zrg4?4@u00PE-IW!k{ZR)Nu#!`cGf0xCNF{$p`R^nBke2biWY{IKA+!av%Th}g{;>=#qW2C1{C+JECrJdI#WiE?sjnv!i zM?PJcU+QabCFq4pXDvJ(c6!7|0r4lwOzL6IMS--`)_L_~7Y(g!dE>90=cx4Gojc=3 zBr>mytA<$5N2H;quxaTotQWq+d_?`8pXNNU9Z8{`p8kZ`LH3X&-~P+4b~1o&riZ~g zuk=eRh&n<-z^4GEA5t>|abBTvV?>%Y5( zXYwx5_}70r6&R2RsSt>%=RU|D0@H!`q%QJ#OM~B;CVo1txo~S&{hj++IqEaWzw*2^ zQ*QT9^H|6KN-5>@UX*nx5oAF;wtY}?-hHzjr>KOEo!{;q}{)(K>2|db8 z;#wRCAuoC@Z$KL5A{n3RWVoZ)<4GuZpLKCPE*We5ORumk{gU9eoFR?g9;cz4({5a1 zJ?>h(n+eNO){>wIpS;ny{7Ybg>aU@B6Y%9F-qV*Ri#+bi+1T8fIn3Ee+&w4-_L`Ozu+r;UL`-=&iTaUwWHg-w|>H zjQXwWWvlxUo;+T-PXi?YN!E^^r{P#_i414c$yiz?WiaAwyJyVxQS<#R*YtMx+@}{- zEWt|m7fzJ15UVwLfw1-EH__qQWdk$~1bgb_FP9p&%-{5n#WUr{9PS1LmBfF-&RcwF z4+s?#lts-;xEa#gBt?db)b2TL!_VU|k3;96n_*=wn8%Zq2EE6s{a$Tmhka{50-wgW zif#1BdbJZ_gLN)$=}#2YX7XiDF#6f62ft>Qy=0brj3Fr|_ykT0DR_&e{*7J15$xc8 zC)uxCzfv(Ik_CI&jDzIZMY#2OtSt2NdrUlZY$<1>;`<0STr~w%n`4~gP@jJ4^MG$p zq@VUk{+^GQp-w$-7E4Fm)+h7_S9)n3m$DIABPC8vucvoi7wcz<4OB&s;jLBzNTBt$ zoFqMzOAJ4wU)^pKQWsPqeS;5W^*gGAlG=Be@%v~<{`pSK7_?EB&*Hc+iHCXk$wGpb zG5yiP?xD1(X53gdNd(z@GfM*Y1Q~Pk9a=QkX6g_!aOowJnQ&KKJatq1u$EO5)#lb% zp2BbReV+@S(va2|1JsO_d0s4+%1_?<(UaIYC@yzP*Q!1Jqer%X7THvjAHmdSnLu}A z`}yxTxTHp|Fa0(pyA=md zZj79WExYNv1j#94H?gK(Lb=89F_wqWtRqOVF?3;3u%oNQ{=^L~GT|1)#8?sxO_Zl< zJBV|nf{P@A11em#hC^<@9u*qJ-Xk)I%)fmU6*yDe$%pgxH+P?S*74z|&|#pYO5x)- zUT=QzixlMp`j@woCxNOg!{T5h1gzKGXi?{==k26Ky8{xIZQZDGTt;@{5k7s72!l~w zqm+KZH*4JPFRPxR$O(jPMtf0gA&0ifss05T9ce`4{-z{HwCim9+2qknOXAkllov6f z$Ik_;^}giHpiHUNrCx-6suuIL__KY5CZ0BbylR05O4)!N^mAvfdD^};R;6ke0V0>duwx)6o)znZH=>9r`m9R(AZTu8z{;Z@6 z)FV8kW#BfMhEI%g3*rrF;|sM!1CIIjHbT4;E0@L;c?5wxu?U(d-Ol$n9*zR*p-4OY z&fHUNKM|y8V7-AbB#b+G#$A_#)J?++43wP?cx+Ex^((~z@zGjagSUPhn$%sL54CvD z&mP#n|Is+D!9RHKaS6#2Sk7|ADIk>Z*V0pB6?;O72`k?%{mEHiS3ndWRITTCSVkBu zksmKl7{A6(m~t^q27#$Mrv%c%m|dUccNCOFYeA_?e)UbLBkxFjO@!)ZU2&JbUFA|V z8a&Z||LUn)omu*-LdqmQrGBx^UK~QSQ>+J!t&OW}M$m*>>RSkAPVjHcsr);d56xvG z-U8E|_3f8a+??eIuZxo$NU<(c6>5i~}|4|DxmCC5ydMWOeja%`U^m8QmE{{c==LK@us%^ z)H-VYhacowm3*V^-i3O9;h`{55mJw&i}fwVbU4r z{tyOLf8j-3Res@7w8vGu1|>`%<%=+rkCKEnNLm~=>Y}+r1;FrkC*p?zJhZDc!at#? z2(%uPoISCNTnhITbWKQw4E=?5`&%sH*zXwgh{G? zOYQ^xLbI~bax5YHXjCcCpsTZ&ASVkpj^X8qB7;pi%^LT`M~F`$+iVvRf5*J#jh2>) zXQgxEdr_#fJQO{orI>SJo>8odhCLKOc%1bqtzqO9&}Ankm^^9< z_vPYz%2V(*D^|uc4sGu3vH6wD^sipYj6}m2awOPtc#JYJrIldW1TND+ctl&Kgq&c$ z$>y)2yuWlS#K#!|)J%1SM$fmTK8CI2j8NlyD-M(sFivGTk{o!io2wanSFh$wY*RFv|AMg+ z+x5CTu}azJ9_TYiR+(BEQ)T4ET0nJ(1VD+p{9?lB5oxbuTWt%Eb}L|(M6C4f$6vI# zw-Z3P7Z@G#?IhuDFXu|nk3YB%abvGPK{8>Qy5E^B()wP&amjkQ@Ck;+uZ^1{^kD;2 zeocK0RG0AG?72S6=T^BcB1P4W(P=Xp{8gs>4M5bfXfGB!dW@*pe90jAQ@YPK=FLIk z3%F+&5zxnW5K~~-(akk+;_0+%L z+6yy}_zFtWXQUvwIG0Cf&D~|b5@*CMYP`4xdJzJ98%>3v(YPfgLF)*Iq&@B<#;Wwp zxOw@sk(#~3uYUbQ9Gn`%E#?j_LD@W5^X>wKf8~v*8iv+~EJI4h3KLyLg-H=tKuf6GF2CQ;;(h2P;XIp&fRqHNq%j9F0 zz8C3i=R`!v>BWn6Vfe0!5W!650>OM!kR1Q0L%OgJH>2I=VlZicdDDAAYXxIFm0u@v zw|<&>bT>2A9J$NvQ4m==#8ZY37Dj_R)~kGWym+hA`eyfoLh_t?R!YF-bl1SdJ z$Q6xw!6q&W6V4En01OGG)VTpIP?De{<8-LxFUdNcdf>HL`gmcVH|bTs4Y}JrS3n{3 zT@GZEYa6-0<8gHza0+lmA+4a3s@TI_sVvhLur?vyKKMkXo1JyT)zOVx*e&4KDvxO) zh&225{XSgoQduruEJI>rqRn(bc;co}_b;(}K#dfXi%T5q`ofRC1;A)P?H;|A?m+w^a3GE*_o!^ouL-0ji_MvM&(S_eBdeAD|34V zyqdIJB!}P)L@Y{kDpN@cEi*D#7_Ng^& z($A3kuGQO;$zbdnJz7V6r=Rn?EBq*elOYJg#r*68-}1s27ZVNp3G$vN-Y|J? zT>vFl6}=Qo)mi8V+6*4y8SS{xPx))L!qyqDz%3t5H-D@~bKG9XSqf7>#VpwHPi}i! z9z);wgp#3ngW<1=%wVv1%2BQ08I31^f7okPO-%u40+k-lxaVmswXf|%-NZk;Jj{Nqd|3`*Fg?e zif9S1Ou@TBLz&4h-?)4c>H}KfVDCrae^uuCy`h}F_7+C6I0YqjPR@jrVCX{mgb8zG z-$z}S7o@xEauqy2*`VfxcTe8(0EeGRdTQF&GPCRnkdL*?=LX?TEOk3 zo7Y#0ZYc6&0-0U;v(TSn5u4#=KfG58Wnb!r+~(~Z0)k_LD0R1vPse9XE&``#C-96+ z3?kc_J~brx#Hu&)TUK0azDoZ-sJCCED!Rx2xl3@%_H_OE9Td&he<1kDxSBOAn#GAs8F;NHR2&N1mjXokE4G&FA3&0WY>PPO1wXOznO$z%1a~ht*%-Cv0VZ$mZKXf zz&Amk^b+6j4%$Y^_Ey-y4lh91m2<3Zud0mXQ0huUxqf-AR|s z*oY1H`TffUk}ihjXPanTSxlGP?s|9X3exxn`$dXzyF=37v5x=^-4p&?dTNv6aWZod zAQol#jR-~gQ2o1mhEP$}ziNo%IDysf^n2v9ktEoW?n?Dk4c2|dZrNUom+eLAXc7Zb z@;=xy;WgNY@(k=0iNDwTS^|+M{nyd#Z3%yJ&ME8ZHd&P=^3r5z%1%*?4}E;|WKUir zBM0j+p>tW_K}DgiL?v0Y1I7RDIP;!iV;D2eR&magIAs$RBgb^K+%5%q$0(LB+n_+~ zz>Lylj*o-AemF~=v-lh!ixRld%|Wgx0Q{Y=so~o>tzLNIIZl*zG>LfT*p-rIM)OJg z@b$Kai%3bF=JsXL@{XLmnP7xz*gPnAbu_jz<&Iw8OD_AMy2pNMnB%p_J*5e}U(&1p z)pE-E~}@K_lJYbPlE)= zRZ;gpllc<~mZrI4u@97^=Tw-E`_Ejm{Fo3L67vulYV|W4C`%^#>DU>|R$E3j9W)+I z1{>i7ThwV4LuUVEe*mQjvs;ov#(_|(Rz9ZVIW3dL;vYOMX1WZ>okm&K(K9MSxa+kn zKgVZz)>_r7K2$M9c@jn=#vD;CfF$+mCP1<^_J~4diFB%*f$Uc{%k?+b$xfy$Q+L>L z=_zv@HUeZWUvysL_L(d(*^hjbZ4z^mGTd1BiWKAq2X-=Qwz=&`*NM$*Y>WWf^rcOr z)4uD|1R>+s`)-%aZy|>VvmC!u*XcvPIrchi*RYdu14;?59c*eltC4WMDm?>kLGFHg zh2zW6tjaCBnMVQZKP)`s%C&1N?X10Yu3S*!|XIdbo^!7O~m7=_2 zR-fxDUSRJv9uL)DW*mN}mCi+{D(bvqODvlhyWhJy{v6&t+Ra%jHej^vt~oEC{zJF) zF8*!jKHH{c17?44_5_MqeK=FzeseRdS+Yknx_CMJ`{wWOvKw(E}X!5 z3oE|YE6q)lglYBlTzS!XE6y6%7#aC1g5Q4;3ulE{#TPg>9?I$?FZM0Jj=b4m4-pGq zzT*XO6K-id;C3i)jL*l!(8~0qIH2Lq@5@eW-u{mH?Alb`WQ<#xMQaCuEN0|R2G_=u zwU&$RLGviJSWBp;O-JeY`A{ez*QKxhs*V2K_4yGNEBGhyWfvTgLgljBc|xlO52-c^ zr(X!Z2MT(f{?ZMsjL^l7G|6`%Yl4@@&1}{dqnbQC3%K6TFj_RM#~i3Mv_jRuF~)Hs_xJ_DQolqUItbKjN}@tdE=Lqddd#7FToz9wiSDxS^b zG7?zovtKQ;m*~htf}Y_%>hFr4@kjp{n}B=lolxs;atcPlFV^7{;?yPjcA|6&;ZJf*DsD5>^}}Jplm4^f+vp?!uJ202+z!2b&#y&E32_XgRB8EC_ ziP!1u3oe=2?9dJSjd>9LJfJ=M?m3!XSY`Uwv#F`QZh z<3TsjaMSwkX|_ywiQWKx+GRWdFG~k7V4XT!QX`fU2r9X}$n+bO9`hAn@txBOfz~kl zvt@zjq3LB z1>Ierq~AG%c}Qc&!^*Ao=RM#dRfCO;D99TnLqpXsV{Qz|n8gp|kB{TzFJe)I&YqgjJaZy9@y(J+z!5IK20|S;wHSuf2!^3s5n&$ z&5Tb+pm<_c_XaHq@O)iQmRXWNxLDr;AK43CO)Ji=`P78T5Y$hFz^^8Vh@z&L%%aS% zB14gbpVFCrnem7`qjCA^Qc_KdvE7Nr<4Coimh{pKZ8UTMk7(V0>%?l)EV4cSbQHvV za4HNDEr}KXwNoRNr+QSp|B@k+TT~3hg~~U+brFx zU)24{g z!+b&6>8*sqVQoXyVHURjnS+dAztQt7b&!og-M#!56n4G**^#dLfWVu_{c z`^b;Qf?;`c@-Hn~@o`3{gI3f{$@0;+Eh(aQ?M|l;t!syt^gvsU#;^2ydn`1$)Y?iyrYF5VvGSNEc&lVcd3J>Y&h>ot)^bp}aRaaDOqRUHw*?t=ayVnyLZLa6fk8rh?q4@3x;KAIxTE_zSvRJ(@l ze1RNn1va3v)fq~3)frnhE!rH{w`7olih;rA-@;jp8AS}aW>S1*p<%{DofA6Ng*OZ5 z)wz>Tl%sej%{jqG`*a&M)Xx-UV9R4t!`DID6)p7c1yXP*7Gm3t^<0e;;}xPTH`=0z zC*JBM9>(wr0HaP(ID<_pzOzL6)#y_10iO0VS^9k0WY78nBB$f^`U1lr(rk@S0CHJg zFbkra4iRmTVP>g5frUaKY{86hWE5xoBO+eODBd@RnfJnPu7$8vd;kH0JZ}%)1X^0d z!N35Y0XUc_zWxQobQN{2wVp;vBCZOxjsGQo7(V=BQ*1v+rks|GYU}Nz%}ur%!<}@8 z?$xChagp;;()c}ohM7kqU5^2V#*a)!D(VVHLIv2*A^(DDXPo;Gkn8ABIqY+DoK@&u zwSc~cCUAB;lmhW8<^LJ4XoL`XO=UoQ`;^f2Ddc+SzH6_tpEL3$k2}`Q zO(hTeGc$z#oIEu1S2WSk6eH^9g-&<@K+?F|m#r~8rPx1{tSYLAjk3R1*mzrzv+Q&D z07k9&MAUE7SX{!pM&0eLTOcqHJVt5zRZ_BG^qh$`KJG-ml#M;yiHbSX*V#}m+_&+@ zj)qCNbk;ukGK&b!WZj4OjXEdELg&VlR^wK!azaCFuA`A7aw&{E40LL-s+CINdGd|V z$EY=4OsdIAY@VM@cpNa?W2MyM5(H1X^l0suX72-%d^p!10N#K6S$QL?&KpZO%0Hj_ zvJrMhnE?gUTbEs6xDc5!d9sd)X44NYy@;Y{G*Z(yu2;GJypU5RQTy_9Ld7;!kxS=3B8kYSl#1gxc8p9~$jzRuHy^F%#w{FcZ zSpBqmTshhUo9rn=hF*&8l0n;RLr@VpOtqIJQESh=8FIT~8MeCZ0u+S~m&C!2!Z+Jh zZ`f*_*M9|7k(DovN`aL!tg*7T*p5>zfVV4jk8(XL)pW$-@MQ8l^TJ8Si1T>`dlKxp zILFN=5!mb3BMIVW3_^iD*-@B?M?ga9fZJe^9jq<+Su85w!xq1^END!g`s;rPQfCA7 zfbl<>vzQ~M$lvt!WUDGfiaY1wA@Qhb;OWcjBa%APRz4%nVvinpHo#D#DA_-7rZ2BF z{=%N?=lyZU6&4I20o1!#ZiqJfWNse&HDy?C45bNd4pxB!96>A%#FS zyiJQr&91YKBITfLo_ICEs(UeF1Cv0T(%$T~jCUF)_e(JT?X$SpFW4X8{_c6Y#cq1S7`EHiMTJR>&~{_{k^; z8*bSI6_dnjwo58Qg1g1DMF}riJU{coqK5#Tw(P|`Th7TUv)BhDo;`Qu9fo0`7tx|L zzJ<2X$^`h9SbfnR9bGQc6<%Wu1%>KR)M{%6VsrVgsa-Yr!A2K<8a)tW|IJHuz+SXs!ob2Qo9||?>l_7P&tERb25_?G<8#`;(E>kEt3_-|qOzZ^ z-YKGG;<4I1qQPxM2A3&uhaM%~Hq1qI(ve)M>C7j(_xN-+mVb~9=xq}%s92Qrg5127 z=xkwWlZ0Y3=k>;Ery8T-ANP)zAH-#Cxl+?|BSu?_UH@{4a#$FS16j~~?TJK>=eA@A z{oFyQRg7npd=9f*~o1y+y-!|@#2;WWl_cykuQJxzYsXWNHY5t0<^I30CIpWu&|Jt?$I&b;`|_uU*qjgdeEOpijtROc!65K~9U@X1zMB zXtnA*M9Zc4csRvb3jMnAAFc25eh;eQk5csNI4_~X0LSRGl0qmLsk%^8#nG}O!n&?L zHzdTMbK6N&P_!d!c*Gyi!ttb>$?Q7LP1%>4YGh?ihI9+ziEnwhhIs5`CBSA5A$Ijn zv2GN5iec-Qka4e!qPzS%5CMz1aGxv-MFJ_6V52RIdiq#3WkE~A-GImE5j@R zmoXK`c$1CHVVebM&hjGe^z0mD$Mny#7w{-eS+j?^WzBp;+dkF@!_)k2`=rW4OkF7# zDMr5u5#jES>|T$l`9c3^^*s)i24^C`@>J zG*9L`o(aauJ0Qbi3jEN#lwa3z`GmQvm?MUk%ZM9AaR$YpmAxP%;_T;J%xu8wb!}Of z;qq2v|1Kb>)9M+uIuQSC{il^OAi@-xWp*16-)#J2O@E>zT<8+*6c?%1@orWnC|V1V zd5(heY?)I=6Q)MDSWeZaE;?cGSe*?U8bkw%JSttvhbnt{Q8o= zs!}r4}NlK&U%sYKf&rK4@0vLJw3zm7*(0EG;rv4{}Pb{th%3kp~ z7ZpDA>&4JHhKA|cdt-!183%@9msz6xTq(8da)ywB$5?3K8Ma5!hhy1lK5m8V$(OY7 zyiGUu&;(}3_^BdQXkE{)f*}D3s}XyM7NcZE)xDR)wxX!Ek_l~B0PJmN+}BT?9PlK6 zq@$4)q$~tN<R1cQSiSobY@9Y-L}EoRfeYZPSy=SrAxyyI9KWf6MN&xnN6*A`6%clE;Vw!BWO z`bP5VvKY22>RyA|7E!fM995HsC!B@W5uwd+!+n-;5baZJxt+<_=7JoDkCtWJo1Ar` zzx~AQvAj_i9Z_pIqoXF81&u7$+WSu&VJ_6H{JU+~!zNf(6F9r_x&Fo2#LsC;=|fY; zYA6dj65wG7qFo4i???q62WgvQfL7uo+@9I)jwRy9M90keV%8>WPqs9@Hf-#Ak|OXJ zp6@%Tq_foT85XWlc-z$|zv%}>hv{@Q_z*{37ID;wh*eW39_7G-(2vlrWEgfjQmB#W z8@rPHs;q>&uZyVJRIYxpsWTu)SfR}-XG2vl_$KG^E8cIieu6|wU>#BH!M^)YSnDl4 zGHP@87f{aaJs$K|QA1ge_<(M5lE8*pH(ZM(jb!Y*W$P(^`%HA*P3w!G@+GJAFCre% zBy*Dnc+Q{E3`^?KsyZERE9$xn$V_n8S+a|5R-rJSpReOsUDrU*!eN>01kZDYFst-6 zimlncN%3P9UAmZ&8C{vV$%jB8@84^HgsPNgTM z!^2TB+ywCjFej>N6R%d3V=SY0d8}WXs&&#uHos{`TCaL}I}$GXS}e}kWKtL}cMSi~ z+1OtKnFEA3^5W?62`hZ78VK$n1bSoSn3g*U@oPGI{zaCcVbjBy?66QyU+m={*LaB+ z2T!GK+idY2O|Vq1MPUUowAS1yGERZqkM1bfm!Dd6d~jajHFJu&RD2h!{{9p(szm8T zGINFUdP4$iB8k<;HD0SWv({D&^ z4j3&5F_tu19xin!dsBAIVhsD!v>}74{82C{JaO=-gXHwM>?4T4%Pt4vI&h3AAI-{xT({6Ub&`!E0 zTkWwEaonLC*D1AVLD>9r*Zg5?+zNiwkXc$%eYI90HZDzt3%ovUm2Y$=(oO8?qYeIu zdJtI)t1r4OZ*7l>Xmh{8zWOuu-7AvfrsdFILtp%6dvnY^VF_~6P47Se^hTq- z`Mv7I%>aLs**d4~lSuf&V6$kWs$?7AW;||2F6}P(LnGVw#aig*U9m@Mo1gzwuLb#o zshmAQ)L{8^_QU}KlR=(OB;h$sSO{!+ZSQkDFy_&HeyI1SLH#3j_~XMF1)`@xj_dtN zftUfDI#~`p=MqqS(dOAzj!Q4y^ZR;!QxvmLrx9u9r$L{)uxyE)5&qW4Ui95e$HOT; zg<3;n+wfZ@>2KqS=+Z_40Dt=2Bf-7VxAwF6FC38_wYbVkzwYJ$%x4d&%D;a6Cn^Hl zyvOj5lhl9x@1GZ(u_1cyS580oVQxN3C@ao52w|??=c_YfYsd;EB%xYoHYrAb{3;{> zU^*5EE{72AJRy7@aGR^v6%Ak#)zh!)q|nOwUf{2VsX_VyvCGajAAzwTQ+W~|nQhXLRMbGOoKQe3(T!jDU!=NMTNDwFX+*59^ zx*f>1M_(uH-;o6hQH>aAcAP8lvfYEV!Lgo%}X} zbP{Wwc)$I@&~Q2ExY&sCG_OGPwD8Qq5%0_0TJ4V}d$+Bu@F_BCrxt{9(j|)b|2|b= zG)`63j?*#N%MV3b?7~k)CV%Cwe@yoVK0naO+r@PB+tu52yhwT&JiuT-_%iI9f3+ni zrt5dnPF*?!yN#fawTjpJc~Ns~BWrAr=DVYj`CarN5cf4d0|mgNAV!g7dWe<}KmU^q z!Bq@s+|4>bWSZx2XqRfMrNnf8P49Sr!*x%GcIi&Q|&N0sq_R|Lcc92jpTWcvrW_|KS(y@*nU2 zQwx9yzr3vpEt>1ee;Vh1{mp+|wk6wwaqi&jJN-9b{A)n}^B2YO0e6iqzsUX%!~DBb z|HqB~zYg^O4(=aj{I?n1l3hw{@N38B+nSL3cT+6?h^Fs%I!Ug>rPcS}mbHb6ZprP0 z36ii^{CRH79l|&5ZHZ?^v=30v=ZE6A)c+YS{)~MsQE2)=1NoHj!F!@q1nd9Xk_R?L zKEhBh%Q@fpk$F|JkeDw!acPf%s6qCLKldizS8clezdgwRXkWD$fO-AcajCET+kpQ# z-2N>d|EHyuv!H1&Ls^X4PXG67|2Cn4C6a&>lw9eT7XP=g{f`c1hXHH|j(tf^BL6;P z|KqU!yv(==ue{B#NHmGf_TS^)|8keqpaA0i)FVcH+<#y0zm4R-J?acA5L{s2hu8c5 zk3vIBK8i6!A~jDQCm4TQBux zYmWb4Z99-da*6Byh^q*Y#(-Y+mEH914B!18uKl)A`u!hY4s3egq6-Kr-3;IBH(f8l z9X{Op-^1_Ugj2d}AN%O3)b2IiZN=SvyINxw(`omsN?j;!m~PsCvv9M4V^c1FeGR|A zgYN+JMgP;oIR8e$wGUD@Z_g8d=qvot$gye zOQjH)l3)Ef^t@?OPV8!QhYh;I_FZW4Fg8_p@K%%S$M`MMZMf)3){e^En##_*z{6H^ zwWjXo%S!;b#6gGeGR)R zf$0`&ZPP`qgp1uQPr_~&V3R+@&RxWQ;K)=DN=D)OE+I|g-j3i7HtplyE#Yb!-JcqX zdDur$H(wPs>o%R_ag}hqx<3}Xuj)PeBWHVKboypeit6aY4g#*HxQhX^*Uz?|WuV(w z@w8-aD%V8-tZdokf=Iown&{jc>L6p zNd-wBbQFg=QC)tdzWnGNOHbW}+}pEwlF#>M;vIO;5wi42fwS<#sJPgvhL}ZrVivWt zLWV6l?*~$m4W78d#fvUJP2K77I2@6akrcV6r6A1j@S7nxJ9Hf&Oab`FC_W+14EI@U z1&d|Mxa&lGZ6QSes{()B*60)3i%-LV*TO%$(hgdR9)I!P_a63H)G)D%Sfz6|H|K`k z48rF713wBJoI~K}-^DJ1#l9WW442*Ql$G8mBPrnc0tR~jh8FcE^Zqh3RM5?Urp)mo z%n{6_)2*-1-a~qhg_wEK!TkL}yT)OTKYvAEX-;$_+3foq?Cz||>EhuuS=PNx-y_Jw zAT<;TK{k9xhP`dnf22QsTf;K{#sme-(co%N80)JqTD^tYe1PdT>n**^seA6z`Z^s@ za$_x(oGI;;cBxohvv>5-%dul7i(auO9igv|_(j-B#`f4}Z1IW*5 z%j96!(9Yt+ug%2H%xVxhrY1LiND&&tKyt{-sC5CFaHV>pz+TObhY)X%#!rKMKBs&j2<}v+ zav-d*N>XDDs)S#a!c!Wr(1uP*9z1LmibN|5#vIMa=j^G`F!w@3F44vP+KYahdy=&cd z&w2LQ&))l(T$4*=`dnrC>}P%u8UOD$v|PLCT(jv!=O5>_SF;W|id`POD*p1kzg!Q{ z3Y(`u)L3>NylBF5Sd?`(K_;(VCZCwqpl#N!7v@#&W>ths>;`Q+OyWiV(&LCR^jK5d z(NkEy?-f6b3%`szlv4Yg662P$HG$b*pXd)XQoO*hbBz-S{q9qJ^vc%WToK5~9*_etZ^rQd)R z?5#~WI*hMji#4g+pArJ6bN=hZULd#vfEmzaV=@ZQYU7l=RCP4k_)%=ERUCe<3X7ah z8d0c+|LSqmwcywZhx~PxqEHQHLAsGe2_!jz;5%?i6@NfqdF>qz3xPw=PYmZw+{cq1Cicpk2sBK4sLhgu$5DmYESye!nKR}nlS&f|4wHAuWJu?YYr13 z1C>>E#)>EXS|H0HCQ);0a*faQYVD;YtIW~(B#+r4kA1Pk#yM+K0^~9D?kz_J6CCM1 z60o}Y#0RK;#=LgItQqOOVuMK_Yt6rVic1jnYDAQueFb%Ph9RG(u3W>rLOsTwujXlk zl2*eC?tT^gv7o=ogHV4?ilKrSU*B$|Ils|%WL&YjS@A+JLtZcHVh*kLgLoy(OGdQt zqEE^=(znlgki^9s(yj{o;TM77Em>#j0d|emtw6go|E|x;kJ4X?;emRoU{fRQPG0(R zG)2$JzZYtxhMg7*7L`MxMZx`0r z*>b5+EW{ayY*KmR-XKCI5PR>BxXs=KVxIh04o7d=fM9${OH9>EHDk6Vbfsk{yLt1X z0*!vzVUem=iSk|J&CObZfK3{{pP`(ENZNtaQFJ;cn2Gca* zS76#u%$Ks<5Wif+;GFq}0?hixWe(W(X_In4!_~){5LdUE_TM`qA6-&pjiDVi@{&kH z&e}c#D4e8YVLsqE?4o@!UA%Nj{lv({m>R{={9Optd#HSeXKhiS(rh6?A8DxhD2zn; ziJC}iN6BI8)LbQHM?cPxU5;Tm{c4GpI=pnvbvilTHWjt6oHpUSUxI zj4UNjQp$_*s=ZqGjaS7Bc1C@E=a5ck(S-=^;u&3V*Z= zU}sfsQbZKj#4C(iR}3&?y5ji7(&TN={M*h1F^U$evE#utvhd5k%Ehj8j0+dO7g`Zd zS4Vn@S&kqSH)h$+-!%+F0a6{Zk4!-_e*av=srLaYr36T?h~-F zeD%|ipe#TYDK_N0)m$?KSc0Ed2X=ZMfs$??S9ooa3B%6xO(cnjsnE#Bk zi6Y+qqfSpM1_YiqNJsP#;Bns)+asf{<+XubL)e?lqVkwf-Zz{y^s<2XsJGzGbyw=~ z-xvfDT9uHc+#Fv1H(%N4U}M7GzW&XQX6-9J5bhy2A@}n=COnz*V%5TkM<6~YC1UJM zK^DEMI{e?50N$Bf|0Dk&2f-gl4%^`1$fixdf}7vdn65Z&ADCBDzoO?qzY3i?n2Q zc1T*ns5Fa&9<;y7Rm@X-8A?Y0Onci8lj1qZ)iiBLVkfW3BEZIQ`p%Gw2r=E4zvet4>k#8UX%Hp$0o?Y6^P0kd zJ!{%7^vmgOT9?I0oM#8Ge<{m$J0UoRAIlE9P%j`lpH!C|hMQt=U%9CR3+?X94jIn2 z0D5lE(Y)-UHe!L7dD{a*5RAwPz^?5<3rRQok=w^BYdS-z3qF-=(W9s|M}@i_><|;> zW=xm?Hi6*lb9R7Y`=6t?WdaM@a8YZs$v?j!w~+$MUQ6>biwnq*(^6nNJ7Uz34n1^@@o$hxd(Uqs;>_3dfcfT}7vC^Acu6`27o%~#Q zRn=}hik&7!94u|DDh}rL#NuB8tkQ8eh&J*m7kkqK-*(3Nqelp zns?27-8@?k*R1W;1M&y3AkUUPTu*)t#>^621DUlD;QK5W8O24is6X z;+9V&bm19=AbnBk@3&$^LpHwn=N`0rXxBRafd{gVJcv*9wftoC$6R0iL)M+nDo>~a zcH{UDmd{w)WInKLGl~V0essu&lXN97_-XKJ{<7!T)-?{A$;`F!37Y+!i}r^ZG|}v> z#4adJ81^K6r}9B4r9S^)#Nl!?2Zq>z$7BUo{QsNPMm_Jc!WyJgxT5K+3)QDWsAt*M zvZC@2hXP)*_j)yaXWJ4Ck}eV(e7_)0TVtkD_9v8JO6Hl&Mn7K+@c!$NP}4`*5VyIy z+PAJ<;G8}&x`Z~0oq==J>B0>E3U}V??2%lQYWcBE6V5QPw>nhwt!epRhNwPM1 zc{OQ@L!4~l#6*T2c(GiNZlNU#4M|d}^Y6(y?Hw^0Y%ch2oB+5PLG3VuxKv132L?yuK`E zwIlB*xFvOoW=2{JnB~e9NSssv#^}@_4I$dgc*l=@dYFFN!#k*6{w{4zs9$%z!kgn} z;6|J|ip;gVq5A1)>yH}dT_k?hg?mI;NWQk8C|K>DuU~Mx%_{>kU!)YbtPDx<#-l;z z>e146Z_Aa8*BdilX~qa7efaoz?bEEqT5c21UE;aUgA!_p^Y9$&fy_ba=@Vu@=c_UF zsji|6a_qIx7vWyPpQ&ixF?V8a=Z-=p4&+uoC=kq>Cz-XgMF@f%&8l~a?l^z>CfuIJ zYobj}8Kk{H;Oz}XuzxgsMIBEdP#n>yAIWt5vH9=S8YRucah3#75(0|P#b@VqG&oX6 zayw46j3|jpvAjvfubEJc6KD53saK94Q}d2E=}OA^tUD^puLk>qkZV4{$Z)D!J~odZ zR?Qi`$VyR%Yr@9sIF=uED0Q#_lsj3P?cel~gAn<~Xkh$>EA zYxqBZ{rD}nbC+{xsyLIL&F++R?~?i<3%v37`m=CS_230ray{4Hyz1zsV4I^TP6;u0 zuN9&Br=Z7&KzI;5tV>~y%APBA*)j;`>4;B85M!oEooKD_*13BP=C8OM(PQW5`{xI@7c|C-JdA1?83Bc4*VUQQ{Kbp=jB zqOV~``lv(>a}(+rMgz-oPd+Rv^n83U+w$aSTUG{4%QypHI8!=*-(}ieM;fCLY6BLk zOWw?T%KX)8QVSvO?Q1r|8-xJ3d~0ohO53a3Co<`niXu}|Z=ZN9iqj6tUxpmBli#px z1+6Uf5813gXe840_-t2l06i}krJa>TG9Z5cHPpP@9I#HqV#lsj!&oK3Ybj~;pbs9v7rnP%qy=!S7h^VRK4y1Z7mOxyt>@if0hR7Zx1msac5O=-{j zf2}1URyuu>cE=ypQpa{wf0aLeiXL85;8)E3po?rvGrnh;lL?QTIi?Qq6se&`6@o;> z2mCJhIQjqXcG=jAbej*w^Q3l+QTMuJ;q(w+?OshuXNbA|3x;=Oqye*N$n&qbMt5Rv zjDweFbKAHdUkM58(9CT6Zv;{{PG-ET07+Z_o;x0HKRDhI4F~x-_!~wKsom?EOqCqI zu^fKnvhk}i?G0@F7-RU#qC1Fj+q~f_T>r}(j^cG27W*P;w;Wi^9~U@0%3(auy}RZQ zQ{$P~;fKVsWJ>t`W4oQ{lvZNQtbt=?Wn#|sI)(w&dHMQ z>*Pn7&@-9mbhN(blO)t~)BV}{PKo|@tkZamm-QlJ(=iKdKn&^^=cd0Lo7wbXHw^Ka z$YiTp;vGEYp3gtwpquO5+(6(=5;7cGW`X!4R^$3S2#}>i%x~Dp@Z4$M1`j06Ic3WZ-Ox zzSO&FSf{E|^mH&RSrZ4Z|O-IdlWH{lLQ&zR}}iGYMB zGV09H3gNId-A^){cKfjEo?@OI4WX~f#uTaY1+!?6LM447*zOfq#L-zE%A^o%Lf)V{;6fLHTEi2l>U{x|*p_wJuvg=t5}Co>C?wo34j z!%N`|R9nMuE|YJFzSds+TRO?zZ?cz1+k{iE92SUm*_VFDSxzJzw|eD&glN;ii|ayz z=8r3bc%w&mL#+nYPq7z#-f#{_I1JOK3`f-K#u-GpW%|DMdvaf$ghI5>z=QweUihn% ztopR|rkfaqtQR#7+RBuNe)k0)Wkf=+9lcVkh}(5Qv;Q>5WYSq*SL+kW{&|}+yj}suDuYUE7oc;kp;m8oE@O+(8Qm(`o7`Slq?kp zM&DZIBQkx*h3FXa@aV+G_}>Fo zcs`{S92Afw?~crz0bTO*q16Ky`gppMz^EK$6*qg`jSE_sF&@L2A7pLF*-wt=47{n3 zx^We|;6H!mx~KRp@M-wRExK@CK>Sz3IX2gaWjMrTPVC})e{_#bMz}=8(0hRg19-ln z@{o4yOit4y*K==m1*wTAI|DDh0qQ5K!-$-fmgIHgef+UOa!)sxt16$gt(N5I&^1Z9 z-0=)m-@9yxLt<(jUgDh~>dTPrGg7fY;o?Rm<4k4xIT3yPHRE)QEk1`;@7bBHtpKO} z3cQ*6@EE;Az{NT7^-p2;e$fvaLsD|X8S1ObVNUu4=|z3s;q_A8&mhN@B@1y4Do(f>1B2u2* z=~sL#7-v ztaaSz7d$p{RiF1peY-|Ri3D&v)q^DyN@0 zL+$*?S-y^SHhy;Pza0w(2&XQ-W)$x8Nj#r@DZN;h8;p{;1}1Sm);Y3H)1DkczdDma zJC-z`RDS4u7BJ8e5=MokF;8y)S2GDAwMu*{1C)Y$?c!W3vv?zUxSbya_z2hDC=(l- z0?mLjps!rT)4QhEE|dZ90EA7E2lI|+Hi2}?ygOmwdw(XP?gFmsfzQ^Z)3`_aLS*85f~$MVN!xo1|ZkWRpz zjr52X--3OK@AX)&+kd9tm4O>__|!*w2PjDwn_VbWJ*ZO zUQ>iN)sK^-gv2OIHqdO?x*@WvSjkYgF?C7nasm^=QK>XeM|QFeSc#+?k2_{CSNPAubg|Nq@$3RJJww_ z?!TB=j<-HNRxU-xjTjGNSfyjCL7d$Y{si&NE>#DcKvu}vSJByvgj0=p{SLzu^0M(+ zEjGBRX2LoHnj_s+&*Dv)p3G}o3l^pxqEy*kJC4#RZEL}ed;=FsKKfq^tD||Gvk}?& zmdhe%ya$i^Y4HDJat^P)bfw)V=Q|AHwfZeGzqFg2%Nnei-{D?+SZs>qgr8$H{ zv#yBl1&y>o<>CgaAt}?} zmU)acJztY<{O9|YPqbN&ab^Fw(Q*U;aWsmI&*;5owMQ6}&QFCMKo z=q?-Y^RlE=kfo-la_JVm5WbmJxi!&=v>-^**`p#v?_yX`SpL9`%FjI5B1|BJ{`OaJX=Dq?r_+)sQp$1xz5tHFc*WkWGq=xy|0wSul&vgK+j8c ztM0!7J-9YTNRFS(bF=Jhz;Iy17j@UA6OA>E?w?9ESJfDV{5Z8r{i>>Fak`K~XFuCX zM$MHL=d0T=pRnsgfyB?Kurz4>87Sld2%~XsdSSmB0L7b>nQySjQv6-V)!Uv(Ko#_I zutekgu`g?-8cbL1s3-hCXO$iAvU&Mh#qSw$;q%wJQ&uVkP%2{o0R{VG##A6D;%dWH zT$81aX`*=Wl|4_l$Biz#Lsc0HGdZJfk#B!;@?JRhjz|z@z6M%5hT5Z+Q>K}|?&$*o zJ7-%rGraU=CrrATM{2o^bh&*+r~e>;Uai4KG25Xe>5;o?U(uRk#ot>$YMxm&N~Esu zWb!=3ppY4++cErI*#5?9GEAz^@U#VowdZzTqmVG8Y$vSZYS61NeckmorQNYKw`;bWU6I~Vsbu5nm(xU z>%3(9P7c&3TIqLYQD;x`5D%nNu18cOBokGlOQ{6Dsi{^DG@XAIf>yTwN`1xX`6Jw*hafR(W5h0 z<}|2@pR4)WZ*0M!ADJ*6hTdlCPf>x84yW5@^Rs>BHA_*N&VD~1qFsqj;w>@?K0WF+ zIsUQ(E)C)7hOs)ke%Ysp@Gec(WnoujHOd4>a-lc9tz)VEU-D6OosvZA2h-s`yZy|l z_pu#%N0D_bdPL)`CwWayjQ&mLFnR@%U8_0_YQg9LU1;bLjaiF?8))T;4-4`8e-6o*p26xK?I2&wLB2uF@fI&# zykNa%L>uNsZz^QIC76_HuAU40bt@6TqOr@(l+o*x1$CfS&=%J-VL4ML%uc2s8n7@5 zGr%j6+#W=F+Ld$-p^-^L!fp3y-u*h(=2f`g95B6)YU{U^J>^{OluQ*Qiqz z)zqQVc=wt)hbe)loMB7gF4tfB&fb+HI0^lYNI$mLkfG>z6UC*VXo?-W5XDAR3}eT7 z%UJ$kEKb|sl5~R;WJPlt!BotOF1t2AKdrRbq!?=wMz8WPB_AkvZ z#twfcfS+QsJhFpZDA(tY#8E|XaJTDaQ7k1t;1z~DB7r`45 zZanuM&paPJ=F6|Zd!EM*-uc3*L2a_15F3U{;)rRMz(2ghW@?g)KR5_7`F0m!Ex% z+g}&di{Uh9JImY;f_t5%h$7Tw>3htQ8 zEXP+%^J|df1ub22^WgoK`GzAoyTRzl`H9dQz(R8 zQJKD&!>Mr6Dw0;-8_UOkRgf|`Z{};3DPcF00xIW?5Km3{E(=P4VxbSnN}j+?Up_ZY zjQRkKPo$HHO$k>Vq>DdO0cde`xUKN9_GKN>E@e&Hx3hGftqbeCjE#God?`4iAii|hEzp*UKl4JTCBSs-{2{oK6Aioq8aQ0=mAz6Z zHEA*}m7?70bKsEXruVg>OkJ%?Gxn270X zd%IwvK`B)U*_=w;txm-jIxv0G)V}+PQ$xPgAZn_bc4PCb zYpO$;g|F#**j1WraMmKi9Vp2`Zs6{peoweR-mNcfq$ZTR->n^%wBOuHvT&GK3%;ln z`x|ue;`m5|)vMCnOyh;dCZ%|4kNNDXm4n*wPk+^v!c(U9W&R7mL#iL)g+?gi{j%a= z$5No&!G-QVSy%|#$r>XIJt%Qr3PTDfZg~_BlafAVNr-YKOQ2j|M3eD};t0-TWB3ppR4^R?Nuh)X~0$`&zFBt*JD+hg7fB=;lp{JZq^ zkP-X7kk!dc^CjJ)x(0McUiLNP4nC5W`-((DF?lkm8ESMPTjXat$GiwtIm$fkYCP>R#g=rmsR-HLiNWK&Rd2%H9xM!b>2;Rfd#j!>3 zH=v33tIkQ;*ha80onSlJQiDsC7zEXfg*kf(DeZ+QA$P zChPte9;R9K$cQ?7-nu0Sdo#rkcCQhBhj-dN6*KU6j&05S+A&&5XR5k!&g48v&4XCV zKACh4Q?P!Q0mMB1R#UTI@3lcX{#7wD_C%2IG2jZ^IIp3h5aT|2WriC;0Dtn%z{IT4JH)Hk&+CO|qsIHROb2(|aVZy76a*Ddk06i5%N;J0kEIou9uD`Ir&9x9K3(9jcwI7L7oyjc72>fSy&u31> zcfCdhyIBxaKycpV%OH4KbATbku2V94PBcY4_rjfVnvNsPX2F!mIOz+2^M-$;b!T>p zdAO&Vdc~6p66WIfz6Li;3cHT|LcNzVh)DlbVNz66*1!D~RQo6awYm~?mi*AQS!dLP z_xf4vQwikP@i!|`R@u~_zFg6Z&uEgMHGB=?52Jn$8SZb1R~v6Nh#Q8n%zFFLgGJ|W z8k%$_inouIwl9oMd#Zz+LZUJWz?-SQhMr*ye025hV`J$3S)(#0TJ+JSMZu5{`B$nK z_k>L#Gbn|BmzKoAU6cc8cF?<=529B0*(IGQ9wUk5|B+;(!RAmHHk?_$`d0hmrJPo4 zLa$#9s$*v6Uc5fqEuvpRGg`OQZjb_0L9(uQr40jn$AY=HS}r+u@tRH)$yRwM2>Cwh z^#?p}%`1n#9l90sx6?n{TwVgDz59_HZn|Cf60#C!g4aPGLV5RCy*1?Tp5*H^GSBzh zgmi?p6GQ02f}fKpyJc$DZAmD{n#{nfh@ew%^+N^(9ObNDcj`CGM*j34#EtI7rU_Pf z;DWW=d}83P1bwHmwrE1Ir84FS0>qgb7 zzgO7FWKI7gUj1D5zR}xPa^5yC`*h~((y{}5=w%z)*w?iSU)QZnJFMWwlwsJ{87OC>bMIoby8{~MALKHuoTJ1Q%8V2uj zAv%3gsdsjl>fhiTsk*O{$iyc~Z$Ajf5HEQ6x%g%TS4qk6Dkl(|yN*ZkygKS3=#P1} zuZJbDd^!h4NfYr{jyKc1B2c@k{v&>orr!r=I0R5t#!)vUL}<9ODkH%5k!))L zqsV3*@x$p$clYe5{cNhc z&oOsPUC`7g&{=7t;=fvHgE{;eGq1WAeKmANcFbYjBxE0$`%*K~iKFB|je^31l5bfU#PRN@j!>!>?t__x%NA&ro}FV-yDK@EfJ#hykK^(Y)OXsPEYiJSIUFXX zGdv_{T((9*2AA5c5GlH)4rnyWNbR(n6mF+oqrmmG3oZ^Kc}Ya4Ob=yiw4 zdxT#%6WH%WCKP6Oz377Hw2f!2vTuqFwERoNBVW`Eayw|$Tj9D}5|2Bp<4dJ3Je1!o zr(1m0#-gNX`t1X#Py0SjoJYohe!1*Lwz4+$-X`J7!Ykl6cBJaJ#I&bQ#4cuK8*Nc%=Ynq_Ke*<3XLaBzP8Mg-5Pm07pC>mo?LLUbB4hjx~lZijTge|mJ6A`Y#X^!i2cC{%E@3%s)pe^Uidm8_EG|ONWBJsd?V8?S;*E`8bRd)t zi>brvyz(#TC80E}ba#;|yZ#GprVEipEcR=2x1r^84x=wTvsqAygJp6sLs79*oMSUhtcCC;Oe*a4QVPw>5 z@OYXiP;sv)1K%~+rji3HB%zUmUI{ml|7i}nhVJlPn zcS#yg7Kqg?r5P{LbC0A_T(P8~ndhRa_CiT9hQmaj z^NKU8e~5uoFv4QomsW9_079H4KBMA#s-0>Q3TNi6R<+ncPv6LrLrj=Tf6KqY;tneK zdFf@?NcT7$zE)ZobGNRA*TGeJDjii5zcH##I4JeBe9&S|)m6M~mnbkN1cy`ZC8VIv z8wypfY{sAGWNAk-u7o+uUC9B0??YoJlt8PuBFQbblY>jLg9cJ~68HUKLCkN}=>={1q z#q<~oJ*(tng4H5RC`^-p9E2$p^IRa9%*ksGI4FLcO(R`wx9tj>j+W>(-9l;`uF zvoR-ZsC6~jjWDzW!twg#m+PeepR$_pzW`Rx4546cnl6atG~YLnY`!C~Fh(raMhHT0 zE@lfhS>~WqtA(g32gz$<*Vt}MG?+J8qXees)`E0yY)iclm}67q2xhshcxz@}>A5!k zDJ#(E+qG<@6CMotFmW;FLGT*HG8!hBx9-H>X8gI9_5R5!y((`MEA?LjcQ$Il&Cqx; zO2ipmxlYt%^L6c8E+5m7my3FXId4CYPUZC|I9vT7T~0V}tXdrdXq?5vA1F3EkndSKAXT?6d7<#J8z-dS74cX(% zA48)}^ElW}5Cbdq-tK9KYk8Y2ltqDBwUI-w6@H)e2Lf`fXBy8V9iA5Qm2{euT>|+= zyw@pw#Eoz}Qf+hChVA*HC%Os=6#U8cK zQ8mGKf=LJQ?%6Z_{qX&0>7oIdN#S}5``)R2 zPL%_9}hfw_8Gf@QxTMw_H z+5JHNhZk#|VAdJ1*UZw=eAhArw|%*0gdy1FHsRJ(*@!=!CjCkQ3KuE8z#xD< zGCs$WcXP~L3b96Xo8m9Gc3|kYdhJx&9EXn2=x;>5$+x&@mVpsJ1MPtuG5PaOkts-3 zEN?I=<@;=w5|XpBya&P3R1cK2?sehaZfzqCpXSp9|0!8o#0;emLxJ^K$o#cvAHe#m zSNZE`&47e+8*o+1t&l)fT(^sF%9;)U=Em)WGBH`30M>CZndcgXSqX2T!R&_fueXA? z5$55CFS;>gHhxC|czAb! z&*Bd0!OAEhwLSir_Kp?Z>^M${Un$gLL{tTS12jKlcEGr6PC|FC@&V7zFWOej3(m>b zYJ^EnmB$_k`d9L3F+$FKI@%Wq_CclsaWwIfJy9SO%dSL9+@s_jH!3B*u4c}TW`%o`g&^+nMRbYzInlUn1^BLQ+<4ONRe(b9eM zi_3ABb*i;)sLzTNRDDQ~Gpoez^?xxBu%fLWz*+^k2C^Vjn+y6JY265+$9zOZ z>})$z%I~Tj|Me)m%sFM2bpBQ9=fX1vQjax6a{bVn0 zuYm6$LC63svONLBPimvigm7|bMo%Bl`2MxE9hqH(JR+EiO^Da-$1S?r97_C4`3H9- z0I1*{tasfU@WclaB2az!OAi-+*HvP-{D$_-Rwmi(M;}x(6`yCeIkc}1mC);APr@yg zM4yAF%tliVi~-aw#^osf5-i((!qABYU6eR}gelO@QTe3u}|v z@5+sb(HduCsndQu-Pty6Q4Kloy8KVq6G%K@#``wwPYKxjllo;!e`jO|+q1%`)W0d# zT6Aw`=vVw_^Eumwhjj~0ku!~O>UmgOtsk9WP?2#qO^Sin31huV{XP%QCJZKHcNC6C z1rFT(Prfb3P04ad5bL)YjPOp5{3P~TZsU#^kZJz!>DW@V7-pIM_KRW((@X6htc8QW z!!c6tb%BYLg_AIK?$noO{2#~DPyDUppO;Pw@5h~&Dzc*740yXKcK{~)N}GO=Nwem? zw)2YFW7k2-FvaM{c)1fmfa={ zF{UaS{A&~%f~&V^&Q zmG4lek2M+8Hbk7r?f)rqlDy}hgL+FZNU1m=S|&!{+;n2_e5yErl%;s=i9{H{&U#bS zVo^4HkHJ%Vq3eLLF}Z7X#Mi(g>`*yT#VI7LpOafu?bW% zRNxF82Tr}d99Lv>7TQZ1e9O;CG*Y7Tlx5{zf4mOSQ1!L)k%w_5c@E;k?kBeeQ=}d# zN$B#vQF0Qf)ACAb=N2oK9rnDwsJTr8Ksr7wk21)1`htS62b}PwxWdng93-J)B7IYk z`x=6T?STc~s_${A)zB3lEtRoOJL=>*DQ#y(0eMWomHdvaUKt=kwD-`0ieAvsvyI0?wCcv*!@~@Boaqjd zgX+_=lFHFcB+5k^dkQWjlXueGoTMKm^Z>Tcm1`mJiGfkn#a(Ceqa#-QO=;fEAKyhh z>+^DW6W*7E5v^fO@?NRKx{fZW?<$3l%WKx&8^r$YD>0$pjwb)w$mUv`L~J=zUw}I@ zF|JUOWOt^-zZ5n6MJ@fA{cnm#tzJJbQws{tjrP3G}N0HXiaMWF&tFx{8{N3fOko17$bI1!e2e1Kg1djDuLHm_*F zAdGASn1>vq?Ql|d3aFcKLvj7pztsZ6F@piEhvoI3Fi}g&hBd(As^ciq(SfOp3QJ-+ zFJ3xAOxW`8bk=5$dJr`wNn1%Wi}K&331t~mrx@OBI@*sh++5EzS*|wuWKdt2;L7LQ z&IN^eIT3nz8lbirA25+vp)ZN+#@uVJD5Py@q_0h=ua|=WKLeec-ii!T>HW@gh@OcV zY2A-;`q|%8g<#_~PXa5GH}T7G>D|US#cg)Im#n{LutY2QyVS>W#FZ?64Bq5PR=-iP z|1;W+n?yt1URrBQ*FWGR-pHKdtx^%Z;#<*LCj9WC##kIrf~VF_m!z^kPqQRHId?sirIopi+UEOmNe-x#tbCtS(dt4#8XEv810pVYYv z5^DC>>}_^0^Qx|&_*v4(eh#8-a*Iwo|I@7AA^Ab1GidEWGcB@v2sGPKz0U4jEkOTs zPkC@ia?p)4JRfaxa@7oi1kMFUlBM{$guwiEmtDc8B1D0;YMT_6|-$4+UvvA zH$=#QsEOpDvNsK*2b~i>omGDeF9uWOIvS||X{^RO)d2D@jed(#=&@s3QA>|s3&m|6 zwXDWi!p8Ip?9+k#@t3q2g7+w40n~ewku8cIS$v;9c`ViP?I#-ZqlaV#lerOHLXo_l z@s!gDO}kJdj}O0vT{ZeHzWtmF{#UcLbn)@T!x{`Zl4{<1fgV`V>v)0yx;kBIF#dc8 zyKrTq90-tbskT&>=NSEKR$H5rosK;@#3smq72#i%jao<#GzD4#`!B0zs?c zFp1J_jP~k>K$qv9a ziK@+1t3C>~uH#!N|A#lhahR$OF^H`R{&Tp?GTF)Ufhw{wVqQuJ{T`1zHWe2spmF(* zkn@xYVsyJ?JIEpM%2dF69|N^F8~7r!Vy50S;3QmC1*Nza(<#6Ps3cyIijI<{J|dKL ze%0%U80nSu*ue?|(^>`X_RGv;8C*C9H9hZ96DoN2YgU7#47MRdG$+kb#dec%a7;f5 zgxi{dMS%Kj1POD}J?VHGPe;lx1OM|g4PN{Pxj26f0xheZV(~hF+w1XO$_WVohUDzD zt>9J}WCsLKwqzsbefe`EuXm_H{mN>0R(U%&J^;EXRn-K77d$;d`}g&pt?OxZ22l%_ zLV60&1~J#$$b7o)x=_NeQX*LVw5smZMDL!&ID3r6(`Dgs%LPClu5t|T)%n+)qXNt; z+*XzO$&v!y6OT>YPQxEeLWI#XKQ20tJ0pVa$?65^gKBeB6N=7%o(zbF`BteNqw9{` ztX0j&l}1N??cadqCkc5hMlAmoPGve8c`sC7*`2iJi; zsx`RDY)UcCSZKfPv=$%imzx=;b%P^D`2;p|Jc}u8?}b*;MU*Nv!H3Gu7W^!fPTr8V zkJ-$K1Xp{2;;1cKu_$ngwsTJtlr`>i&BLyxNiixLklm36ioG&rU-=l90)Fz8{d98C zylwF0YBD_R)><)@$gcxO>gy0)WSo0oFF|45ffhJDOrdnc02_vZ( z89Z8lAFVS}tDK_s4Oo#y&?7kgO#^hwW+%!Vs80_GMRBP+l}M@W=Le!*6`Vk?f2#OX z=vjk9i9C{vn4_QMsd5!N{soLB&$Z2;HDU^^s0JWZIrPL;B*Gg{*7#P7s1jX1g$|OO*siZi zS^BZk6PeO#*x}Xd&0f&eEoU`7Uu?%XuKah7F_DCi@X6_4_k8xJ*WUv36`L-^ntok+ zp-nMoc8_ggiBcM^xP=#=d11V{XmZ;});iQSon}j#18ml|g~_g1^t> zoCd4PbDhk6MYghW-}6)E_J&cx2y@RngG`d>kUh@Ok4J3E{twILHL_M4q*R4s(iT}g zc&Y{odM^*G5=JrzUZ+PUAz^a-&y2(Dx+&~89>+RA(RT%t-o9Mbi;E~P>6i{>wgibP z6$4n>j27kUf$H?iQksuBKq{E(_-$%sz9`;2Ipbuu{2&YW1>ES{Xt06DAesuI(x78`9;L9 z!Ag8QH3KM-Mgp6r+CM@)hUG_RrK_h;md&|@aEp=NUM#H}k6hWSHk6hCq#JBU%$y~Z zPO4f3!^w7f9{P&}m9)4xLPJ0wIt92DHP(L?(Oi?dk?0dsmhr0=t0qzLg&lz0>g=f# z#3M(BJTXeMddaztUVQ|*ONv8IV7E6(Fh}tCY3KEsk$Nh@I*MEt;=PWCo#GsW^7EI?3tZVak_wIGK#{~H`l{zyqUd5WG{dw^=%*X3y z82!KA&NHmZY}?}ss30vAA#~|QT2MfG?@d4;fYi{-AWZ@SQbLa)AVo@$u7EV@ARR&n z=>`ZLq(~J*)f?uV8E59s+~=GxH{agpN!EV%T6^zz=iO`lfBnyNgfS~8J7x2G8IJ_;z{6nq+IL3_K?mbPs@r$lejZleKhXJSSzA~P%UP0pMCC;cRo;pB#%CKec#79iHmK2O2-ECOdzBD(pYzi8#y%^QIZLR%D$8iNv#% z@XZ^P37j&PvNF; zkr$W3!n+el3p%4FAKrvM*>%_>yVc{{ka^C4)Q7p9h=(*-zGk|H%0F$paYu-ej3`nM zKiehR8JKfLdC_nFiTFevxajQVR6&}B;9inG?lQhm?yLi;@lD;?k(2(@U{QHRnP$8bc4Xt^?F8=;a4>@BL`z#dVkxtPC2?XI}C*Dzb3k-BmMw(frQr<=kt+ZDeip!~fb1vX;vccaINr)F+Y-RV@= zDY;+~fajWJM5v8*H98I|h_AinqF$y|%nDuChl#Gdtk~_UX0lD1%-y4n)`lzG{+Np5 z3eSv~|Dpg{Uy`=HKZuqO3e2mf5~`dYhT(~ie;x>F5{Z4K_*sDpw_=Eu9Llfrz}yx2 z7OS)(rfL}FQeVr{q||d*9VWgYwu7;eF_*^~Mm3<ule8GZ(eTy5fE@f5M$4k&FPoz?kYFFHRzL3`$ zgp8d@`eEKg-QmA+K{lYip!q{dEE>m+tJn0_8iAa9DL{o8j53Wo0G{jGIhQNf<5T2a z&>3(}7_}_Ni@*i7?un4{a+5KR?67!$P|-w+4csDB;K;eJySky?V$}@>k9||BdJ3mP z;al;m-~31!K#(m+wV*4jB2}K}#!B_dHw$?fvZq^r_15tkuy(a^(|ga7J}&jejqaNt zLqTgAbkXuLm)rg<&$Sd_1v6SjHq6K`N|2-#$Tw60zTsnxKNkKWs-}61u?SFQ{kw|E95wE5`h*g z^Zduh;Q3#7ZLbTc%Y1utjre55Z39E9(f6n%W-(pYYu%K?iZTpD;ky1E)AA$ZaWY11 ztK_|S@inF!yFK8T5h^P>md@f$tJiM~&<)4| zAGaA@rllQaa1}f49IYmS0Qo-_ZNvAkhF8PmprMIO*%9>ui-ev}7}X-&a-8?J@x2#( z-w0f!yWJR`QHBn-Q8+Mi=F!U2A573j`$JUEYMQ(OST;O?Nem%m+^UU)mBy;2yEx z_`-1N%K7c-Qko&x+0Dl6z@epi1R&(Eu&qNytWEVc*V3N>P33rbcP7r-BH`Di7tRJ|8@iCDPI76 zhon+--u&29UV4a6%&}{Vm;7fmjKkU-TtS!terct_jye87*p~ z(*>!w7y@P)@JC`-U9@C^IJ=F5>XWv5IBYtj6YmCa>UrS@`5@oqleRIH?}Qa>TLknW zc(qJk4nN;mJD-qP}yqf3>whui5XhgSMBHcfas5lGEQaJ$g20+U>)L$ zJIz-*o|QuA^v#4hgXTLOh7$yxvww-=Mm*)`18jO229(j)vVBhPH}Y1~9Fu1_uwQoD z%(WNOn}=o{=DB2OB;s8sbi@`0$-J)rx{_YfU>~LXsE)B;n{datl8S#V6DE6CFm_{R zC{ec?F5W4=A*q$1u@%oz9Ogl;k6K9)_uFlFfV6ovD_QK<3DG0re~I*oay&THYt&22 zJ2vSN0F7z|_V3)uVx!FL=Oh?NlYAKt`Oc7FU7$8qSYlHxrNQh^b)ehqI1|j#0^S)p zWD_i&$vxN==ZI-H76KS^$?);mtHqC+*srRk>oA584(nqoeA%vc@Y0ZDs~Nr32tU)@ zF9x7q}DSCJf%n>%qOHh(_9=;%2bK&(ox7}uY_I=+|cB?7+Cu-$03%RG7 z-kN0ec2T;ScLaVYpKD*&dEdEE`i@cm!|?dY$m9u~d@m$#r;J_Fo6nbPFu}u<+dOac=qd2*#{Cs)o_Z(X~IkdkIu>kyS5VoZKOwXXj25KfIk~b8k9N zts4T0srN*4PqGp$ukRd&)~GV7BhPf>GPjPHq~QH{&o<)Hr(bVL?Kn^ydw$os zUqn5mp@8wE*5PS^SHO0v0zyp?6v`Al1>iV|ucmLxD=mC?ZLO$7H0Ppx$S|!2BGmBe z>60SqxubwY+5A%K-PCsPp`?~=6``IC_Rzt4j5=B;Gp+*tTB_FS_10ebxJ2Pf*GEah z0(Mlmkor;V)B+?-Nhme0){YxT$5VhH>FIoW4ryhx>JX*YNfAVn1M=3GJax)(iC$qQ zQj+5$N726ptSpp}_HIZy5=T3ZuuGm3VH|Xuqa0dPDKkp23AemyhOEgQsA?N)%+v^Kkl=Y& z6vJsGWf|gAc(QDfHUPsEiXRnrA3b~PxX_yc(ogtg}i{0zo)oVj^RTYSrNt?Z>w)lWQ$>s^KN_>+T)-f5XrA8K@0VUH0(G&k;D zq>A08q55oCwk*EB1P*p}(Wv+?y&EU%k>HB5ap~Wu55!^6)8_X0G-?l#7S~a3@if+& zXjv0-JpmcaFjDFBs;B4Z>1cdQw1fQ6FU!?{RH#w!Fn zHwDQjUBI48UuYF5?+`OfvMgScS@~ein32-nmxw7s>q=5^mkD6Xe|i4!Kr#xWu@2>4 z&W!MO(FPY<`gR5GxKi~%Pc1Ko&Q|Ax&PVZdP5rE{hUXin=YtGigTt-4`)XtGs4g*B zU#^X>9<{#rcWX*P^)Xw>OOlz~b91g3s5v}uT-i9-r5szwKt-B|E6;easXcr84P_7n z|M%E+b*8O$;e#&1pa;>L^S-oF5?vq=XY~`#HKeQ*Mv3zd>IR6R3 zLeTRS?3p(R7>#r1DXa;UYbbr%7vX1R9Lq^OU!@2=1IRIl10ObUWAm?;dPLn0tp&dP zV92r^ST=)lVi`7P5Hi}d2fqEMCqkDM+5Y}K)fjByO=MRkMi12#*dX0ScE_Ql?qo6_ z!%=x-5&^YwZ0Y9inz|GhYSl0vV+Rb>C13(#sPjt%$^WhsO_45pW7iIbbaBZ zNvC71$Mo*Oq8NuiHOuKjQWR2A+7LuFVz=ktkEK90Y-af6@I`%N#}?HbPnM7=?u9tL zZ|HU}647|7+HF!@7~tX~Mg?j1Mi}|WK}&0TtDA>A*S)2?QgP?i^RBKvM!hjwmq>P?Ee7n; zo-vT|TSpG-nK#|Ze!Uo_j;+IruEt+}jpkmX$ckDA4T`)Z+cFhb5y^GOk(T17SMN1! zm<%^UsC7y`3xC7oVpiDDWxo$=ql?`)r_ACkLP(B(mhrXWlj^|eKg2I>^W?tgmGwlt z3;QPN9d_xLc7zrX4s)+l+vxTbMgmhPJl*t4Czb*J*C8`JmaTTF2q4UADZkS_DMf-20c@*q#@A)^VnkE5MEp zv#gx<&d+|nw1Fw*{Q3Q5`*VdRguKoQ0h`mD#JjIWx_$laZkm_q(B(cF^8;8GGfNJ~ zxv0$4a_k4O6o6DJf8pu<6bTf* zhF!A?-e}BAI=y#++4-jKmJ(T_tyR_VI-2~MSkB2p*_nm#PdXRyS&j8HS5L^)0n8R` zsfsU)SJHVIH)RfN;(?rV$C@)IsTikz&&(k<|`~-Op7tM;dHHu zk9lFba#q;q!}5#M#)ANY`c9mnUlA>1+=!iYZ(tAc;i(h`pOho@Gn`6mB_W>9M0x zC6#K44ts)pf;Ygh((B3tP#pUHNnyQl;uB z?t`Jj)S`=(lkR!!dtuP9)_oOl$8=kU`ZL>Yu(vrHhDog?fo+CaPj?#}7Jd+nwY;x> zX0s@p72BDC%n1fj;3gQXKTn++@ofL7JG`O>#^`r9%^t@;h1IjJFdQzAcS4bMgV5kT z(h`rW?c=uE@l5kn!8hig*N20CDXPaY$2X^urZyL&wdXCC_(E(2@F#YSU5~(j|4Qc# zF690fYliv2PmM2kcH=}EhuqBkkjzsBjGnEpo>2G#+Ak{jVbifJv>GekR5D%XI85Cp z?`-nYWNKsQVUn@Yny`2YHMsj;{$5In>jRr|^Na*+c?dmS6(3WG2wYku>hq6Yik4FH zMccyfPyD7pU%Z~dV~Q{@ma!EdTO2C^Jt+$ouVRdhJIYM3b+keV&@jtx^h`lX+7#tR zp-XxRF0ibP6yc>R5n&PZL)CozD3z47^6mMo_PF)4`O^l=Z^jtl!e%N_i9G8u)B# z4l4wTO@fT}>A_XgS&;}nb2lLuWFi*U58P+}6&Bg~9C^7E1 zs0F3G>&17W#etSqPLRM-_BRT%njHv(qP3@Pl^P%MXj;bek=AO6zhi;W0(drS%2eK_8G>%9iSQ`1YDT zHtltn*cN@eFHP`PHvID4qf2&Ajs!FqkN~gH)!81$NPhJ}TXgefCpo zKOKIl+JEl-Nc3-1`=|BsXP2mI-|X>7W0lZ1F?Ko&myn~0IjjcV>F)OX;ZpR;kk2G$ z+UNj#N~P?LeT@v!v06znlfi)+N^cnt7ZI{_vYg4L!?AMxLCpAMvaiq3nC1x@`-}>1 z1J6Hm3BGaR)Xo-Qq%WB~8N)9J{j zL7AVy5muwUOnxKq>qixxr0PQuPA;Hsr(vr|Cty>50()Y57X60lcS_5@+AVJ(o8}3V zz`6EavjcE{Aqba;YTz$l`IUJv?ShBTeRc`6Y1pppFS?X=ow$@+kG`0TyT25Yf5FaVqEIb$ZUS_}HOR{p=NI^or*FE&r8 zHXi&hH(Zhc3>AX_hfwze``;Ay|H5AoA-%f0*z7ysDf|y#_}!_O)_%VT=99%jDEN+5 zOaD8jiVNctC65Am#LM}Y0-JvSCwk=%Bl*|C&}w)YIl};cqsjj&aw6BTkrQ3j zsAK$_Tl{Mye~6sHW#kO9`jdqJu5bVJ!(c5r?4;8=Aus*kgsq>0_cssywBmB>a?(w# zd)WT%W9^?jWvPET>GYdnTYn*5{dv^??AE_qG!4T}I@6>2N5=o%q@%?9E_1h?GYqs1+38^%lqnAM$~M0>p(t!9n)ukk6-V zXs9=kJ@o7KY?%ML^UY!QoBuk7W`bOY5>*kGk%8=0Oq|Tj?3^v_T|`?{dLa$xtyDE# zG!^9eOzdr$jZE#0&6quG9bTJ233%{94sFd`j7U9fzt}nRc?gpKa|a*f`1LdkIq5&Q zxY!7iYbtyq6}NXXBjsXdWo9K8LL?<66>u^&=TnyW_^;-W{{+b`U0fXaSXkWM-I?7v znC+b`SlD=Zd0AN5S=iZ`Aa^i1d)m1ec`(^IQ~Z6%e?3RS%-O`r%E86T-j4M3xkkqJ zt}cS)b5~IXJ9{UB#qeC`JBbL*oWaZ5B{6!Xv~${l^wSCSsKF4hWDA z_}|-~2&mvI9&b`cl>cZ1h44w!f`Akn{eN#j9tsg7!7*a^aPj|m4G|d3xrMj?*^e~o z82l&A=o+}LKmQ-^2NmpE|DXLpqla-o9=CY}tm66qpcq1u?SIe%>G}Ui`bT2_C#AoG zd)Qp-e#L-gtb484mdNUe)oF&Alk|ucn zFLWc_0Zi4J9DVbw7>RiWS6#sK&Al+Y-JEq&w6uCJa*FHxq@Q0aZDz+Mmd@5mrTK6o zk+-Sz3zyT>szP{l58A(w4UHP;-JZ$B@=`CcI8#ZFnlUHd%vp|SF8`JSf`bVni+zy< zbY)VqksC4rfSnY>N_ba-!KyrGdP`Bvp)7i`(&D!NANbb);f2 zcfs2(_J~&daVh&OW%G}_SPN4RUGUD*8S9>Ru&$%C&@omvHv_SH1Xv#D5wC1&_Taua|;1o2-hcim0cANPyE1 z==0bky+7R?r8+py1}1ydAfwRZvrDrcX;>hpu!$CKWz{ZNb4(y?HA|OodXnZf?zV7R z<8~fdyXtaXy1f|%XWa2`uBn;&YivpC-*(GvyH(xjtqm5~XT>3*T2lEY`qLtv@P543 ze$4c7o)vYPDHz}WGf$oWAxqVsq|AQ-L{g+Bb@=mDs&v4sCAYyM7K=d(6?Obb@F{Th z&hBE~e0cFl&q-v-i;YRC+Tyym_J>orwL~?&IX=@vF({47`^R5#k^*VbaGz!wJsrD@ zt+cr1?05@m2(gT{v9P&(jk?J9OM}2*)CFNgUJe9^^wF}b#@rx&1DXmXyFDe(N{WAzCXH(4N64ZBB(bsp;bL7{+Yjl6+qUXod;%5}=g zxL2AK8$esuAIN?|3dE!d=-o8De%|SMG5xfL?X)(yA}jwj^$I=LnS5*l^xIy&#^Y$v zZ}k1~)qH1DKgM6%IYU{cTDLb*Fs=@K0MvOAwxQ#b3uc&jQkzh2VelhD=n552M)f6aC|8 zi5$G|@NxFRC@C#|VCr{?<8U<-I*y%!p|{)5gySusXeOl>%g{89#{P9CC1RjWinm_Csa#`@-sj_tO`ee|N0Sc&peI8F z1@QA=xAt2s@-nvEW;Cy$eiaG3(`eD;Ui<+kFnl1lb>R_s_2`)%u!I)ZJVlu(R<# zyNZ~YCWIUs9X`IppTKDZ#$40&F@%DD2rIM>iNoBZvq%dyT17?-bhWFDm&4H4P;Q_Q zLbSrRg)K-Wljisrcm4!HF&1YlyjY#^@n-7@;^pX6yMF8ZP*murONttq#*jfUALIVg zkTtUvMR_(!s`K$^4T zfO*KWZsxgMum89t#`qVi2SuTQfAwv7=>%z!`&;tilXyzHEU1@mO^w$_z4_X{3Uxdz4D*r5RQZ&2!;$j;A!)pJRapdrZEAK6*=fAAb;Sf(~8(wD?!#D~wH^a5Fli-b&kkOlk&ok=+~)DAl!=YvadOcX#hJu zCV2t+_KX8>_KgDtQ|IH-qE0BETt18P{iX4oiq&~rz3Du|-)yq^n7v2|DOaIVpSQ*b z3CrljzG!yUHft=#ysl>JSnm1#- z==z4E^Y$PK&Hxl=zBdH^+&0;aw*JcSKHqMOZy9`#P$i;Z{9dtQ3ZjTACy&Mj zKDmMXU$0`D3q*e))^N42L4^tyev>vLpb%z&j%+t|5Yu40P@qhEIG5U+U#nR`pCMoZHVT&4pW* zzC%Kf>=n0=_a8dW8jTsXu46kYigNO6S2s(ih^Kkw<`$X5Y)kz11sy}a{UM)Ie5yYL z*ZDo^HNL05s`%(1i-GnM%Z_Hgpg0Fdkn+0G3?(_lD19TQE)|1t@6@9w8PxuGXv~|h z!Qpv(NgPZ4{^AruB%x<9$8wc#!}8PYm%H1wZ71dN0;k za_3~Cz<%b2=EFYsfgw$XFi>|z2venEHT^a#y-ms4bA9II8QMb6hNtpCDzE*wnZxOymhTZ0pnzZB+5S2*0m49? znWQJSkVT^lrjRFwbjyq^MxLN1BunM(LTyfS8zD>3Z@msexo|)-tB+ zTR-bRSQi0cRoe?j2+tGmK5z<3Z6#UAH)2<>kw2`ZvuI!of05t4H7L<(F^Uo zVEMOafR^8@M^nPYKPqOhHmXgbK|H5lAzUq<%(lsZ%XxTqB_OMkif}PMoMAA6c_hNB z%deJnX|IyHg`4zhLC~XK!^M$h7sh0_>oz9S+m10p36^aY!ix*BCU6?B`RBIX@f9g+ zGsnmTWpcAiC(4+5$IXv=#^0kL;!i<%{N+)zd^ajKIE}R(f@;YW>Ml)Kb7ShqT$VOa zujhH*GyXCN7q2mFM07AP`esoYWR3MLQfSI+SZ99lG#(e;Q7eDp6QzU@+y<|mlVY>2oSO9td2wij1||Z^!ACIzoJgST33N& zF8IEIP7yf|+3dyG2GJOLqi587Yv|1n1g^)Ne4?q@29r`=vw(A@&F(L%Ig4V`<6!x>k0KGZm3SG~dEq^bWSuYZ1?GbFt-}=D{A*P<@%T>t2zvQSrF`3;k#}TX zPxLlq(2ueK<{Sl}Z=Dit9KgzbI17nItR6nZ!zu2Q4O;F?j(Q0+bnGSC?q>RUo-XkQ zy5gYhYZ^c>Q>JE7?PnT-%0EVgojj(7f827qJ+n;~<#0yCZU)#t7HO04*-oB|5XSrb z+?6P6;ryONj%S6Q&=6VW1VUoc1BD^9boM2Hb>96}YI@tAh^cKmdF))+4yfi;Bu{1s z@5APruSMyoVb`|or;Edz?_SeLM}Q>u%GgeLp91sw246lEx1&J}%jsWWZoNk|50gLs z_de#yo$+kDmx+n47~W?qw`9X{5@`@zx5O~>qC_)+F|jC1v{}pgsnf2?cHxaWqqY{m z@VO>)M2XvFCDC>$7OsEn$GDnT$sdfJxstPi1}k)`CeuFWbHKnO>Z>utD}x4HYCA9nh)>W8dSFu>FQX$j|(k;bzZN8N5~(-OFQy`|-?a`zcKCdK?4B(=}-p6ero zN{UkmWIL@qsKCDMXxM*TF=?R*U6`A*?;otVyFmUuqFtB2*!h$%cCoeKRPm@S@3fN+ zKHK}_>NSSRCo~xNC@sZJg}&bXyzKWxDYZlv1}} zAfs?qx~^%&Qc4$Q!;S{Tg+jeW&LVCXY2HHwPZW?$HW{6(GE3T=uZ0krV54^W-gYRm zUm7waC;wC+vnx?B60{?Rg$&jl1Vhe+G~rCb|pUGby3W`bPfaosp&jNIOJhY;qHAA?%z7 z$$W^9uBml7U54L58}n^{6tKtR@LgM9URgbKAtDW)IC)M%@OD(shyNZVxoh|GC1j>d zSyUq&%(Rj=8$rqy6er^HI@g3ERUigqCbs^sl%lDg7g|=Cok{0#B;HWFW z8TIQW5r6v8RHAL_t-VkrhWkvc z_wzd+uRmHOBNO&Rv@1XWQtE1H%SrlRu{x}6pamNQQ3R=zQxFg&6rsY?Tc7*Ur|EEg zmAQ*!VsX7?2{snZK_|UBucKqEGbto*AW`! zk1;vo+bIv=8=OBkmKL3STee=J+t%`x==+UtlRZIBB0Z2q;V|;}P5GMnY z?G;;p%~wgUM7KDO($nX;$EbL7Gsv)?;qd#WAei#CGjJPxEbTx!EU&q-rE@cVKE zZmR3;KecGtYytF8H}9c|^3C*SS!wbZy7C0YgZE^uyYxFP`t);TU2Gbqm<}SKD#ad| zpSGzA_60C$KjmFos>=}z*A&*4l(z0kXGcIHPZpC7`Ah&g+36@Gx*TnZ&kuHcYo{U# z@(;a_m0-E3n#)^Bu7OLg701277#kiS6pWi)7vys=guQvppzi@M(xL72a%V#sT9r6T zEv#JpiA1Z!_iFB;sruZo-uZnL{8*>@_GET|QAmR!T!jk#Ww81!<)?ap&1tzAW@CzxzvVt%${Z zkdX-BcVDJ2Q{!9FJ8ts$YEAsdzf#G5hCwYBIZLpE4)UD_t1=matha@6nDb=#cfu{y z&M?OE6S|IfM$^n@OVr{@7f%=KY~*Up%`D8rMByL;U}}{MYbfwqd~1Yf2=K@vwcqV+ zQMgg5Ev7cDTYK}rUw*go&)JW7_=%_0_R@0^L^(h_ZDjh|KgX7z;Rk=%`#GrocP z;u>DKQT`aIX?LiLO3w3xby6-drO}ooqDOmg-|6PBSZ7Ddcw=SQ>vIk>!oxYATQ<8M&JB*FaOC?v z-7Cu|Olwr?GhMl~c@-)K3kSqn&QUPsO6|5mMxl@qajM5i=LK)_UQ4h?i!2BP;V*h} z3*VCE!Y}`mV7OYYaIQXkD=l_N2&st?;JRc>Uu3_QVe|D;4#gVdko;?k!Ds5@5-Rtv zIaa+R4Ti9Hw|Ij2ZfYmWo4(SI!l@89Oe&swnj8p^@K|pMN(Cv!BBt!~34>|~ zr^_9`(j^FZc&65Fc1I~f`R$R)X9{Rp&y~^HE_(2PTv%9Om(=(Qo-IvMt<+y}L7af5 zoec9Ge9z0q7QH(5&Hbw<{2B8uSFZaQ8%-wj3B177CXA=$vhM!R@G+yaCSrufVX!jB@usUZ9OJ`Lu9uUF#f0 zh1fHH{c!p&zX`~F*nJMj9a1S&{4tinFBkN7)%RCyA4~fqIg?I(f_5EZ zeQ9^U-_}5^6Bu;E2P5!!`m3Q`6Yks5Urh5#d8rc`_}j z$^6>R@Vkrl4k@)d$2@Hfz%HJOm9f++9q47>9?uVL`LyH2b(%<+Tc3pvzwj;xwhFRT zBlo$iqUalviuwP! zJHVAsC$QE7j(P=aoyN4rBCAXt;@MJq4leu*wQ$7ZiN4X=gglGxSX&o9Z!m-9cZWan zzRm@jj*KI1H=ZbLorwxky$R2oh!vrGg?cKHk2FAOczJ_1$qGOFYQ)@@?YT|9;r)jX z(Ue{TRelho)v8mx(9uV^gt&t?rFQ#nrwr;#v^s0w|{vhwhpp=Ua-oq28=HY{DRQaC7Nn%@G$67z0 zkF!SE-3|G=0}$TDte44;3;xL+Y7grXnhee(p6K1JKN;bKc|Z_M#eARIAf4?4@55!5 zZ>lyD1FeUjs01BHI!`yum6kzvz2#{-c2Lf41IaBvPPmzaFE8U5Bh=BUqhwl?SVJAG z^n!=}dj!Yb5F_HFId%20Otw&uNv{K83&{ZcADh*pfTCxgedLIJ>{Rxq64W zZoBeSVgkXU#T!9>B)bPK+M*v~3G%zb_wG$>;gz`;^CT)jqNP?y0AuwUP`nfDQ(%OF zU29NIBtS5#o$+NPmoaDqA6U;c_^|7FHI&)b?hDGD!Q60Lt&t_G9J{hw_0u22GSqpy zNG#+A8Z&>ji|9HG14-3AG;+a|>+c@Aw&{7!%FvCzZ!U+j;Ro#F(Z|>{H!}C+0MebG zwJ1ETecPKt=5;H)w6TgC4U<$4mo%qJgPZc@-`_PK?!%w8c`bQYJV%oSM5PrM&P~p7 z675zr6988SacJJxB9T~tubrC7pX@9*ezAjyuXIVGSiTZ}SaX@}C{!z<-N!m6KI7Yi zu@%K@GOS~(n^WcX&*TIh%$0M1eTL(ef-rf5k z9|icg3TS^?9c_KGvijKf$;t{M9iH#9Y4wF)T)x}}@`Qo2vbZA}T2CH7q`$3qJ=@ur z?bo1YJ!K)NKpHaHBoL0zWD!=;XTAKfl$V<{1ij6WKr%H`wZ^dR(H{U2L>ACm2 zqS`)vnNR45vyyw0& zjDGkzu&NQ(5V;9v{p~sdkW0{+Na(t}{DExmbI}*(2yL96@rKH@&1{6sv`umFQE@r{ zTM^M+KKcvJ_;c;2Hb~kdYRcB|dA_|)b;ehR!qMFBLv8hMJ9&Tgm~P^YOhhcIc4gSJ zqQ2$a`2vh=k~{(U+tP{z|=0h|C^im&2(T*9*lKQW+28}+61YIG%n8%nD(XX`Re zxoBAj$DgfIRIT+?*sUMZs0=*kugDW%Ja1g($k(z77K%*o|&g4FHk`dFum_#J=6^-de4Z1R_3y0wccd zM4J5BuY3PhtT4#qHq>F&1!R@{L1A%Vg@8n1X6Nd*eb}_q9P87JYlVs$^J?j@1|R&s z1cH37Gmv9sOui9lf6=MsAdH=~6{AmsB>}0e?STvVTtpkq1L@#I0hPNJw}6n^K-Wfd z(|)S6m^-2+g4%Z8H!r#tVK+ZI9wHpbd6Q|Y#}Vv6+@ zN1M+mP$;eKpUSf`<#|G_EOj}~5}jbL&LAFb!d6uBJ6!eVA?q9OG`U{*J(Cp9rDyeY zoXd$T79YeqQ14>`VPK~;o7wumyy38!Rc}()ND?fyN21ioyAT;rS8-DsLm`4%Wp3hK zid?tk8^ltTL&?#FWq&-s64(F4ZeLvxZ!B~z)VTz|PVbYJJ1+s!6m89xB^%NXi(%0v z1)@#9X>~5B_z_WpmFHxU!BQl%Td_vQ8$T~Q+ZH(^OZrw!`PbDI_HPuwWFVSLTf`?+ zBv`O#n-IT!Xs^>Lu`SIAa@1{R=>FGz&jM?T(=UvlZ`h#Xn?5WJi-yf-;kAB-CKdy= z6q;U#^}E2iM95dpUFu&Ef{ekuQLs0c%Px5^U@NQTjX*5gysQ@L#L%}P?w*bC=TF{{ zdWrLE;cB{me*bE(eEI#ws^<57q(z?oLOGvH%`56^5IajnVlINGn-@<%8h$t{Hvk%1 zYJ2Ehq=aQv*~Rrm?Z7$OHwb!TiXhI9-W4>*tv|!W7w7Eu0GTIAeXH zVv0N%eHl@p-SE?;b%-VAyrMCldf&HD+F34GU0f;jm7~CGY|7evCh>o z2gocr-QFYr)ie}WdX_;HS!8i%S8#s1%P%DS3YCai6Hg)7_;xL2Tq!{q z+m@Ag)k9Uv1jb9FNXW*63xWX(j%n)!$ zTKYr{;9Oz00uJ#LuWG3~NIhKRIHteCc0QI!2GoM;YjO( zo%(dPR?TVDTP087sl>eQ=FQUV#qcD&7yZ$8iD71oZJGw_T4pZAS&3liM_qp_K7Tyt zu$+IY|_7Oi0SRc6?fYQ!@c+Ss&#P*YG~*{U2W`=g2V?nO>1; zmCzV_ud_u4ccjO?WgPg2z5NzAsMeeBVY}gndBE18N!O+)oxw>^V)@~GeFdb8?}?=% zhR`sTtSalfEDoN*6#l~Y_{_ptpD^VEE{0h|XwO63^EWZ_I`m%d5VX|S5!Evd_dTW^ z3O5CBSaQe5S%m$Cx`k7jH+L&Iaifn{f0rSwGllbm0)2+=el7JAx%c-rFJ2z{Gsc$i zIk?Pj9OskENA1f>tTWU(1@$677lb>Z?HxT3h>?sryKmoqJ-7V>)Z*Wfc+fS^FNyoy zlsdFCd#NdIb|ve#WpA${3RWMIFVnF7!xNv3|g9$9p<(}nANSm_4Wb=uTew1>H5@7nMQ7O+P5op zGO@I8nUU))BuBBH7!|9h2gO`ttyY{ZOt=z=FGTo_HY`*U+`dNTznWFeTT^&6HXP&i zW6mbjB78syCj?7y5=K z8`l3ua2m)SFTn{4@HnXrXHu$yDhkEA^$mIxMGB_*?F|R@2*yIj#3iQo*>HfpLF8!J z2r53`5FS<-L;)|0=<~HJRVh!gAj6QzYgee)NGP7Dd7Lsu>_KK7%|1ebwHU%S1;30R zPg<%OQI`jLHd||xp_(5&P>M4xu`_5SMbOV)>8OcEa}Je7$p4ng*32PZV}4hfXvf^! zL?U$IIg|8Wh|atUFA#*ab+sH{P&z{}3~!4>Z0}tK1LDs?td?R|^{9k`)(^gsS3p&F zvI3Ugw8-zyn}OLcehbeBld}lsl`p%v(74A5&;Vlq=<1s7n-?kP;3)-j6jt@~h>~uD zrYE_1ipx(YHt|V^Z6IdMvBS@_75hCQu>}abc}C=zvPj$X3HFAI_#Ht}wegAmgd_P~ za(zYN@^E-W8cz$(tt0C`^TdLwip&+h&rw;2_!|oF22un@tqoUU&QH9IBSc_-pdWA^ z9xKYAina64TO^#QEdG%mDjn19os6kcEj2t2zf7yN-J^MBMeyuQGJRojic_kcOd!S1 zSMj2unWuV=Qcu_m#Mu(>y4~OpnL9aF!Jsd#FAsVFAHUwbgLMytI`BWvGQzzH%G+1$ zrZkWsj@OSRncJ3jqX7TZ|55j5)_U$?YX9~PH&ml)Kqp}+QS*DuT| z;h?QR3&m%mEds5Q(a=0v5-QR&pVy0t#n8<@z0~hF{o7+Ce1pmwDbV@TyL-Ei-1Qmo z^6v4nn_?^Xe6j44haqY(LTraJiAw7+x%SIrJGr-*e z>c%I7eOY3Wi;3{*{04h|ZJMaVJt``V2zO$k<|9-2yh#!`QBeCUhW24ILV;sj;QbaZ=`8wBDYCd^D6@l2cFc4)g@314vmS5?qR)QFxTjRc=(q28hzvRq?@)IVo zwl$s5#lDq@mM}80*W>mfg_Jt4!NjyXHM=4Tx68_6>hM_5i(ju1sF+e<yHc_ah^vw3n>XF|0slh62LiLpM_5l6xRzk(QJa6Bp#?o&; zO!`V5tkXbsj%7a?yhB-S=4QH`;lqC3k$)v(X`L~_KWK3emD4Yz$kS-Qpe$9!N@;g$ zD|_6-=e@oqP}8(0zN${9Iq)hwK|acgelyqft&<7_4~<`ngKGg!yF3oIz4p>u-=^Go zO1q&taVI&05zw9YC^WL8ERfHh{^t7bJR%FM7yg^*GXa1kq>&M&<`N>3Av5iRbRMvc8&`^M6C<+hk+KuM$3kF#;cVLN?R*YqIl z?7b9H=c)DbC+c>`g2y@D6^*E?snBpSTvpTAZzAH4z`Nml*hXoNcVYT&NzkxJjf^cm za&b)AuM&%?hI{pn=SE!c^35}cY(WcxzHygsY zr?m)7vkGRn1~(UFL7HW*TM2Z(Wkh%t(5OD`t>81-8MTjq+aD=Un=nz-J_=oTVx_gJ zSbzs3uy7|CalfV3dNiqy^@)initNtZ4ZIx$-0`!?!m~%Bb1h*bQtD5+20%Fh@8^tvc5P-H&mheL?VUh zYtqslndBz!;eNt2eVNs*l>+~zpAl;y7#@koOPlE-BGSXUkA!N}Q`iTz^Eg8z zizkh#3mw7d#3MG=kP3^xm976!RMhJ7J~Ojg5_>-s94y1(3Tp)>H{co~$ns~{&2&fr zPbChnGA*_Y)MLg-_~?EdSVXW>^6?QfMAYjKqxh;=BH{k!P7bq)RC&NuY?U@l=P1R@ zG`d$(glCJu?l$mJtluF&RHfbeP7jk3yQ{?kiU4g5AlQ%u3mudmj72NmdV9*QBn_u6 z@7|$-MYya~QDmcoM6jyw9o<_+w^Q%04XpwFt_QKdo{%hBdveN@;L~?@&g~Wz{c*RIym1P+ zx?<|~F*U7^pn}T5SpK$ja-8~eW^z16uBSkZTMLx}pXvdd{qvjewoVU)@mrVXgS~7V z!sUCC;Q`d?!YzTUmQ`jC(0e*82G5Iov9?WCQvwVIUUO#y%(nM^TIEurz}DxS=LYAl$e_`%>@@AVQzYQt4oz#yPwi>WP1 zYAI2x1;>)?|4~x^2Ospsw_m-Y>WO%d%f;UOVs=^NNZ6C3DOmW!8`eD3{vg9Yo-;kC zStB7+>;n(QBA=u_*$?`9$=he1I%y0X5^TM&!oa>mpW%?cXJ*032b}53^t=?;N1}5^ zlg0*mU{&~Q0w0G=Yh!{jzE9AM_yiT;3shjSf5EK9B$&E9_TgUFXvD(0{-irI%$T=?{cIYG~~PX?~qw9FLL~byOZ;Pp<`I@gI?*pr5_E`)=%i!)l#H0Dj7K z)H{MTq`kj2AJe}L(N!dH7hRj&9-k&h*jh>oWKgYklwWH6oUi|{nz?^Ug{05}ME|!|kdiA4 zm_hPoYB|9_P32WzC_kY?W_abqBL7vs|F_0gIkSV`pDL7^PwOD|{9PPWToj~KC(k>t z4DCNwri%Q8RD)*jDaCBRmRkPTMvDVuam|$6pwA2&rd%+n98J4n$W94a7YkVmGMZ~B z`nQ|E-{{{0ydCQ$=-myq;`51tSARHPEB7kiX8rGnhVcSBBp0f%QuT}kcY^6eL);GQ zJG>G|={`ajLrVdZ0;zWx^NTU-2^fT|Y-)rr(`}k^?VXN8vz*G4k@?B?cUi3n4BCM7 z8nd(d7Zz1z%Z`$~ZS3=CjcEBnRPE@9OP3rUv`VGOZCOqj$nxG|b*ni@4It?Up#Sro zl-JD(5g!y7Qzqc?drx=TYhBlWZAR$p=~t|xY`FiyAIJi>?-1r`#+nOJ#^eDE(`)>m zyb#RuYE1f37V2y?;^xw4Axkd)n{$vVa0;{}q>JjM^#%_XX8Bo<+<@C2?3@W~Z+kG5T;P5*toi92%vXYMv9NZ2^%FY}1;U3CI)!B` zZXd%eQ49r%#^%cLi7I-OG^r+k zpBLT_dbK#nH1GX(EFw-PkKJKCuzSfUe^dg6X1V4svDeAb z*;0)g8|≷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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/requests-1.png b/latest/bpg/scalability/images/requests-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d585103964f360eb980223bfed7ef3478e6a0bfa GIT binary patch literal 17109 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 literal 0 HcmV?d00001 diff --git a/latest/bpg/scalability/images/requests-2.png b/latest/bpg/scalability/images/requests-2.png new file mode 100644 index 0000000000000000000000000000000000000000..c74dd3e4b0d2af8ce7bb31bf40889779bb1e8407 GIT binary patch literal 18037 zcmeIa1yq#X7dJ{N2oj2j(v4E1NVn46UD7cFLwAS@2uOEJ!_YN!DBS|iPy*7@4btC( z|5tq1e|_Kj*1C7yb?;sGveqyUXU^Vd*V)hBzvm1=N(z#=*d*8}C@8qnQerA7C}_GU zD5$hpw}FvcdhH^>8>*v<)mb6ei#r3*|QIZ4~tDDJW>bulxU8 zqXO3?D7Su(qo8P@lHOb!pg#FKKhO#V~lx%FPC1>&WLONb`FJA8>s=45Fd>J;ezuNTVgML?sG!Fr(sPd&c&R zMhKgVib}x2)SOR6OyVDM;4eWMOD88gJ`l*&)s@Zl1sl}C0`#1hmlyPm9mLMg3d~@2 zbhmXfa$~i1r2P+*KYYZ@98Dao?3}Eiwp7=Ajf|nrPJ%Qv*9+bJ{6|hFEAziA**gBC z7N8*L`V-J|wr8Ll-TSiit!h??cZ`MCVWxaWWh8CQkkHz%qE$UrGHQo@4 zIi>PFbf&jYUW%dK2{u)V>Ml&0o=Mhs*>*WL-*(x)tS>F`toO9`xSUumUfo(HdP#+X ziY0=AM(_p&T#2-$vt?I#fA(uX|Ds{qUi}*v>9rccGAI^>`4|(FXxd`0!yOeOnGV;w zzknEezL%%>Ec;$Y?s88vPEopu6s*nZ{92;ZuH13ep8i==wc6s?E27;}%xd@oFh?O@UR&4CHEQ6Kx3N)sG) z?~e2jlOT8Pv^k+Kv-{i6E@@+7n$ft{ePnzqkkI;{6554>v4{D*7U08DoF(5C!-dT$ z`1bHU3-CbZ?9yS@V8m?8g^=+Wjp5Ax`;?taoDrwlut{3(mj=9xbVJey#O(abWT7L} zVvL1eUA$Y<7Ko=s%%vCWYR;D$J(~Ce^ytf8k#?5|-b$g^UQV!EZhwZ@b+nlVqd;lR zgIQdtmEK~+S%)L4;sYhE%Pul7-FE3mePV{=XXbfzxcr(&5yVoJ==E;ym9wO*mBNn} zI%c^|QI<8w4q4&0$3+e>}zPVCr}YU!Uw5WpZBc?i3z_ zT`nz65vd~pv z(~4zSI4*C}hFibU$i9DIQ!OsD4(Qu_&uAlcXXu(+B1F9gUd6xZHsLYGH3L5zn~$({ zFdQIn8sMAs9CQ7~%+`m4-+U!Op6k^|Dp54+5|}T*b#37o4Ahk3s855>sUxV-NHt1> zD!w1J8#pXh;){*MUHy`!yPSDUEIE(FF*R-rlyw%0;T2(6&c1~}uYzb?mJ@p&RSS&O z<+*-D;Jk|dzL~JDSsaNJZ0O_0$3J9f6&}4Lu*%(U;?s9d<5)*dFdL2wdrG$gIRt|$ zf)z+o6-zQo_*fVspN^+Qb5yFW`BqlNhK!P~R>jKGGK2Ztr%gBah$6GJKpI7Aqd_}h zA6+u(5~SU_RAYXmbF)eEyQLHsiyFO-;FDcSSSNt`FUSXW{UeX1|F>f@9ue0D`rjcPvp5dcv+sOcokD$qEns z*7J}q_2Tjo)Y!}5#G&FmkCz?#-C~9f4r!ZzI@)MZqM(@yDh}i6maUOKIC3%d?~QHb zrewA6snVXw%;plS^Fdgbeh06|{&bs%hM20l(h^#~qbaVJI zt+6-{8`V6IpPuLCpfq$2Bs)159r02O!l)KInNN?isCzs%fuZE zZQS82O-i5fYDr+YuRGi8v(>p6nl<#jLaX+;z$-__`q&t{dfPEY;((lh2@LkMdh9uB z*O~${`*mlIJb8}ho^{%@9H}_ST8?e^ z8cXDpDc1Pcxe9GZfxKLucOLa&>ZAEYi^UqrhQk{nU z1ViJcMkXxz-9o_D{aE`|+{w+wO#c8Rtr=eOx_d~CsQl(MJF64~ajI3$H#S?~3}K(T zE(l~kid_B@4N~_*7yVOT`Hjc|P8#vF;eCOHq44@lv|$x{&sX-a6BoTE^yRe|b7FzQ z#Hy(xg&2cfteC_xPbi;}yQEezV&UZ< zAyMhS$~(UWgER{#O$NiU)O18pL=UfdC-JGA*t&+rcAA62uB51F_Go z|2lNHftMip6teXjew}3JO1wT;y%oRxYiI2(&I8A-U?S$lMpX31EZdrC7l*D?*N0l~ z+SZV=Y5(Xb{GOHBEbuSOl7=ptmFeyLuBPl8bj~`5cL6KqP;sLmX zo2bJXIRcTF7ou>R?K(%%CDxgW9I4~2hoV4|g)l@|en_()!UPUrjss>pH^QLCe?x|LVMF#D!c=aUh)ma*C>;88_6^t<;CKf`LQ+lR6^YS zbUE9+c}R}^1;w}YZ)|zn_RYs>-ILYS=v*HYVCTmzCt-2CD*6op9>uxqrdFi6Rg7dS zkclU;j_@Ml{%jTcd+XGq716Cj!dEPk#~THLk&{G^;~4uF6khtAZF2KAyF!PC_qLCI zpyPMz0`*MZVCqFrJ2eWBuv)8P$QoW-X%Jg5p*MX+8(t5oz{a!4U?S1| z3dr5r00JA^IG;e7!?lbVR&v%T#x#ONF8RfH!&lKeS0{{4A4e5rFSTM=4A732P88hw zYhf;`3Kw&jZ>ojU+DcD~(DV8?HC6(XC6@zT} z98Zg$u^O-#A3^TiA@|#B54fK?u9Qjos>*vn8}QZ}Z$G{X(RgROusB&+h7=p9-1{XQ z@6E$j+i3ys{ZQ^kHODHA2~7MRE3|UKPmBkvv^JAf(yJ-wf}fh4$K8K?ddb&Q4_9#1 zT0eY~Yx?m^hfHg3jwL3XTfRNi1>-quM*yRu5bwcAY;xSZ0?YYcRn2O%YC_!nPg91) z$l4Ej7dG?phPGCai&NIo^QX&}@<|UoJa@Mm#32q%hp(G<-gY03g*g4Bs+h9P6qU~C zIaJLHID#9=@^PHgRWdglFZD|KlO$QB1ZWM#Mf;!Dw-gvMS=U&ydgc)IXrmpxS>DLO zDVmp)y>r)0gEZ5EIkeAYKec$_OB&Ysy5?lEKZ82#{i`!*^v|nbqKm#)geSXQ=T0H3 z-BBxgt7MktHH7INOv1AaJ^c1fy6}|uhdznV-and;D89N7B%B?ur?QfA^z7hd=}NbI z%W`^g{N%#4$^f~0AU962xFl$yW`PdA4Ra21dsETn52%EnsInH-nedzjS#IA=ok^Irk8i#Xp0HF3r=STX4H+k4K9%ql`+^hYIfW!@L})~^ zl;-t$G(>FBe^q0w7`xNb^g4Rc#!m)kcI3E;d*UtRxk{x(s8sKxi?2n)4=c3ymuHkB z%*M}4!-YOE;w*9{WSqPu<&g|$tCXIPs_S&hGh470f(AxqEE0pXJRz8ppBh=~ zA4(36XqUtr+WSL_2P323IX8}9-C7?}{C0Wq?%P~Nx>0%BhoreWEsIp=xVz2AGx>Lp zk`F~qp;RvHisZmv0|NJ82`76G2wV&kB$Fk_u$o=Jr zrb~|}V*w9FQ=sJFw9PkI-$rL4I&~h-df+k3p>K%EHZ$S!5fQ;XF~Uh3^yg6pkVd$1uu`x;yxwh4nsV8~;o(fN92@|DXezIuMU$DKFhAp&YSP}$xT1wMV=HBGkP$){*^+Mj4Za#ay7(rA(E zHmXu2`dwZ&ND#;KLygr_?(YP><>_Z9`$Oj{<)bQWEqVv8+@dF3^!`>)Pm0)yn5zeo z4zuU^a-aLErjMPdM=L>n!ZMpWd=K2?E_a;qQgq454F)8%1;JiHYK6*a6fV2l6(07V z18Ybfrtc$oI@Z8C7anmL`Z+DE(TGXMB(O?WHPlOBjLES5^x-%3daYTn$EW=-PT517 z<+F?hKkcs!%^IWXt)pIOq_QTDSu`bIQYbl=*behz+42&2h=jO(X0P?kw0g=XD*_qZ zj@7i~W$p0s`r;Ef)*gVhdF*)MQwQwg=305#=jB#U;kG7?z+BbOga&YI`|g7)l~qXM z3-(nu{OMXb^#1G%`u!a95WW$I4xNJU=3s661BD8^ndk~@0|tDOkDIm=zf8)OEeG6w z+7)Q!N#oTPe%AW{si?3&dCNsk88(Zqb^nmXwyPm3ZSh=sTT%hxdyb>{lZlwDrR7|} z)eoXy8uqP7nN?+wrlhDDOgn_vET&P!rwdyJ4-qkId{{gbe9g$4u`au}{$+M4Jf|;5 z2foWQD;8pA{w#7H|qKOl<-j{_Rtk}BqeKJ!gCxC?R+~n)W zr72}k*quA%@7Ngoxpsb8X?*vgHR@=l)ZxzHeuyz$<(W$#L)TQQH9VYTLroKW+7M=& z|B#OL3&_F-IkUYqN3kP5S$OF`h@1Ay=CUegA?&N+^Wm_)B^W*H1Ru%$2k|2tkXs#C z`~dv3N~Z*)=yq7WZx+3ZiLNrbR#>@K`j&=r^w1{TwZ40(Coc%(%>274aO*-Am|g5DluBJI&u0)L0*8 zC0&au;QIkFyN1X910hd{zJ9Bb<9MW&2SLzXqP;W=LAAiS=^@x900hLu^7-AH5vKt$ zs((S)reQz}wLEV8_@5pF6@aliEdF#H02&vCBB+~~9b)raKA;Wh6#$wL_N#j+HxPIt z-J8l->H6`2Kdn|jVe16bJ|!vu%KwLJgfyV!e=+eX$?NyUK#BMu!gZ--n^|uzdJ4ec zAkwvarsTiwW-C;3_~4yC_$BwtijEkxnI2^NBu3gIB$+-jT;j7?Z|}h9V!^Fj@2JLT z%Rc!=tH{0`64{G~bNK#4^MDM*oF4S{=?8$Q?~`5SgQH=ol%av>1YF*KdMPcm{)u4v zFI+eM7ghvdi8s%l-?}lCG0-x0+&3b&P1OQS02Y4?B04?L7GTa*)G{6`{ zRC01R4WgeGpnJL4jdf7aQ11iSJpn`RKP-UYVF664MFaWU`Jw>Cx^0pb21VU`{OtrpwV{!^n|mIQu7F6c~3KU++X5gL(0?UuHtbA$WxKpL}p zp=NaF6lY{(V`EVvEfJFsnxpvzOR2za$~nh{CtIDP&B*lFd<;3Rl zRh`XOXI-_T&s?FVD}t`Ew2FKhOd3T$mxj`WWGQO56hO^qLY^LHXRcmzkrs=6_Jobu z`y~xplN<0#V#7Kwe*x#?EcV@np(Z}He65!@HPJ7*4d?uQNZa4h?f_j#H>s#$WNFOV z&t4US}s`%9zDKi8Ru9c;q0pO`Cl<$S<)+ zQMYQ4$m^U`~xv*)EWzR?r@^U{2|`Gx%F)^a+^XXUFjD#N>_*# zOJ19=+A0Mq^q{McqNm*}SzVsHHF+O{tRb7XH)raj@Spw}=y!Px+#4cs%VM-2XA+kGvj`FlJYhHAl zlx8U0Q`LH`n3g$?Ej(s`xyG#Pz?HBibn#elg=1*2e>=Cw3X`01+3uu6h}kggLe3!l zm)}O2EUE9qT@9nuH0>A*?31m4{nmi_n_@Lg`v+cb6T#bvz)Iu3pG5)4z~JiBd5}vLB`Cn-B19Q4%2A5eP}jIF`aD` zEwMLKNNf5z#n5aa0GEB^@+#YgKh`5Ar@|%Oz+t{_uPwV^#!7ccEb!t8xjv<*!J^C1 zaw(t)ADQ{6#k;mRqhhh{v4>zx@57( z#2CBx-to*b*CcZ|hT@M^Pl|9Jog;Uit$xBBlQ9LAY8`bOe4o&IimjhViFLn@3e6Ia zJ~W>$?z3OEmCsnrZ!z0Ou1K_O1>Yj^;aVef-z_)tn`}?O0-j|G-CF%F;8M#UAVf8A zP~bApXxRP21HDA2Tty=MS2yYWgef`nNY5cu;LJ1$eueP_A5ing{wr?4MKExNgklHV% zHBD1}?p-N!9V`98vu$%`dmvV{QsE1g_TdVO9_no&(B{!(mXfZ8o`-FA{O*^9p{Ph` zGl-Pi_FyuADz(_L^znm&zK>6ZyFU=m?7)*bW;GzSckaZs?&b6?_B8BCKH75MRpvea zm4z+%fp^B!3Hwk*2fE}V?{Z90o99dF@DYbI!q^YNtl7hP0g|={1v6eh9eFHc-wBwNg;=N5Vh`MPS;f?;(S-!x)s#=x4j$oz^WT!P z=V_jq^m3H0bcb0uvX=P#SbjxbJYHXI-SBQaBJA+ZB*CkCQ8ccazHcB|C!g?Wa#x%6 z%=f7G9&yt6YW?~S#-v}e?4a<77j)fEVU;!HfWCydP)%`to46_?Y@$$0wm2<1ii1?L z3hMf`9zISyypY=#f@dT7Ow&JRElo{_=qOsAU=uA;ZiX78{t$1&#!{4+BT8^?E1}2;N zvJjCiHo7QbU=!kSvfNq0jMg}fzP4T!>h!u67ftz{8S*}WJO5OU< zohG~TV^sZigA(_P#{to*Mp|0hDaBu~=(`nRL#oE9eX)9k`%U^p+Jgt^o$mAZzi!I66$E*{7-4vI7Fa&*^In{>Ouum1 z7*w2a&g1Oy%|q*!w(vrfV-viiSedx*0 zL)WG4mMdiSq)^*LaKuxO_L*1C#vnR6<|CTE$HeKhlT>cdds6}mEel(|S%=}`AvMn$ zv{o?q3kVDfhin?Y&U~OeL1NA<&yrrn?R)sgJ>IPWS^OmX!8YB{tA0Ga=t3(O36z<^ zt$MpoP>QLmU{6~DQXN+_qxn$y9Zy6?%|r^ zI%0S=wSw1k7q!76wbBf1=DgMHYf9eqHq7nY(RyWyA!k?L z%BQYMLQwIpi#%=5CA~RKkk|;rSC19)MqUlBf@u%Xtoy1w?_T?tyxSaKXC!rtI3hWY zt1(rbPSWWo!5YE>a#rhW-o?;H{&Ih(g`R-J4ENV@7EtBneIjP~R~Tz&NVX!773E!4 zX9Qe$bUVhjMLIM-lc+If9Tw-ZO)Bx1SI4JRK?tvw?N8p*OST61dZZ6)UKYxtBgeD9miGzA|Y^o)iaebi1H1s8Vb(KNVDs;1$zeBW6v(`+)pTett^ z)$iuM*+Wd5yWtooRit@Qp*nc{u;Y7m+t!Fw>UL?DFEzA4kg=zPW2=|&p!41hdX-$JxNA;;PXwOQ~z-p)`D*PbnU!{6u4^ zH$GZ3K!CDtr8sXIIT6ChmEtvXNDPfM1Gk5Ix@O1w^xm=v_CAU@06LtU9=6!zF64x? zI7C0zs2;nq=L4}pJX8J8>B~S0DmXH#cy^(^nJRLF{@G6?bJN_TWEN;x80&*a4O*|S z`Y^M-(6|L00#jUe>}PzAWYM?AZl4DfeT)vDaT_8fahR&Xy<5Dn1ZVX+7_eAuO$+=L z{ejr;%^`__(>f9RuVCFK&`U>%Ngd^Asba4q6mQczyYV!gxC+zp?Ko*j__Rk$-X(0S zWHXR8Oedo8xYzD^DC4vz`7*9iXCE!AHyYR2+UQm2Xu4DK!ee*Gac1MScpO_f@6f_^ zih6kk!5yuk{_H!3K~_b2$2*(l(vdc2Z2VWJtl?n%;K7MC-xK$9J;nE09+3{Ko1F#{ zt+o_b-^m*6ON91~>vn1{9nQqZ`gDhynZQ@)%w}4GVZ3@rymp4rmKNms>V=C=%T|{s zIBi@hGKg2_NL4`U=ze}7&i$|i0hz((`E%AZCL0@=XDx+a8qquzUS^4*FjmI}3ZQw6;w@r3GeHj^sqxOX_BJw+U$AjLJyKhJBkuzn0yy@ zwykRESq2UNX4uT6$>wVtEPNh)WJaPBQxWX? zUX4U;YA)kS=qdiJTX^Hac$t)DS&lC4Wm~rFIF+I!p~O z4{V^kSZD5Zo>Qd-c=VHsRXpX=YnMT5Y=X*`P(B0itAW!OY?|)EUQnpSlv0FzucEmi z_u2QlS=nmoL*(d4t+wh!z4AM;KsrGxw27}2be>G`b4=Mcbh3pz4m`U4FPO^2fQIPt zlfm1F0BY5XJ+>XXp1begcuOP4tIet4DUr7)NsWR{xlui(uuuIlz@CsTi|QHGA7=Qk@6 z$OGvy2~+nkjS{f3-+cR{zbFF(fHDlcWBp6>1Xx+b-uUhf${+^xjls*GAKuVl#Q-aR z;(31i21v;SgcIL?jdMeT0UQ}*R!VvF=ZQWF+AttorhD06zy|Fa-*}?%@vn;icbbI= ztvcX2Rt!5D&MEg(GmG}sY?(JhBCvKDUw0wGoGTJc?*KF8#Ju^P(=4^qjq6A8GPBzD z5(NZ5UPNFQS188~iA~fFzDzeubb{AvzrB29g#V8*{KPO4Dq}y~UH$6?lxwUJ9PhdVcZiTD5*orXR8U$_%cEZ;)8NBEcTJ-~Hhrc!}7h!-kw zOaU8(hT(5q(Ev*abw^wuLi`Wjheids0Yyyi5B!G$$ZH3`A4yIA*O?-KbSNJZexGaj zO&Ej~vrL(}#dUpb!D&7_ULK7!9%R|Jk_j<5Up8vFGb%4 z`geS1P|7;=8QGmf)Op|kCPaYd^$_i|7D;FVx)7WrO)D;4wT7kCFtSjSDYckJ_49wU zh36ftv&y&cmKTR=Dz70r2>qiqM5*+(pW{||Czg_d)HBWy+R;BE>E;UcLx-si8RSmF78r8o9mi7;Ph(X@Xf73_usos z#2o9#8;byDjSz)5yt?8RA8!4%*fp^Fio^78IAj9KGVzJB{2h6J9Uz(1!0P`*#Di3T zX!x-)>dgq+i@NAg|Di ziQc~1C{OtO=FjWWY-!Jkn!fyNB5?FNu2aZwLxp7!8I{_gF+7QP7feOeg>^$IYt1LTj9Z-VnCuiZHIW*h&1 zajr-l!8nh%X$|gZ*T=r7H6>iEm^)~sEtI3;+YLtRKEKM;6M5zyC`P$F6@UF8Py_{| zqFkSexYa#2KS;_XPSXftU|=wIzxXa@poliDk^$3CZ&#g@y;$=fPD_SflR4KZPiX_A zqD;S6+ajd1Xk56Ni~#KxK{s>wDE+GjwN}aZELact{Wh%P9R?>dpEDmRGGo3M!N#b_ zvzN^n5oeQWP&0l1=#9wjJ274jF)s!mhHBpy4onCT`GFzRY>#suGyf=CKN#Jg4$G9) zFA5xAF#~Yvn^a^adM9!pL#D)DHq*h1I745Cl$`$+6%N(|--ej@TNdOs*vJH%xIJ$6 zRY5k2`_vIx7+lcFMs0&%E9tm3w$=L?!b_9VU)h!>iL#mrqyj{ir*euM;g02xj&TMrEPcu5tF!9G@dOBpEJY`%%JRz)hX2V5`5Ey{@wi&`n^4#w4Dg0xPR?C+;*rZ~U3u0VJfIc&o) zs4-*+{rWl0J6;C46!1K8yo>dK+poVyR(l=7`>lY>mS~DB;&5egFq8lg@AbmLbA5Uc zRBvu2@}#q9hYv&Zt;5N-ATlRB5D7AdTO zah(H^RPRN&fPu~;I;*d2v2@;HxPD)-uHEK17$+*Tuq;LJii#8%Fp0x`U>RRA$E1Xb z#e-HQ8z%NTV_s@0k;J{~0Yv*>C)9{(?cs->MMBQ?ZUF(fY!CeC<(!u=Bu<{MHH=E5fU)4+E`&O?bJ_&sluet(A7s$j_FDD zvj%hCnz>f*rvK!WCvRHcB^@hjg|mGk(;mj~SX;h}7!cAg+y$#g6FHX5DC=jeZH!kZ z6ndn?Xu-04g{-NPlGlgsRx`rRUHb>Ga+O%h1n zBu|R%RQXuP(FAMJndP`FqTP_oCEa1pOLOp5bjz#H5A6-vm4Dw_p5S6^grN9|ln|5! zqOZU7P(YBShQZp@Q)>;L){v7Thu?Rpr)C{ybz&A!6nG@9$-`9DO*;1K^9_pY1ybCr z0`%K*kL=f%FHjlfQ+Dz8sli2a84=S5N$pPVR>m5W8GL0 zH#QP~TtNSR$(N+w`&>^?2-t>EBBFw|q$D+GkEGK?6j^m*3hU)2yvy(}57ur+kt!Hz0VTJ5D!ReCuf zy9k+HtF-qXm*5*jCJXT|wYgwje=Vbb!r?er5R1C!UReQNm~LYkl-hg)^(#fp!Y0_N z&-?6bD&K8sb}v>wFZ6U!Go0KD{vr3}Cq0t0GTGhxKeGe*g}tO2GCB(ka!wOq1Ip|t z63z)QUc)9eN_A(4_aVPttq+jEte1!bM!{C&f@B~WyNazwoAFjc5(=0{35@q+pPKxZ zW-+W@1wqE`h_(52aB)v5;@efO&f2`4v?p5COw-%!YS0S=h`@7lBX@0^RSprby<>o% zZBwdVT~7-nqAkMwPkBm!W#d;b&-|Y!q+aExWqZV|QK@@Mg)`<^(WsKoM^YE}6P6`+ z3Wg@Ui;rF8&bpdswEVegQhv$L@;D8OC5%=<$9$Y+pUF(BPA`u{&~5Yla5VqVB8dEmEBb ziykC7c~Zp6QDv~$13R+&l>zfTeQRq=Jp>NkgdUef$C21`mD&Z7z?G}H7IYB^n2CCE z7^iybM*h8ZzqG=74Fu1DCaYA@%%(9mS@u-eQf-33mAT;bFI7aW;OF$mj9btwm)#}d z#Y%f+9>G+u-~v3MeDTmE;xGV^@P&TlQDELNQg?U9Cp^wpTe4~{FeQOx~v!etIzcu1C69}b(YIih;3So9HL6a=cw?MxjI z{<3=X$t_qA1Rtq=xmTm`AWv% z+E_s1%c+oP8dY?uU|lOklF?%0u&GXBKHdQo-DX!Stt2>%Ep;D29E?8%)yF>ls*s_p z*9o6gK#=6LsTKP)so^VC2Ou~ZNDlWlo{qJ15+EZ=4pi=6HHcLfWpE|to`MjeaAn}& zw->lb{z$2M({$08l|#|FcufwGuD-cC8YJk>KOsRo+klHpdNzN_r}G%xzw&D@=oJ<5 z9WDG=US5VH5fgV&+yNksHVJK)X09tH$= zqt?0aCFc6m-H-`|2ax*Yh^@fz^7ALmtE=%v&v8-Pt&F^{Fjw&yEu- zH;*1ti!6IBO{=Zv4m#M4FVL~r;OJIFKjD-Vt3{{}&B<`QeN|_1V|13DSlepzFGrFq zYKDP$`3GpcFF!RSM?7NWHjKWc-1Gdg*C#ezcGL=5w$vw9uq-kvsx-sGcOQKFV!fU+f+4Le)6CSQ2NB_jCr2N(-$W0@qAI53kaB z%@urHBk4pPjjxoe19cf+aLfyX;?p2MQ&@=^8Yq|MufL&zPTv>Rj66NS9kYrESXY-U z;8Lw-?9^9JmHYaEmv5?2!zl>W-zRTTs@f_{1rw2Kys@1-H3jn_*6_p@P(ZY=aY{ND zSPLR%V8}-aj>gIl&lRvKkD=->%UVGn3V>jRV(%e zZcBJs(UqJdphjg*G9B+|d-xW@;Vkg@M5ZmdZCA|CcQMl_^VO~F`2D4cY93MNR1hm7 zAG~i5SD}|YDWch_MRo>c%6Sqgy>Pr+glcDYF(;qY91j{ID~GBTKX+W38LgG3RF8LQ ziobtqf%{QbxG$c9v^v>0y0mDji&Ccz4A-Az3WXln@ON3h0S&}f=dp)e!IGrXkasnO zlr3>BUOJSUKXjsSxf?yEHvJsJCT?VmSH?^UA}c-FlFiBNE*?`g+>CQuv_wKvzpHC57{)U zJ*U^!M~aKJ9%s3bxq`qPCF5=JmAmgcYr=Gy_{tlg=>@~u_BH1=-^6w1wGeIUn{%vi zA1FAfFr2&#bhaAMN4nm}BfpTPuAls~k0yx;wS_TdtvLonfws&uG4NVpbhcS^a!2%1S2w`~#kIo|dUBNr4rkMs!zGD=C(82rfNeYMWUTn1rXkdhN4jlDePFjR z!@4Q&$jMA$978>tQEf=GTB1LQ6HkMfKV2*eqEEO9T|F*H8eLhlv|>PxpJ(z7aH**X z#&J5~!%j;hEB8N0^xvs6Nr0%4&vm?NiZ*GpN5fhq0iMC7kYz`XgWUTnG5I_#t1y`y z2d!Z`o)J$AiUJl8ZN81S>W#vBY++Zp7T=Ix$%L+Wo3f{>jjQ}@8$7kMbh}rR*m+X; zR7Dr&T~XS!bupG>>WwYq9`A(KU2y@0Rx4}*0_3>KT+fO+_M3u zL#vlE9|pzMt$u?CF=R5|R#N9@oZ24(T3`*&^l{(b;tJfpeq=UJF=i?V<3gNPz zFBce=Uz2Clr`qImXgZr2jJS!byDES=eJWtPWn7u>VEmv^Tk7T7gtoRsTU*;| zoS{-GC+Y8^9Y7qY)X{qQbj^npoK`h(oV7rr-ykQdnEE=EGL-4ZoQr z>XojI4D6Prnb%BhYZ@6B;!G!%4YoWB~~@evqU}<0f{bs9J=mu_`&FcGSZjVjGJa-x2IA z#i41FZ9O=sr@oHM%vO+t3EZZ`coh-6q9pRV5NlCcL@o?R%~wUoTRVbbTh{(mdd;tFCVuU^0XAHw($@iKVC23%$&2&*?aA^_gd>&&pP3%$}-moZV_N$U|f@vl~l*TxEzLo zf$4^K8Tf`P;>!^5LE1_}LRC&ef>zbp!NSTGih;orYxeLVu^b0W$D>CNA9nPzvl2La zs6Tu5Lj7UDhvqKY=H|BM_s!`q4Glm2asAUJ&372tYAw|^S6|Q`m2-6zTk&e;Hm=O7 zq*RD2SD~FFY4f~En-k;oQ?BNmV>nqmi>cvXx@1NWQ(|bWj$!J7F+ndSDuX%UBD&^^ z=X2>L=azJPcc!|OMs`TWqrcCnyZP^-(W6Gg~M=(f#LFH)t3^Q0fbmj8M8k^LUqrG zFJFG{aP?{r$qiFEjX(aVs^-2cJ1zbU(PQ@Tlf$EjAKeRR->}@+!1&<6(Ps5Q`Z`~< z@TE(uGw0_bHh1s7RxyA0O>q1CeD3-A`FZ^xkI(EbKe?2Maj(GSja}Q!EkLl^P+d6- zB_#|t;1~}B^QjdEHgJRq{9c^Jz_=9m1OpfNPYnD@W?=o_*~?)Wm;Ub<)9vCyF%1bh zIpDvBnKKk>@ABBe^-$xj18}QxD@|QjT_r`ZnS&kIBXb8+D3_<5<3$q;Ax|)HXa{wD zMC)m1YwrT~6sG_43NUbd@imB^_RmXPZG`D{l~idZ9Gs!Fd|Y?A?$SdDXlZGMoXsu3 z>XOobH3vQk(?51~bp(Sz9v&WC9=u!*&Xyo<0RaKfT^myH2dl!cP z-Q@r7BMEgebGCAHwQ{hhy}0iqQwKL!VS4(D2mSr?zkWhJt-e3W-sP`h0RseGoB?rj z-39%9Z=k8r#kXKpD^IAco}`r>ARgcu5MF*>p+B$x>CE>h{?JnQdrNLUK7k*b{&4Ew zO|@L0&JqrGz%yMT->2rU#y_6?tDz9+V(34J;(v1f^IJgB5CS34-;)L*Fd#YK#J~{6 zkdqYC^u%17!B2@CJ#XILTuavLv3}ualC3IFKsGUM+j&3|-bE~B#dsFRQcfaw10iW8 z29uqXlpKrk`@na+BeJZB=Ho^8z2rXrCUicYdMvao(62Y^adf)szw8qg5+EuY=SUlf zfra2 zi$4)57-E_9=vW@QUte=wv{^eaBc=qO@z(>O4HS(fp=HrrfT%Nt{%)in39gft-_OMU zO`oo_I0HS8n3m}Z{bj!|P8eVYi&rrv{8FeFC!~}EGgM=bW#QLVrHU#Q;?AZ{RVZ~ zcu^cX8Xs?wfIX7_*Los)<0gxC@k_&ccPV6PXV4|w9Pu!M`Hc-O!ZS=dx$$HVe{+Hx z*Xw5U-}(KnH_h6#ckW0Mp493P6BGCJu8bCS-*#xAi>lJvZ3+!kJqx(};&);rC<|ny z&9Qv#FbA1v3J5p|7LSUGA|_TB$HKyLQ49-IjZz!>{S;!mZ_cJ7GgMVoU%z!2)&qNd zg)!t{hdPJGO8-uaf;6%E`ugTm3hz88*C{iM^|My0`&d)M0kJYj4gCMqd1X9FX=w`( z%fiNIx&Z1E4dVFA3V6j5AkSGJVqMkCj<_- z1=d9VZUvdEHH+am#>K_;Xw1&e4!wT#er=ugtyOom9;Nuo3U;Wvk7L;H+Ao9#Mn^|u zK+9*6yO0q@WEDImkGsqr(QVfx3F~`ZW)ti-WxG%&vNdiwM2O zobFep-uP{Yx4Xp9XZ#C7tD>~E^+QMOdt62?2xR=IF7^p?BcG9wu<#<{QMAS3_S^K) zuq(@qY-~K;>!hu?*5ifj8ynO+UrN{YZlyh+bmYsCl&f{$FASA2dE^(U9<2c zHa|Zpfn7)J?AsR)n}C!bXF#+Mzox#vJAqZBwYOI(B_-t!7Z;b0Sf=wLo4$-rm7?pq%Z7x~;LW@+)XR)hyGYyUR3@_fny~F= z1=wRF#TPv@UhdgBecPJ1jJhsu=G(SL@A4R8_*9QzVYDdVsSv+=@X0Bf+sjv$X4N&# zdq=PKOO$lEX`8y21IpLN%UuQRu|nr}bXBuER`6w@;pQyWs0ai1{PHsMjT`)D?N2AD z$om<-?-!~G*u*3xZ9C3RPO%aJR9&+>PWKDP-X3YHojbjPhXkrxBou`Ft#7K=al8u@ zsr9(g=_s-@j~v~OcRUP=`g6GQ7}U#n#7jdH7ZTPIrycr@Oh@9TGdYT={h zl56|zHTO`4m;~8YM1l(BRQ6!)u=hj?PWV`>M4v(C=)~llZfN!MIjc-QrPZeN?ZNa> z9TPvUfYbea?8}$slemPXaM=lVoP_Jqvj(&@0ViTGEb&9`xxTKWfy_%o)ehv_TU!Zy zc6HC5KQHP@KF$;>^dEolPe3y#_rddZ??nQs2B;5T5D@k4$casX+7|UDkVJN(MhzGDN6lyXWCj zW%EQ>^rV<-oR1mY{+Mvz_M@!+JqPxd7RH6<7C#=#1K0T2kt#dO%Am()aQ;m@0q?z- zkrD$HYVWT%;JlWvC`J4=p_nstshV46>yy!p&}O-QHA^1Ump3iQg`wPq7m-QECnCE& z5=PXpZIU!z^zf>|+{gr5do&H~*%n^y@kSogu{ml8$9ZYZ%4;!^e`LpEBQJ9MOa3!1 zhmnGCed*$?wU2M4^dTRWm->7Z{7?6p@8cft@)9jKM<=9@#b z$Gfarbt$h_ABTsBCt8nMcQHf@S@Xm;9$A-oHM*k8hiY9s5bCv0QiKkxdtRO9>1nG1 zBjB;qipdcRsb46QIEJn-7cF)SzIR_A;zDX?iZha#Z{PJ3+7h*~8d|{I72wxd_C~#{ zT!q9sG#WF9^S{i>y~K~6LuX9q8z+HGV4x<$Y*^uxMenz+$Ho?_=Vy*CZfZ?LmUo0s zf)6d_%Unt?#r3UtI8GctSJz&o{Cf`o3|Bdw<9utlrix&GU02%`Eb-cB3d7&Mp<1r3 zhusHD3g-7eZL_5z^}`0w7LF%m6n=iQ5KO7shruDEWOjScNW<@E}^UAP!34@aV|U6 zuYH2I^^!)1DNK&gqD`(M-VNT$-VQ~hMM=rE(Eaw+b99wvq2_4MXj@yad7_<8OT)PF z?WE5QLmQcuF3avDSAEYnnIF83AVq>ZAmX&nE`I&U zz=6oFZOZTVP3*?N1pm>1f{Wk2n{$w>__rEw$;8Q=zn1aY-}d>y$&&UG&Nb z!g6*$>Dy6(NmHiRIE5lu_O;EpyNlhSng&!HB>`GZ+<6dimeQFvarmWb^}xol+a&jWM8b}UTW!hiI2@h4T`;+!J<2P-m75F5HwN#Z`-~kj7e_#a4JV4L2=NQ%!Q1pS;U0BNm-PSU(tkZQ(kjGc$ zy#z;VjmMNW88nNusfOpKcxPiu4EW_I%E=TDB4+0h4s&8V)4OHxqK!^{ZH-2n%XX}3IZl{ADE0@CdoM=Bb)l4+u%ACXN+B6<$L&MfPNiXk(-KC@U zdwSw^Tj-f4+2{?wkvM3gB2_mLa$4{CO}oXd%n-JRu_@aLYICq``uP~v%I`b zd$*3{a5{rSB#Nu69p-F>ReZ|*PjAI1?oEHx8G%4B)u+p95bA}RR=cI>sKPufM;HSb ztlul5#@WAY7NMN-ZOWN_coV!~ark0y#|tJ=T@vDxuX4`NFU)U9?YAdKM#=6Fteq-| zj?popDmvJhut)ftZBqDNg-P;Rk|$}})t}a%$LDTs(;=au1k)p$m?ajy)c49RT%Ma; zDe%t?9R2xzpp9kFO#Qxg_lh5vitznOj#_eZa`t%Ue)S1iPM*|9NmWLrH+~4}n;S(- zal-KMCUEmf|F&BhTln`H>k$-hjc4UGRYhs2si~P_2Hr@ZHN`UL+|M~|#!L9zoLAd} zLIPgpDI{@0*XMx{l6(0nA-?)F{rbuW zXMk|$7Z({Z&w`vk&wIJ7b}~yV?5|XsPgN=*~qwR7MRg zE_~b0W@E_9!H>Ieo1&-$Z7WO?`lyFw998ivU1!NEC{v(9Y+@hQ+P|!@tkZ$|)_v2SM`5V^q+VU^qn|J97K0 zC^TWx#%i$;`oVQ&WPIV1$uV?HP+%O0Lx=KP_z^qn5LO#<`#zU zTOE%2C%($0=Y7|Qj^}k@okN%0oSYK1*vFG?32D+7dSV-1H6t{bM|K?YM~6%qduAnM zqN!pHtmmxj&ew($m;9!xB6)m2{^4S;2U$bU1@H!Cefy?cnKLDp{CUMM8e&i(KZ!Vv zU+Oa|gyl`;!qnOGgK2Yn;w-u$o;p0k)k^QJ2;RL1JKUhs<0*W~p>RmWD6V zLNx;|U+%dg47cb_vpA?8RJhD#+#v6M@>*$S3{eI%x)Mhxaa<^zI|j%2@ZMSlA#W`w zMCGaA_0{$bjB^Un+$nh|f#b)4DX5SddAo_PKbl5l0$UghD_C*B?sJwNaW>DBJ>pQe zRlb-?8=Yj)7ycXbZ7xgOZ{2YT*DCHMmv|r@MrvJ_N8+A}?aaohm~YO`um$RlV!w60 zIZV`*@luDIw@PrcL8c2q3nQdnk(e8ok>1rudeh{FdOE)`&Op^Q#7iE7Q)&U2D&7AesBpkWFxy zTUEqaoC!^O+2O~AfZ8+O-Lr9%Doi>TiPM*WyI+xzlqUWDiAQo^%q+Rp$+u-C*o#sR zWFx1Y-YlnCm0_9s#Dhsh6v5lCj2j$ijY()Fk;0Uom&(N49xA>kn+Wo;&%8@0`=D#^ z__mkNaTnlW@dQPVE%(+4kx(*R+(wr7%HEm{kAv?DeA}L7`}Qr{$^^G%qi)r>f@WMrmc1@tB1_$L%PEVyQ3(Q^30h>43yCzI-X}PWCb8X^we&0C0((2W6U9#fm+902&#&OCZZjX&=3OU8wEowwxdvdOj_aQR$R`Pjml8z8P zCa8mukdVdTBip?puLD965s}I@gB&+_ZGu}Ve_4XtaGH&VCA4&E>4$wABj`3c9zK4o z-#M2~YI!2%6##3K@9g@AYECO+0eBey@Cls#$GwDqItpM+-hovykKvsA3~15ZSddUb=(M2#0hiGVZQZ!fBE-FE-voi2Vm_( zX_fZh3UL+yqq_ucynl;D?9#C{;P*Uz5uwN z;IQZV;0ey}K6){WsdmDyb~H;#BZV`>=8&Icpb+TdTlPwi>!svWcFxV@G5;dH#?lFG(i zDZ6w*4m6>mLv1Sa=A-*l2<+Si4yIG%a_QU2{+GJ=VhpCv(nqY%f<1Ayc+hS)wbo%} zva-28y>6;u(o2)wO~t*tQn`VOnOQq>JVd|NGafqCvf(Kv+69xsv=Q%5Qnj0%Gzp)fk%?S))8 z{?7P8ZMna*(V@GvnT9c9@L_Duox{%|vrNzS0tuc7)Yf$N5gjAuu~#dk)>~@}l%5^_ zTRDDM$D&7A%h9K_mHG{j%R^nYBO%j5CyVKRt2rM|`{h#I%M`9v_Dmv>=^bLe>1~i#UZ})62^8{cl{jI~ND5`w$bY`S`1Py# z#vP^);q{X``TFrUmL}!aNi+}B@<-CdMGAyN*}60BDi~Sm)Mi}nqRq&6t#%e~ZO7*0;RvGv}Z8ZB|2 zW(x*cd24f9b@+uNR>uL({n<9XagO!l5Sxv2q)%dNyL2aK$%p4Ax~W*p-j3Z@dGkc7 zKVEio57|m~m_*VE(4PHltC@$c1etaw>aM*r}RS%i?tq3f& z@3=*TH#lKR`D;1SI#%F4c<{^^tc2@5L><*vn#CJ2G&|ga?a@Ea2Y+Cd4k{S$D^0Uj zj>U2F6abh0Ut*pw)lQz}yYczyC@70FCc&I!?~UREZix2YJ0~k5WQ^ft?!?d-YsWah zf+$ONf8gR5o}tgwzq7}xk{8MSSfV(qf2-&Zs|y2*;=%!ted_a@aR!RsxB;Z(B_XnT zzjceu?*O)zfokK|ivxJFlw@=5v!0M&cPi%wfcYtEyko?|BgGEt=;-jJxGa|G`zT-I z7rQhq8fRzq`SNr+g)nVkb0pqt-|5JL?W@0)O~-|7%86cl{!Ky~1B;(tRQ0R$i09>B zsp^G$!(tBjJp>cD9~^%OA%33J+kgmN8LWkV=?2C)VEOy|t7l0*t~w&RdX+ff9Ao%N zk`6b38fsQeetCpV5CV8b@3vUErGFuaPfXVxT^+BV*3E8zG-EKIw{b8j(|>|C@$xEv z;eCXok?(_s@T~XNQjCFK@F(*-aPBTOf}Ym}XWj5)I<=hCIKn{wx}9qt<4CMNCDGQRaAQvMHt zbrd%zuvSPlJtzmM=E}QynSNynfA%cK@7O;Hi0u{9XD=ze54lVjU-Rw3#NNy}kN4gK zjj{bqi|Wp zlS{qGG~r_)vCX=>a@v8Rk;e-GyMDD^sZtlaMsB&Rx$cTOdEIc-b$e)G7WWPkn<15K zcOgEz_rWc`2EiF`#4Ro?@>H;UJdoj_xbOX};p{`V^Vb1PtD&4)xL#-6qjIxj?Zc&2 zP>wFQ2`d260VpSoO0eqYEBNXsm0IUT=tMaqkH_rPPEUnOL`6l>y@EMaHm$-tGEvm9 z^nh8`?d@%Ko_mTP5OeS6{AaWtFC`gVQaV*pwci)7|HY^=uyB+=rK#=bNTx1iC|clp z996rNA4aD07H@1UaaC9#nK$f9cb3zSwL~qle5))HIdt!8q&kc%dG#gD#J>-f1L1?*<{A<9c@sn1UVVp0#*LS}j1ASKOOI*E3( zK1OdQF7+C~S1YZ71S%0vP=<+C#zGi5Q`cC@T<2i+)8hRrM{6fy^OaL$ zT3aPqjp|Z-k2>Yy!aj(e)QS;v$r*nc1{a4m8HFoHZ=L;ovBR8GUlRTzLFlmDG}ksBNFh|t^~$Jc zOWWx+n5O}m*15Mx$3fdcxOAoUXe@ue5>HE7Ih4KQc3J;*AduH!=HXF4+C$NY%gONs z%sypn9x?P+3(DIeV}l=quan*;VXztZD?WNz5`1ZUv9#h%-`W6Gko(_0L zey&a#q53hb&UvfZA1)FAze>aXQGe3{LdW9D8*tP^^^fKHeedeP33|oW;j-ApNOFCs zx6E+A(F?VU^zo0+lt_nJN;ee*lXjY@88m(xM{~-oPgcJg-mJFc*=&!Zf|bt1@fx`X z5fWUuH$bOf(rSiGZ6;uzD-hbRO;i{dd+qC0`s!wJ7}gl#z)wbpoCuvarUiBt)y`vI z{sG$9*ch{_tErP8YBH`s;@0O7o*h&&zi4Zk zILasJdylgIKPCv;!C)|t%ifUJC0li9?tatu4lbxRgEluf&UgK9KQvSPU*_o&XK zYV%`UxpypNJSdKs@m;Y?v2n>0NhvA4vi;7jM`n_^Q(Z7lP=0?(g8yl~{Hk_pYg^lW zEo88#)6$+CZ}DX1$}0~C2ZxIM0lh>vZ0|lka{KX(D&Hli0H<9ZsBSJ(nrS zsbyd1!4qa*7oCFtt4O&MD|zl4s}756mE2ro$inBR$K5NV-HW3-ObU-5%b^Y(eVm+~ zV}T@A;nlPU6yOD`;ih^SXK4jZ*92_bL{$pmtOEitLlRe5_m>cv4jYnmot9Mlq1^8G zg^^WoYM0T%`-(He`R8h4K@rY2Gna{}sNksOD=uxD)ef;o`?m}ILiL{;mzR0(>+f`f z&ew5rFWGv`PRJe|tg@XR3+M6Fmv&SZ>GUS-rztx*y}|K58nm`*X4ff`ZI3cq%uf%9 zfgo|=+Z&UWGYx`ZaOdm%4;=}JvWR$a^z-N3E)n73B*^iRUhf!I*9!lgp4-3Dc1BEO z^uVk8ML9mzv*jo6E7j{<^%84&$Mz03>ML^9bGvrVhWc}YyA}o&UIB^l(P@L~4Gn;K z7fU3fYgsx6-_QHn9924n&>+%#y+uXRFu9E!QL_c1k$(oWa_CEx zBbied%fn;U?rGO&WNqVR)z+?<1@$n``BrEjtWPnhT%}^v$nW9nUhhp2m;mR-Ge>p4 zeDglCbB9bptGPIh!=zE$ef>xbN=g>hJh58VbO)dcls`OkwwkU%_}2J_8#bmiM5~*c z1~-8Hizn(=WXM<|A|vCYbxQb;+3aRdB1b=42s!~i?weEQMGK9GjlZ-S0$iU8)ct+^ zo-25^N+nnAL&Ux3lHNWww(c`0$*o!5qW)SDJEvbT*Lnj905>5KaDk18d%&Vku=*%w7nv?RMSyk6 zGW<;rzjQ)w+E<*B>!{rDBf6GyZYNIwT%!3#ktQN+}DV*F35Ps1l18?2^N$ z3JU|DL$df;Zwol5XqFi(Xa|%Vjuq=cQ~zN8v-b!bO3Kt+?`4l1&qE)LIaM7sa-!}{ zh58$Rl*eZN8#DV;U4z~+XP`;J{%bKpr+dT1w{EdLC8UZ=_dk*&Xxnib&g)H-j@*cK z;P<6VWYbO@H%_*P1TiTY$fkm;yI#QKa|4=M=0AUCC1clw;gjT%HL5(jaj_fJvV8iw z@XB6P)?@XviI_E7pNlK)to8xHE9w94MFa8H)>aI_6_ry}jk#z0QI&DxMFLinuVGt+ zR%?I12{p}-%-PxTOWT<`Ig19QDw|HJ1(VCd*GCsQa$*`95TnF<^XVG7a{HN;2A*6R zz?02T#S5Jg=&*mH+SRh!thxv*>!c~7R?zGD2X_7E43e5+s;Kmf3wb|@5*;La_ToiP ze5c&2xLwkeW+~*JOWCVe#jSdV1Cr8`cgf`ftu6dHhel0bP(kR69I6>Lihn>G%L_$cBc+DFQzF z-uo-Gl@17YT%xt4!`-CLts5a4kariubR51CIx}mMVkl%wMLaJ#^O_Yj<(boU^Om`W zGUk5=GNjZ&p`qBT4+G9mJp}wuY94&U4ZWkMaAhmJUf$-F$hpJ?I|?(}U1LHVfqT3( zBH+BUFh_j-`km3j(S-L;iMl%S@vrA<&l6x`+w)<{knJHv7JQtX&~o?Po_@5M_qUI3 z{iYKq86BvJ-fQdMrH(1s`ogzJ`iqs+^1tLmz?$;?0nAI6pP3cLVR?W4`ia&7St&}H znz9(qd_096`hQmHa-x`Kqc0O z-bF=h*2>K`ou~ZTUm0gX;J+QnjK_Fig+HWRInoqY2!$_x+Iz6S;{^Ls)^w(MjC(Dv zwH4dT?L>D1d2H#z&c~+=F|IV`GHGN><_|DK^a=i{2lzFfH_4j_(33q=tSebB?_~yT zK9Dk2Rp=m7(dsYJefFGE~*hIUo7|x$ph(2gsoaRN{1uuvRR_&Qjf>r>CF6yjOF| zMIpS>w(2jEQWd0QoW_yFCDrlrjY=*uaRto2-gG)f&#F_}Kq*vXBK^XbLrV~je7Su< ze_?J9*D4aTsuc%ivW}FQ_@jZ?p4 zkM@&0KZ^oZw|vOuYXt2(PI^*622qQ9g&|N>jTEnNV%A+B-)a83&*&WjRKVihvK&t* z&7jP;GLF53^95&NL6?4ZKWgAO;=u~f2=O8*c1Nz^h7KJmsflr)cJ*ewYe zDqB(jM1X?3ZH0$(tgaw5mbKyBF6Dch{JKIyLb;}4T|AG(omDy7an(g{kKo@E6B7dr zOCe-=u?5WVo(o~YlNb*ff`gIkuIQr8DF&2-{N-#E-sA3mJO(xkYj zlzcDgc*BP4{KQ3m3G|YVoBK`Pwbb>jkU#tz&vr(~)4Pd8Yf%P|zyOCOgz7 zW^euw%viVB~<+rxCD|8OrrQo-ZD>kSG^FP)6 zG&$ByrJN?DH$9^M;%KoLX3w$ZLqPUG>heWR3@H|7Q@O_kRjyf&R{bI&D&aWMMp3n+ z^pCI~*4O_G=CvRx(1#A>{+>QPT!im*f%ep-@oa^DvthTiOVJT_dW?Pr{p1Q0pUjB4 zU^Ay7btA}j$&k^$)uqw0GvNK=psT`#Eg?_C2|vAkJg5yY&Y9jnxkd^qGv#sEz;*uo z&P%{;rRD`d_UlPKhT&f|zZb8!$x#)Bkb2HHR@m34%;WOGbhI=dwK|9?G0MjXDR+9W zGrzE4z9LXx^Kub=o6q)6e`G2xI54;AaXP?qMvb4-RhX!*YOgcW(hl4r^;V5M1gM^f zU~z91#%`XoBZZ@BaB#4ALa)f!(*E*5gBQCCQX5D02u)*-CDwFSr(o>)D9d){$OwjZ zDCbKfVs2?^$s0HEpRk%$Nd-R&cF$EvidPZQL-?1$x~2sbl%z-2J?`@_LvJkqdkSb(L$S+mT_4hLhzqAx@4Z$1@@gi;PcRv2Jo$EmCFJtN#3Ls^f&YW-P-DR^aZYW~M!}Y+#$t@+7q`?)z3l;#ik1weie;exH_@r?im- zWwSwr5Zz49=**G(qR6Bka^%tVPO8Fue`PUmJzCqB)d-AEm~hE6XipjJoM+t4v7b50 z1Fop84oyj01<14|68J<-k6}c^IN+kCWfT7djC0X#HJ@Ig{RLiYuQv-X=vOb{oJd-} zL@@}>XSwBUZ@-yGq3A68(qP6&u|IJW9ZolG>q*^7dX>4Ekz{2IL+@sk0f+t zY9sXNQxejyJl5z7=M+ap)Q(oCVdu2!OGNa|r=gFhoHgR^D8ET!97K8+9&h+V+h&+G zvq0x)9YzG3<9}e&A8$O)!eSd79AtW#?T~*m4}tCjgv|Jk4p{)uSQHHSHal%UwkKBW zy&fUZ)2juP1lqDtv|+Fnyh$Uo%Da^^;Jsu&UAb zfJ0YCtqU@A6ZZAfuhQ^Ib0&G{{soQtq>E~x93^%>AWR?XMD-kOs6F|K&Jbphkv@65KwJ>bf!yOA7v!@$n&i+r zc&X2$9H2Ls>8Dd4?OW*|iH{`=@eCzJ?T!uuJC@wVhNzXmyEnz zGmw&!L4X^_9==5Smm3_M9&lQh<(XR3WR9uVI^RbaBVm)cC?cDR#V)M`!A;vcWl=OX zSf1Wq+``O$3rof_W0>Z+3`i!KFp`gq$YfvUS$v-a`90W5M^Eka9dS)7M7=g|Sn*=@XjEl~dPb}nl z^llfRZZ3!zE2$?^Kc1Do*;Fsjrd@0b6Bxeci-0{4bX#$_D7b;&+vZFxA<4v|g`8K~ zS?VkT09Y5mYR*+kR<`JTo1iD*b8wb-fOn*dqdM6kLsOE(`~<>T@4o)JDrv`jqk&>+ zXU0RPivfB0L~;oIEt@niB9n z>*cr6y8bx&RW}P946V}3b6D!>9D^vQJzz5XK*;ajt;3-eROwyrd#HbZa{+o#Om=0f z^Dh7>E9unc2mI%ja@M4X0d9l)+D9glLQyqa+Z5jhYb5>|fd43ArfF>u_O^)7wjSJW zo?ee1`!jpxtoG?3-#z?!vPU6x95G4T{vMYWZ2Nqn9cP5tslv$He)+`{V)8>1HrK)r zwcml_zmL}NzB1PNpPyRp+eyYmZ+ z*x5Sb8lqq1-T?KRW?fR%6PTWv?s;iyYHCMaKl?x(l2M`Ln$bBMJ1DH+Crrr9oWv15 zx8rLuH#2RhmC>c-$~3Sa)$`)m+is!#6obt5Dp3<{xck{BfkjW(F?|b4b%=&;zl6BB z`5aBX-IGmQ4e>u?Y0*qFM>M+`U;*Nto{gUe$2p10j=Q|jICq9Jvn-J4>u^y{78Lzg zq4hY~*7kPn8#5DalM$1+&`{lq>R!Nl4*4kuB&8dR%8HQQxbX-*QG7Ynl>scsiu~gJ zMfT9p8D^QYtsZo) zEXGZMHiqpIZUf$n9l!;fV9L1&Ju*Jwc|M)7@VFbb4ZljzCNt?bo9}w*zk_NN{@1m% z#qK$UO}<6oE<{*ShXc$;e@5R6ae*GXV7Ryw{2GB&k=BxJ5}aLo{$^!WnFd$nD~tcm zh0=m9I9p*neiz=U7cGE2u^G3F+Ih>%E0Tssa|;rn992GmD)+Nf85bxisoHo8;*_R- zg*kk_NJ@J`*rg+Y&DWge6PbGNnI90IB%hi!l|M5}Ib~dkNGwR5Wk~pM+*_3H`a_jW z@hv)TNkA;LyjX4G))OU5FFOIFNF-R05re!Q=kb_Ipu#6N_txgmejOe*P-c3ig@uA1 zi$7h|Jm*xTr_b)B*`DtI-UWaUWFa{fkAaq=)cB-VkZtxV;Ewpj_jI#oXA-lIs-d|Q zD?cF_qL|k^%0OvXnnx(Gu<$@RW+iE!8hneUtZ2VdI^N zB?7O@+QiJ{XLTJAp4^{$3ADo_^#x`h=bYCx6gb`NhC`|K`om0Fik&dov>a%+y=te4 zQ7$}=l-v$orQ-0}@GTJr>1V)A4Rtbf!7aB)rr*TxyC5%9k*tB}mMJvX zy`!CJevWW2HVA?OAb*W@)N+^OLfq_FC>$GCSd1|qR}m<@l7@7LpcJ0?NR9j#jbknv z?>)Lp3N-#CjWcv*?7`R5Ap3=9(Ql76-wf!xce6_Vj9ID^)I1PW0MgcNEp$+;gFZJO zfSNyHb0;<5#jFA4D#eX;$Oe!WOb$^OReBv1L9QY9oep^YOUH{OynP68w8(K~@>hlX zelA(B>BQ+uEW0zD54vt*(nJ|Qus&KcOxr%GFrljaVq8tCnM3UL0P&-8#}*kNDine8 zd-=}-1-Wp3w4dHv$K0#_wl6EsKYhA>VP)X^eZ&Z(qSDHS*QuUfH{*3oQt3B24|VfY zk}a`fy$O#h{@CBUvcmhHDR*a+=9U(@2F=$WHe!_>+wEr(!ouIshvTy<^wfrAXM282 zs%FjqSu)paCUCS%Pt*a}z~+yvtg?%o>K!l>cuu!a6Tx+nf4FhuM)?n@14VyE(EB@F z5M@3;bma?b;l2bnzk;M&0qMTCHzQqztcIr4E2KFm%Awicj&VDHgnuhQ^>K;MC6hxCL5T0%MQ zIM)!X$#AFG`L9cM3@a3xQuO`j(Er3kV`4?Sai`?6rO_SRU)s$F>s{_}DW9qpf?f0E zZzuNND8gb%_dSZG1iLmTtTN6Vp#u!DutFA)=%wWH1d+8$k8vZkEJ_`E=k8tItgLM4 z=XW0J5YxWZky@q6DijAdH}}r$keBn(o(P{CkYvnp$){G&wRW4R-SyF{ut=;_e*YwL z;p|wyvopROI@(Utk;tC3h>8V012Xs1KK*_>{XiALl!FL>t>pl8tK?-@X@#dzM!7)3 zi%qmb2BKRfOB^4UlW@zXozO^&W=d-yFLiCINd|ze!w8t#bdT!?q47 z_)8!(5pk3P-v0$a^tbB`fbXzq4nS^vxS*>5FA89Iops7=y1seEys6v{k!|eVr>xq+ zUQn1aSKW7jDgP7rlQDq*mZl1zDq6#GooJ?ZOMLm(KXV9QRJ?bldd!+((F3IhAFySf zME`LI+`KdW5kGGlD5uXu3g{f|2gvrNi!hfV`HTv+OXz?Cj(C1!6{=~uGNjK&t;sD! z^T244j@CiP2#@E!;_JMINoIuCF5eJP-bQv+kVV*MFP<&YrlaUf zd(N%lNJDI#unvUAIZngD=3LQ{HT0D}po9RCftU*KXn)*j=iL<&=<3*}qWf^iO*4L+%l*QD$H-+;_VB z$HhjviUpQ6+jM*uU9OXISdM*+>NTcAacCtS!VuxW9{RdJ zWE6Spek`0fzawdNyg)HZP;2aijm2D2=r>6{;4K2h#>nZnhl3HIT!rN{9*+%!tRxYj zWbINb5J16@O&>-&3xtj607e6~e@#heD^Q_cRa5Wta`|B6RO|A|rc=D|&QN#%MV)-H ze(kI|Tdv_!iCp|mwqX|4qrG*Gix)lo1x)aZ(WPo-S9rS)NN*Zccy6=R)~jj2@1bxG zJx9HPV%6IduOA^bOAUMX5CPNqSZesf4c*Sv=aOzQcPKH9envAy6bc!69ftq3EO zQy$otckVSR{}Z{0(x=UqK^DM{Y#2AW^dFUv`cGHRsITXFSI@vt@?JsWFA7Qssspp1 z=hqyDPNqt#gW(W&_9=G7h@_m*g=;j!vj=!A=~d5uj;vWivC@@SSsjR2Vsn%Hnb_OU z{Cw^}AjaUgn`}v3Mm*7kRABjaWZvi--nc&+>OSyM@IyW>WG@{809Ams`(bS6b;yrs;vEdsv1vbYAMb8-*tkKRv80dUA@ntbGlx~G|z zdt4E|EvjFPrtf?s*1W_JLnRA zStQ_zW}&Vgw6r+x$eM<}8`vW1l)D&*IQn&GO?;gaT0cm4F7VHC`;Z#_WLh<{H7#G(-GY)W7t|i+xzz*&Z+}+(>0zrcl+zBMOySsaU z;O_43?gV!T1cJNETcq#3eY*Sf`w5$GvG%O0DPxW~>ZfM0ukn@9-Fe;Da>2q0;%SWv zqKsAm)TbGtRl8L5iooSeKuTnc8A*)$)G(E-&9hNwIKVNbE?iY*^Ld@Jt#{?u*w6?R z#&*-r+ydSsgvjMhz&{w;0rEtRpP`CY?qAHs)6sM0a@rc_^Z82NO0MnnR;j_H417G& zAp5`}Q~kHO@Suc{$*@*4y5;J{fZ`_;%RS=-fYD9U(=U32ZFrJio}%OSWm(egXh&TJ zm_d~3q&earsnaYZ8SB})LGUoi#&*`IRv-=eyBr;fK65<^>N)N`z0o7;WU<-;zxNFl#~^Q1_raJ9@h=f63cSpb6*ZHa?RRS^gc(@ewrav zT;GNo8Cc!!cq0Q8bAanGk$?Aq7TnNrnDR9IJCP#qN93oFrQd?R_&^Z+o7#dZ`jr#C zJ8sKQb0{nb(^2!cJfL ze`?mW)!wmX#}2{^JuO6f!o+wY$q*aIfh~pB)Ky#9zegJ~^#F}HnxqW4oY(2La@vjG zx@(?ky`TgVBf)6H7oTwHADSWztIw>Kk^hA>8!h)b(*~1n3H$?}Ls(~!a_#c_>|xa5 z>uQ@~V`*Ge6E824D4~a^WqkDiXukbpjQ|OQ@jC%<$k#%g$XXQq80_7lU?Q?%$D_D3 z+B6L8TjlmC3>U=zsCv&OI)D6NjdIP#1?tjJAtR%4^OxuZ0S9eg5%qUD0>H!Mg+Q&- zL+G*oX52j8xy}zSNW-kbneve$Kd}DYrcFfAy1IP3-O8q@U?5u|V0yszO$^2B+B_nk zLe~<;OG=qEHQ*8epvfqy)B5z*#^5@}N+m7Qf4~#3-y(Y8)hbx2$FC2-L$S6-zS-J2 z;(SMFxQa9gaJ=i+&{W()LL47#0hp~JRph_y5$D%EvS!j9{Q8&!*v5yzker-2i?&=c zNvYs^`Uy+P)+Y}Bu*5OTk^eT}*+jIF`CPd&JIk&z0t!&H`O^bJM+CdE_hk;@asHWk z?u$3WXM36uuji#peB*6jod63(n)5e60f37Q!h%4cL4O!D#W6-X4!=VA_Uucb0l{H; zFI8{xz%cuU4)c{hrI4djsrCIP0M2A&oUkF}FWdouSm7&^As~rJ$W0bWGt6$g&GibH zmp&Ucm8#d!%wA}{ZV54!PS&)%pRrpxqtiCr{3n;yQGDPu+xDMogZ?93hgN(0`1shn zx+?lH<9R^Cu`LeQg~B2QNH?UEmE!@26?2U-4~>ok255iT*h;l6$(MhIb#Zncp1x5n zAsPpNRqR65$X0GvQz@B?o}6UjcDC-gdPiW>HIwmAUcJKO6NJ%ly!z+G+<&8tWk3Ar z$^-afdCN$gud9?zw6U4-k%@wt=2Lzmx=Dxjgtt`FG~wUL0%~kj4Tul+&aaK5ii=P1 z@t?c6m`^IrTbuw*%i$b|K%E91;R>LA`!9%yLt|GLG0T@NO_qZ+a>W)^Z8H~r-YFRJ zigq5cHO=!XnG6m&d*4t2dy%2S0^R5UI8_Ot{|UETYir)>ddG#21vuY!DHlqp@vHuA zV8S69=(I|^ySoR{f0GBxD*41X5?_Q?%7{-i?e-bachmVsuSsIJ+eSaZ_mIoQ+al$6 zj{xvIrELF)u$KQ6TO48YlVZrK<9N7|(em{)1Za2iGu^#(0o}9l=QTl&t7^4qo&0DM z`765m_YVKL)rnp}k;Nx*QTV*EUJ!#l=_UUKUFrHebjAK;jS}fY(o?wv)zAWy+`#tP0AZq*wg3YU#S+Mtg+TRuH9A_pZZoDuCYf*KF_yvA>02t7jh3&U zpKQSY_P>ckXcm;4?YZwR;}Tfht`(DcO^WW`wrd-c{&u4k(D z+M3*PDI6{FrfRM9_0=@?iUlsW$YTGycY$8X1qV7SF+jI(csy-cg(>?Fdf}1LA_62* z;lb_e?b?_yu&^<*DecT%FmNgWDN!=$THE;Mq$AkwdtL<~B18@doglw#fmQ#yP@&P^ z_%LF~aiYy5SgQKHn0DRsA;G=j&P-uFN?OJ|+_g{RV4n`PZFqK56pDq79ZF)Q9R-zpLScd~u z%9t)4umd=UXwL2^%P>d2l5GRg)2INeOhq z>zV*1jkC+kXjT(B=?WeE+-rJ=oeiHS7O&@Okt=DlG~`!is1ODS4+wO#w3EkZA!ki- z)MT%~EFmdk@kwn^i`5rjkuM63|4z-!jD{{XMWw$fTi>5umujikHoEwR zkiYWdhx8ND`*Q+OSA*e~s{&*yEdYu8?xP4jCm=*Fy z3{r~*?`#JveyNATyzYk6op#&yqX*}*P z{bpwRPxs9jyDTnF0&ISM=o~3o7w4>6JMFo)D(y4Ra7{zBC*JvHZWz<`tKO8h7f!|- zh6#+3JTvMWZU9|h0KrjJpEBsVnMxM-zA+yMpEl_YnjZL{KceUa{pANC&>+!!+s6e3 z8A3%4ytL#+ylaC-juP|t6=`q`SkN&sF_U#>jLe(s&GdpDE35@ye*8ivAV54=TPNaB zQY#%#bIW7^zd4|`w<`5ecaK#Fh8H0N6j1}A>3-4;?crbkF4zgoL@m%7E0D`TZ&9QB z%w~Yi%qg8}_fDtHvMTBQAd?xTpRXUYzYaFqv_kQ>I7+!r+zKz~iq>jy)lxM$fYy9E z^djJ&K$}r_{Hrd5!Y(-omp8sp4#fpFStc@W@L-e*9V^)85KSBg=50{1yTkfzbW7oM|q)WWzWy!jI7F9uZA{4EaOjQ)*REX>E39;VR_IXoFSgxT^KZ&;jSXm~wZ{}7W6K@&t$X%ejO?fmUQ� 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

KVn-`d`kCSqV|++eNhQ?gx{WR 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

i@Nx=jX6S<*wR<}vcuI` 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 z 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