Policy management in Amazon EKS using jsPolicy

数据分析
容器
海外精选
海外精选的内容汇集了全球优质的亚马逊云科技相关技术内容。同时,内容中提到的“AWS” 是 “Amazon Web Services” 的缩写,在此网站不作为商标展示。
0
0
{"value":"### **Introduction**\n[jsPolicy](https://github.com/loft-sh/jspolicy) is an open-source framework for managing validating or mutating admission control policies for [Amazon Elastic Kubernetes Service](https://docs.aws.amazon.com/eks/?id=docs_gateway) (Amazon EKS) clusters using JavaScript (or TypeScript), which is similar to the way [AWS Identity and Access Management](https://aws.amazon.com/iam/) (IAM) manages [AWS accounts](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-west-2_e387ed0314eb9c79&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=VbKKL6uKA_VWnnJ69LKIgd0Dryzaa8nMFViVNSQtKOU&code_challenge_method=SHA-256) and resource access. It’s also possible to write the entire jsPolicy in a separate [file](https://www.jspolicy.com/docs/writing-policies/policy-sdk) and load the policy from there. [jsPolicy](https://www.jspolicy.com/docs/writing-policies/policy-sdk) offers built-in functions to reduce policy development effort, and testing frameworks like [Mocha](https://mochajs.org/) and [Jest](https://jestjs.io/) can be used to test a policy’s behavior.\n\nThis post will walk you through deploying [jsPolicy](https://www.jspolicy.com/docs/writing-policies/policy-sdk) into an [Amazon EKS](https://aws.amazon.com/eks/) cluster and implementing two policies—one to deny deployments of resources into the default namespace and another to only allow container images from [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/) (Amazon ECR) or the [Amazon container image registries](https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html).\n\n### **Prerequisites**\nFor the walk through in this post, the following prerequisites are required:\n\n- An [AWS account](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fportal.aws.amazon.com%2Fbilling%2Fsignup%2Fresume&client_id=signup&code_challenge_method=SHA-256&code_challenge=vyxQMX-ymfRsXRnAXkkTb-pcVgmvGn31JFhzQsnBZcs)—with a user account with adequate access to manage Amazon EKS clusters (See required IAM permissions [here](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html).)\n- [Kubernetes Kubectl tool](https://kubernetes.io/docs/tasks/tools/)\n- [AWS Command Line Interface](https://aws.amazon.com/cli/) (AWS CLI)—installed and configured (*See Installing, updating, and uninstalling the AWS CLI* in the [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html).)\n- [Amazon EKS command line tool](https://eksctl.io/)\n- [Helm v3.0.0](https://helm.sh/docs/intro/install/)\n- [Docker CLI and Docker Engine](https://docs.docker.com/engine/install/)\n\n\n### **Solution overview**\nThese are the steps presented in the following sections:\n\n- Getting started\n- Deploying the Amazon EKS cluster\n- Configuring jsPolicy\n- Creating and testing policies using jsPolicy\n\n\n#### **Getting started**\nBefore we can get started, we need to set up an [Amazon EKS](https://docs.aws.amazon.com/eks/?id=docs_gateway) cluster. We use [eksctl](http://eksctl.io/) with the cluster config file mechanism.\n\n#### **Deploy the Amazon EKS cluster**\nWith the necessary tools installed, launch the Amazon EKS cluster. In the following example, the Amazon EKS cluster is deployed to the US East (Ohio) Region (us-east-2). However, the ```AWS_REGION``` may be configured for [any approved AWS Region](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/) where Amazon EKS is enabled.\n\nExport the region and account ID:\n\n```\nexport AWS_REGION=us-east-2\nexport ACCOUNT_ID=$(aws sts get-caller-identity --query \"Account\" --output text)\n```\n\nOnce the region is exported, create the ```ClusterConfig``` as follows:\n\n```\ncat >cluster.yaml <<EOF\napiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\nmetadata:\n name: jsPolicy\n region: ${AWS_REGION}\nnodeGroups:\n - name: ng-1\n desiredCapacity: 2\nEOF\n```\n\nAfter the ```ClusterConfig``` is created, create the ```cluster using the eksctl create cluster``` command:\n\n```\neksctl create cluster -f cluster.yaml \n```\n\nThe eksctl tool needs approximately 15 minutes to build the Amazon EKS cluster and reach a ready state. In order to use jsPolicy, it must be installed on the Amazon EKS cluster using [Helm](https://helm.sh/), which must first be installed on the local machine.\n\n#### **Update kubeconfig**\nOnce the Amazon EKS cluster is built and is in a ready state, update the kubeconfig file to access the cluster:\n\n```\naws eks update-kubeconfig --region us-east-2 --name jsPolicy\n```\n\n#### **Set up jsPolicy**\nInstall jsPolicy on the Amazon EKS cluster in its own namespace:\n\n```\nhelm repo update\nhelm install jspolicy -n jspolicy --create-namespace --repo https://charts.loft.sh --generate-name\n```\n\nValidate if the jsPolicy pods are running:\n\n```\nkubectl get pods -n jspolicy\nCreate and test policies\n```\n\nCreate a policy to prevent deployment to the default namespace. The following policy prevents deployments to the default Kubernetes namespace:\n\n```\ncat > deny-default-ns-policy.yaml << EOF\napiVersion: policy.jspolicy.com/v1beta1\nkind: JsPolicy\nmetadata:\n name: \"deny-default-namespace.example.com\"\nspec:\n type: Validating\n operations: [\"CREATE\"]\n resources: [\"*\"]\n scope: Namespaced\n javascript: |\n if (request.namespace === \"default\") {\n\n deny(\"Creation of resources within the default namespace is not allowed!\");\n\n }\nEOF\n```\n\nDeploy the policy:\n\n```\nkubectl create -f deny-default-ns-policy.yaml\n```\n\n#### **Test the policy to deny namespace deployments**\nCreate an ```nginx``` pod in the default namespace:\n\n```\nCat > nginx.yaml << EOF\napiVersion: v1\nkind: Pod\nmetadata:\n name: web\n namespace: default\n labels:\n role: web\nspec:\n containers:\n - name: web\n image: nginx\n ports:\n - name: http\n containerPort: 80\n protocol: TCP\nEOF\n```\n\nRun the ```nginx``` pod to test it:\n\n```\nkubectl create -f nginx.yaml\n```\n\nThe cluster returns the following error, preventing deployment to the default namespace:\n\n```\nError from server (Forbidden): error when creating \"nginx.yaml\": admission webhook \"deny-default-namespace.example.com\" denied the request: Creation of resources within the default namespace is not allowed!\n```\n\nCreate another namespace called ```web```:\n\n```\nkubectl create ns web\n```\n\nModify the namespace in the ```nginx.yaml``` that was created prior to this from ```default``` to ```web``` and deploy it again:\n\n```\nkubectl create -f nginx.yaml\n```\n\n#### **Create the policy for the allowed list of Amazon ECR repositories**\nThis policy denies pod images not originating from the allow list of [Amazon ECR](https://docs.aws.amazon.com/ecr/?id=docs_gateway) repositories. The first two entries in the policy belong to the account owner and that belonging to the [Amazon EKS Amazon ECR repository](https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html):\n\n```\ncat > enforce-image-registry.yaml << EOF\napiVersion: policy.jspolicy.com/v1beta1\nkind: JsPolicy\nmetadata:\n name: \"deny-untrusted-registries.example.com\"\nspec:\n type: Validating\n operations: [\"CREATE\", \"UPDATE\"]\n resources: [\"pods\", \"deployments\", \"statefulsets\"]\n javascript: |\n const registries = [\"602401143452.dkr.ecr.us-east-2.amazonaws.com\", \"${ACCOUNT_ID}.dkr.ecr.us-east-2.amazonaws.com\"]\n\n // Use template.spec if defined (for Deployments and StatefulSets), or use spec otherwise (for Pods)\n podSpec = request.object?.spec?.template?.spec || request.object?.spec\n\n podSpec?.containers?.forEach(function(container, index) {\n if (!registries.includes(container.image.split('/')[0])) {\n deny(\"Field spec.containers[\" + index + \"].image must be pulled from \" + registries.toString())\n }\n })\n\n podSpec?.initContainers?.forEach(function(initContainer, index) {\n let imageRegistry = initContainer.image.split('/')[0] \n if (!registries.includes(initContainer.image.split('/')[0])) {\n errors.push(\"Field spec.initContainers[\" + index + \"].image must match regex: \" + registries.toString())\n }\n })\nEOF\n```\n\nDeploy the policy:\n\n```\nkubectl create -f enforce-image-registry.yaml\n```\n\n#### **Test the image registry of the allowed list policy**\nCreate an ```nginx``` deployment in the ```web``` namespace using the ```nginx``` image from Docker Hub:\n\n```\ncat > nginx_deployment.yaml << EOF\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-deployment\n namespace: web\n labels:\n app: nginx\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:latest\n ports:\n - containerPort: 80\nEOF\n```\n\nCreate the ```nginx``` deployment to test:\n\n```\nkubectl create -f nginx_deployment.yaml\n```\n\nThe cluster returns the following error, indicating that the image should only be pulled from ```602401143452.dkr.ecr.us-east-2.amazonaws.com``` ([Amazon EKS Amazon ECR registry](https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html)) or ```XXXXXXXX.dkr.ecr.us-east-2.amazonaws.com```, where *XXXXXXXX* is your [AWS account number](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-west-2_e387ed0314eb9c79&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=VbKKL6uKA_VWnnJ69LKIgd0Dryzaa8nMFViVNSQtKOU&code_challenge_method=SHA-256):\n\n```\nError from server (Forbidden): error when creating \"nginx_deployment.yaml\": admission webhook \"always-pull-latest-image.example.com\" denied the request: Field spec.containers[0].image must be pulled from 602401143452.dkr.ecr.us-east-2.amazonaws.com,XXXXXXXX.dkr.ecr.us-east-2.amazonaws.com\n```\n\nNow tag the ```nginx``` image with our own registry, push the image, and try deploying from our own registry. For this repository, you need to create it in Amazon ECR:\n\n```\naws ecr create-repository --repository-name jspolicy\n```\n\nIdentify the name of the repository and the tag that the image uses:\n\n```\nexport REPOSITORY=$(aws ecr describe-repositories --repository-name jspolicy --query \"repositories[0].repositoryUri\" --output text)\n```\n\nPull the ```nginx``` image from Docker Hub locally so it can be appropriately retagged:\n\n```\ndocker pull nginx\n```\n\nRetag ```latest``` with the repository name and push this image to Amazon ECR. Before this can be done, login to Amazon ECR:\n\n```\naws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com\n```\n\nNow push the image with the ```latest``` tag to Amazon ECR:\n\n```\ndocker tag nginx ${REPOSITORY}/nginx:latest\ndocker push ${REPOSITORY}/nginx:latest\n```\n\nNow update the ```nginx deployment``` manifest file to use the image from Amazon ECR and deploy it:\n\n```\ncat > nginx_deployment.yaml << EOF\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-deployment\n namespace: web\n labels:\n app: nginx\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: ${REPOSITORY}/nginx:latest\n ports:\n - containerPort: 80\nEOF\n```\n\nNow create the deployment again:\n\n```\nkubectl create -f nginx_deployment.yaml\ndeployment.apps/nginx-deployment created\n```\n\n### **Cleanup**\nTo avoid incurring future charges, delete all the resources that were deployed earlier:\n\n```\nkubectl delete -f nginx.yaml\nkubectl delete -f nginx_deployment.yaml\nkubectl delete namespace jspolicy\nkubectl delete namespace web\naws ecr delete-repository --repository-name jspolicy --force\neksctl delete cluster -f cluster.yaml\n```\n\n### **Conclusion**\nIf you have previous experience using JavaScript or TypeScript, then you can easily define and deploy custom validating or mutating admission control policies with [jsPolicy](https://www.jspolicy.com/docs/writing-policies/policy-sdk). We have shown the process in this post. Review the [Amazon EKS Best Practices Guide for Security](https://aws.github.io/aws-eks-best-practices/security/docs/) to implement an optimized security strategy for your cluster. To learn more about jsPolicy, check out the [jsPolicy documentation](https://www.jspolicy.com/docs/quickstart) and get involved with the [jsPolicy community](https://github.com/loft-sh/jspolicy).\n\n![image.png](https://dev-media.amazoncloud.cn/1f521604c3a2483184d309eda2cf11cd_image.png)\n\n**Avaneesh Ramprasad**\n\nAvaneesh Ramprasad is a Sr. Cloud Architect with the AWS Professional Services team. He helps AWS customers across different industries to design and build secure, scalable, and highly available solutions, addressing their business needs and bringing innovations. Outside of work, enjoys cooking, baking and spending time with his friends and family.","render":"<h3><a id=\"Introduction_0\"></a><strong>Introduction</strong></h3>\n<p><a href=\"https://github.com/loft-sh/jspolicy\" target=\"_blank\">jsPolicy</a> is an open-source framework for managing validating or mutating admission control policies for <a href=\"https://docs.aws.amazon.com/eks/?id=docs_gateway\" target=\"_blank\">Amazon Elastic Kubernetes Service</a> (Amazon EKS) clusters using JavaScript (or TypeScript), which is similar to the way <a href=\"https://aws.amazon.com/iam/\" target=\"_blank\">AWS Identity and Access Management</a> (IAM) manages <a href=\"https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-west-2_e387ed0314eb9c79&amp;client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&amp;forceMobileApp=0&amp;code_challenge=VbKKL6uKA_VWnnJ69LKIgd0Dryzaa8nMFViVNSQtKOU&amp;code_challenge_method=SHA-256\" target=\"_blank\">AWS accounts</a> and resource access. It’s also possible to write the entire jsPolicy in a separate <a href=\"https://www.jspolicy.com/docs/writing-policies/policy-sdk\" target=\"_blank\">file</a> and load the policy from there. <a href=\"https://www.jspolicy.com/docs/writing-policies/policy-sdk\" target=\"_blank\">jsPolicy</a> offers built-in functions to reduce policy development effort, and testing frameworks like <a href=\"https://mochajs.org/\" target=\"_blank\">Mocha</a> and <a href=\"https://jestjs.io/\" target=\"_blank\">Jest</a> can be used to test a policy’s behavior.</p>\n<p>This post will walk you through deploying <a href=\"https://www.jspolicy.com/docs/writing-policies/policy-sdk\" target=\"_blank\">jsPolicy</a> into an <a href=\"https://aws.amazon.com/eks/\" target=\"_blank\">Amazon EKS</a> cluster and implementing two policies—one to deny deployments of resources into the default namespace and another to only allow container images from <a href=\"https://aws.amazon.com/ecr/\" target=\"_blank\">Amazon Elastic Container Registry</a> (Amazon ECR) or the <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html\" target=\"_blank\">Amazon container image registries</a>.</p>\n<h3><a id=\"Prerequisites_5\"></a><strong>Prerequisites</strong></h3>\n<p>For the walk through in this post, the following prerequisites are required:</p>\n<ul>\n<li>An <a href=\"https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fportal.aws.amazon.com%2Fbilling%2Fsignup%2Fresume&amp;client_id=signup&amp;code_challenge_method=SHA-256&amp;code_challenge=vyxQMX-ymfRsXRnAXkkTb-pcVgmvGn31JFhzQsnBZcs\" target=\"_blank\">AWS account</a>—with a user account with adequate access to manage Amazon EKS clusters (See required IAM permissions <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html\" target=\"_blank\">here</a>.)</li>\n<li><a href=\"https://kubernetes.io/docs/tasks/tools/\" target=\"_blank\">Kubernetes Kubectl tool</a></li>\n<li><a href=\"https://aws.amazon.com/cli/\" target=\"_blank\">AWS Command Line Interface</a> (AWS CLI)—installed and configured (<em>See Installing, updating, and uninstalling the AWS CLI</em> in the <a href=\"https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html\" target=\"_blank\">AWS CLI documentation</a>.)</li>\n<li><a href=\"https://eksctl.io/\" target=\"_blank\">Amazon EKS command line tool</a></li>\n<li><a href=\"https://helm.sh/docs/intro/install/\" target=\"_blank\">Helm v3.0.0</a></li>\n<li><a href=\"https://docs.docker.com/engine/install/\" target=\"_blank\">Docker CLI and Docker Engine</a></li>\n</ul>\n<h3><a id=\"Solution_overview_16\"></a><strong>Solution overview</strong></h3>\n<p>These are the steps presented in the following sections:</p>\n<ul>\n<li>Getting started</li>\n<li>Deploying the Amazon EKS cluster</li>\n<li>Configuring jsPolicy</li>\n<li>Creating and testing policies using jsPolicy</li>\n</ul>\n<h4><a id=\"Getting_started_25\"></a><strong>Getting started</strong></h4>\n<p>Before we can get started, we need to set up an <a href=\"https://docs.aws.amazon.com/eks/?id=docs_gateway\" target=\"_blank\">Amazon EKS</a> cluster. We use <a href=\"http://eksctl.io/\" target=\"_blank\">eksctl</a> with the cluster config file mechanism.</p>\n<h4><a id=\"Deploy_the_Amazon_EKS_cluster_28\"></a><strong>Deploy the Amazon EKS cluster</strong></h4>\n<p>With the necessary tools installed, launch the Amazon EKS cluster. In the following example, the Amazon EKS cluster is deployed to the US East (Ohio) Region (us-east-2). However, the <code>AWS_REGION</code> may be configured for <a href=\"https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/\" target=\"_blank\">any approved AWS Region</a> where Amazon EKS is enabled.</p>\n<p>Export the region and account ID:</p>\n<pre><code class=\"lang-\">export AWS_REGION=us-east-2\nexport ACCOUNT_ID=$(aws sts get-caller-identity --query &quot;Account&quot; --output text)\n</code></pre>\n<p>Once the region is exported, create the <code>ClusterConfig</code> as follows:</p>\n<pre><code class=\"lang-\">cat &gt;cluster.yaml &lt;&lt;EOF\napiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\nmetadata:\n name: jsPolicy\n region: ${AWS_REGION}\nnodeGroups:\n - name: ng-1\n desiredCapacity: 2\nEOF\n</code></pre>\n<p>After the <code>ClusterConfig</code> is created, create the <code>cluster using the eksctl create cluster</code> command:</p>\n<pre><code class=\"lang-\">eksctl create cluster -f cluster.yaml \n</code></pre>\n<p>The eksctl tool needs approximately 15 minutes to build the Amazon EKS cluster and reach a ready state. In order to use jsPolicy, it must be installed on the Amazon EKS cluster using <a href=\"https://helm.sh/\" target=\"_blank\">Helm</a>, which must first be installed on the local machine.</p>\n<h4><a id=\"Update_kubeconfig_61\"></a><strong>Update kubeconfig</strong></h4>\n<p>Once the Amazon EKS cluster is built and is in a ready state, update the kubeconfig file to access the cluster:</p>\n<pre><code class=\"lang-\">aws eks update-kubeconfig --region us-east-2 --name jsPolicy\n</code></pre>\n<h4><a id=\"Set_up_jsPolicy_68\"></a><strong>Set up jsPolicy</strong></h4>\n<p>Install jsPolicy on the Amazon EKS cluster in its own namespace:</p>\n<pre><code class=\"lang-\">helm repo update\nhelm install jspolicy -n jspolicy --create-namespace --repo https://charts.loft.sh --generate-name\n</code></pre>\n<p>Validate if the jsPolicy pods are running:</p>\n<pre><code class=\"lang-\">kubectl get pods -n jspolicy\nCreate and test policies\n</code></pre>\n<p>Create a policy to prevent deployment to the default namespace. The following policy prevents deployments to the default Kubernetes namespace:</p>\n<pre><code class=\"lang-\">cat &gt; deny-default-ns-policy.yaml &lt;&lt; EOF\napiVersion: policy.jspolicy.com/v1beta1\nkind: JsPolicy\nmetadata:\n name: &quot;deny-default-namespace.example.com&quot;\nspec:\n type: Validating\n operations: [&quot;CREATE&quot;]\n resources: [&quot;*&quot;]\n scope: Namespaced\n javascript: |\n if (request.namespace === &quot;default&quot;) {\n\n deny(&quot;Creation of resources within the default namespace is not allowed!&quot;);\n\n }\nEOF\n</code></pre>\n<p>Deploy the policy:</p>\n<pre><code class=\"lang-\">kubectl create -f deny-default-ns-policy.yaml\n</code></pre>\n<h4><a id=\"Test_the_policy_to_deny_namespace_deployments_111\"></a><strong>Test the policy to deny namespace deployments</strong></h4>\n<p>Create an <code>nginx</code> pod in the default namespace:</p>\n<pre><code class=\"lang-\">Cat &gt; nginx.yaml &lt;&lt; EOF\napiVersion: v1\nkind: Pod\nmetadata:\n name: web\n namespace: default\n labels:\n role: web\nspec:\n containers:\n - name: web\n image: nginx\n ports:\n - name: http\n containerPort: 80\n protocol: TCP\nEOF\n</code></pre>\n<p>Run the <code>nginx</code> pod to test it:</p>\n<pre><code class=\"lang-\">kubectl create -f nginx.yaml\n</code></pre>\n<p>The cluster returns the following error, preventing deployment to the default namespace:</p>\n<pre><code class=\"lang-\">Error from server (Forbidden): error when creating &quot;nginx.yaml&quot;: admission webhook &quot;deny-default-namespace.example.com&quot; denied the request: Creation of resources within the default namespace is not allowed!\n</code></pre>\n<p>Create another namespace called <code>web</code>:</p>\n<pre><code class=\"lang-\">kubectl create ns web\n</code></pre>\n<p>Modify the namespace in the <code>nginx.yaml</code> that was created prior to this from <code>default</code> to <code>web</code> and deploy it again:</p>\n<pre><code class=\"lang-\">kubectl create -f nginx.yaml\n</code></pre>\n<h4><a id=\"Create_the_policy_for_the_allowed_list_of_Amazon_ECR_repositories_158\"></a><strong>Create the policy for the allowed list of Amazon ECR repositories</strong></h4>\n<p>This policy denies pod images not originating from the allow list of <a href=\"https://docs.aws.amazon.com/ecr/?id=docs_gateway\" target=\"_blank\">Amazon ECR</a> repositories. The first two entries in the policy belong to the account owner and that belonging to the <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html\" target=\"_blank\">Amazon EKS Amazon ECR repository</a>:</p>\n<pre><code class=\"lang-\">cat &gt; enforce-image-registry.yaml &lt;&lt; EOF\napiVersion: policy.jspolicy.com/v1beta1\nkind: JsPolicy\nmetadata:\n name: &quot;deny-untrusted-registries.example.com&quot;\nspec:\n type: Validating\n operations: [&quot;CREATE&quot;, &quot;UPDATE&quot;]\n resources: [&quot;pods&quot;, &quot;deployments&quot;, &quot;statefulsets&quot;]\n javascript: |\n const registries = [&quot;602401143452.dkr.ecr.us-east-2.amazonaws.com&quot;, &quot;${ACCOUNT_ID}.dkr.ecr.us-east-2.amazonaws.com&quot;]\n\n // Use template.spec if defined (for Deployments and StatefulSets), or use spec otherwise (for Pods)\n podSpec = request.object?.spec?.template?.spec || request.object?.spec\n\n podSpec?.containers?.forEach(function(container, index) {\n if (!registries.includes(container.image.split('/')[0])) {\n deny(&quot;Field spec.containers[&quot; + index + &quot;].image must be pulled from &quot; + registries.toString())\n }\n })\n\n podSpec?.initContainers?.forEach(function(initContainer, index) {\n let imageRegistry = initContainer.image.split('/')[0] \n if (!registries.includes(initContainer.image.split('/')[0])) {\n errors.push(&quot;Field spec.initContainers[&quot; + index + &quot;].image must match regex: &quot; + registries.toString())\n }\n })\nEOF\n</code></pre>\n<p>Deploy the policy:</p>\n<pre><code class=\"lang-\">kubectl create -f enforce-image-registry.yaml\n</code></pre>\n<h4><a id=\"Test_the_image_registry_of_the_allowed_list_policy_198\"></a><strong>Test the image registry of the allowed list policy</strong></h4>\n<p>Create an <code>nginx</code> deployment in the <code>web</code> namespace using the <code>nginx</code> image from Docker Hub:</p>\n<pre><code class=\"lang-\">cat &gt; nginx_deployment.yaml &lt;&lt; EOF\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-deployment\n namespace: web\n labels:\n app: nginx\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:latest\n ports:\n - containerPort: 80\nEOF\n</code></pre>\n<p>Create the <code>nginx</code> deployment to test:</p>\n<pre><code class=\"lang-\">kubectl create -f nginx_deployment.yaml\n</code></pre>\n<p>The cluster returns the following error, indicating that the image should only be pulled from <code>602401143452.dkr.ecr.us-east-2.amazonaws.com</code> (<a href=\"https://docs.aws.amazon.com/eks/latest/userguide/add-ons-images.html\" target=\"_blank\">Amazon EKS Amazon ECR registry</a>) or <code>XXXXXXXX.dkr.ecr.us-east-2.amazonaws.com</code>, where <em>XXXXXXXX</em> is your <a href=\"https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3FhashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-west-2_e387ed0314eb9c79&amp;client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&amp;forceMobileApp=0&amp;code_challenge=VbKKL6uKA_VWnnJ69LKIgd0Dryzaa8nMFViVNSQtKOU&amp;code_challenge_method=SHA-256\" target=\"_blank\">AWS account number</a>:</p>\n<pre><code class=\"lang-\">Error from server (Forbidden): error when creating &quot;nginx_deployment.yaml&quot;: admission webhook &quot;always-pull-latest-image.example.com&quot; denied the request: Field spec.containers[0].image must be pulled from 602401143452.dkr.ecr.us-east-2.amazonaws.com,XXXXXXXX.dkr.ecr.us-east-2.amazonaws.com\n</code></pre>\n<p>Now tag the <code>nginx</code> image with our own registry, push the image, and try deploying from our own registry. For this repository, you need to create it in Amazon ECR:</p>\n<pre><code class=\"lang-\">aws ecr create-repository --repository-name jspolicy\n</code></pre>\n<p>Identify the name of the repository and the tag that the image uses:</p>\n<pre><code class=\"lang-\">export REPOSITORY=$(aws ecr describe-repositories --repository-name jspolicy --query &quot;repositories[0].repositoryUri&quot; --output text)\n</code></pre>\n<p>Pull the <code>nginx</code> image from Docker Hub locally so it can be appropriately retagged:</p>\n<pre><code class=\"lang-\">docker pull nginx\n</code></pre>\n<p>Retag <code>latest</code> with the repository name and push this image to Amazon ECR. Before this can be done, login to Amazon ECR:</p>\n<pre><code class=\"lang-\">aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com\n</code></pre>\n<p>Now push the image with the <code>latest</code> tag to Amazon ECR:</p>\n<pre><code class=\"lang-\">docker tag nginx ${REPOSITORY}/nginx:latest\ndocker push ${REPOSITORY}/nginx:latest\n</code></pre>\n<p>Now update the <code>nginx deployment</code> manifest file to use the image from Amazon ECR and deploy it:</p>\n<pre><code class=\"lang-\">cat &gt; nginx_deployment.yaml &lt;&lt; EOF\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: nginx-deployment\n namespace: web\n labels:\n app: nginx\nspec:\n replicas: 3\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: ${REPOSITORY}/nginx:latest\n ports:\n - containerPort: 80\nEOF\n</code></pre>\n<p>Now create the deployment again:</p>\n<pre><code class=\"lang-\">kubectl create -f nginx_deployment.yaml\ndeployment.apps/nginx-deployment created\n</code></pre>\n<h3><a id=\"Cleanup_307\"></a><strong>Cleanup</strong></h3>\n<p>To avoid incurring future charges, delete all the resources that were deployed earlier:</p>\n<pre><code class=\"lang-\">kubectl delete -f nginx.yaml\nkubectl delete -f nginx_deployment.yaml\nkubectl delete namespace jspolicy\nkubectl delete namespace web\naws ecr delete-repository --repository-name jspolicy --force\neksctl delete cluster -f cluster.yaml\n</code></pre>\n<h3><a id=\"Conclusion_319\"></a><strong>Conclusion</strong></h3>\n<p>If you have previous experience using JavaScript or TypeScript, then you can easily define and deploy custom validating or mutating admission control policies with <a href=\"https://www.jspolicy.com/docs/writing-policies/policy-sdk\" target=\"_blank\">jsPolicy</a>. We have shown the process in this post. Review the <a href=\"https://aws.github.io/aws-eks-best-practices/security/docs/\" target=\"_blank\">Amazon EKS Best Practices Guide for Security</a> to implement an optimized security strategy for your cluster. To learn more about jsPolicy, check out the <a href=\"https://www.jspolicy.com/docs/quickstart\" target=\"_blank\">jsPolicy documentation</a> and get involved with the <a href=\"https://github.com/loft-sh/jspolicy\" target=\"_blank\">jsPolicy community</a>.</p>\n<p><img src=\"https://dev-media.amazoncloud.cn/1f521604c3a2483184d309eda2cf11cd_image.png\" alt=\"image.png\" /></p>\n<p><strong>Avaneesh Ramprasad</strong></p>\n<p>Avaneesh Ramprasad is a Sr. Cloud Architect with the AWS Professional Services team. He helps AWS customers across different industries to design and build secure, scalable, and highly available solutions, addressing their business needs and bringing innovations. Outside of work, enjoys cooking, baking and spending time with his friends and family.</p>\n"}
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭
contact-us