From bfdef47ae6a8adbc67cdc1769b79f690be976aa1 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Thu, 24 Oct 2024 18:36:22 +0000 Subject: [PATCH 01/12] pod troubleshooting scenarios --- .../pod/crash/.workshop/cleanup.sh | 27 +++ .../.workshop/terraform/deployment.yaml.tpl | 51 +++++ .../pod/crash/.workshop/terraform/main.tf | 124 +++++++++++ .../pod/crash/.workshop/terraform/outputs.tf | 13 ++ .../pod/crash/.workshop/terraform/vars.tf | 36 ++++ .../pod/image/.workshop/cleanup.sh | 9 + .../pod/image/.workshop/terraform/main.tf | 32 +++ .../pod/image/.workshop/terraform/outputs.tf | 3 + .../pod/image/.workshop/terraform/vars.tf | 36 ++++ .../troubleshooting/pod/image/deployment.yaml | 61 ++++++ .../pod/permissions/.workshop/cleanup.sh | 10 + .../.workshop/terraform/deployment.yaml.tpl | 61 ++++++ .../permissions/.workshop/terraform/main.tf | 185 +++++++++++++++++ .../.workshop/terraform/outputs.tf | 3 + .../permissions/.workshop/terraform/vars.tf | 36 ++++ .../pod/assets/rep-not-found.webp | Bin 0 -> 33186 bytes .../pod/assets/repo-found.webp | Bin 0 -> 92912 bytes .../docs/troubleshooting/pod/image_pull_1.md | 116 +++++++++++ .../docs/troubleshooting/pod/image_pull_2.md | 193 ++++++++++++++++++ website/docs/troubleshooting/pod/index.md | 14 ++ website/docs/troubleshooting/pod/pod_stuck.md | 186 +++++++++++++++++ 21 files changed, 1196 insertions(+) create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf create mode 100644 manifests/modules/troubleshooting/pod/image/deployment.yaml create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf create mode 100644 website/docs/troubleshooting/pod/assets/rep-not-found.webp create mode 100644 website/docs/troubleshooting/pod/assets/repo-found.webp create mode 100644 website/docs/troubleshooting/pod/image_pull_1.md create mode 100644 website/docs/troubleshooting/pod/image_pull_2.md create mode 100644 website/docs/troubleshooting/pod/index.md create mode 100644 website/docs/troubleshooting/pod/pod_stuck.md diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh new file mode 100644 index 000000000..f37989081 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment efs-app -n default > /dev/null 2>&1; then + kubectl delete deployment efs-app -n default +else + echo "Deployment efs-app does not exist." +fi + +if kubectl get pvc efs-claim -n default > /dev/null 2>&1; then + kubectl delete pvc efs-claim -n default +else + echo "PVC efs-claim does not exist." +fi +PV_NAME=$(kubectl get pv -o jsonpath='{.items[?(@.spec.claimRef.name=="efs-claim")].metadata.name}') +if [ -n "$PV_NAME" ]; then + kubectl delete pv "$PV_NAME" +else + echo "No PV associated with efs-claim." +fi + +if kubectl get storageclass efs-sc > /dev/null 2>&1; then + kubectl delete storageclass efs-sc +else + echo "Storage class efs-sc does not exist." +fi diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl new file mode 100644 index 000000000..609c1f1a4 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl @@ -0,0 +1,51 @@ +--- +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: efs-sc +provisioner: efs.csi.aws.com +parameters: + provisioningMode: efs-ap + fileSystemId: ${filesystemid} + directoryPerms: "700" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: efs-claim +spec: + accessModes: + - ReadWriteMany + storageClassName: efs-sc + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: efs-app + labels: + app: efs-app +spec: + replicas: 1 + selector: + matchLabels: + app: efs-app + template: + metadata: + labels: + app: efs-app + spec: + containers: + - name: app + image: centos + command: ["/bin/sh"] + args: ["-c", "while true; do echo $(date -u) >> /example/out.txt; sleep 5; done"] + volumeMounts: + - name: persistent-storage + mountPath: /example + volumes: + - name: persistent-storage + persistentVolumeClaim: + claimName: efs-claim \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf new file mode 100644 index 000000000..06809a932 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -0,0 +1,124 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + +data "aws_vpc" "selected" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } +} + +data "aws_subnets" "public" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } + + filter { + name = "tag:Name" + values = ["*Public*"] + } +} + +data "aws_region" "current" {} + +data "aws_eks_cluster" "cluster" { + name = var.eks_cluster_id +} + +module "eks_blueprints_addons" { + source = "aws-ia/eks-blueprints-addons/aws" + version = "1.16.2" + + enable_aws_efs_csi_driver = true + aws_efs_csi_driver = { + wait = true + } + + cluster_name = var.addon_context.eks_cluster_id + cluster_endpoint = var.addon_context.aws_eks_cluster_endpoint + cluster_version = var.eks_cluster_version + oidc_provider_arn = var.addon_context.eks_oidc_provider_arn +} + + +resource "aws_efs_file_system" "efs" { + tags = { + Name = "eks-workshop-efs" + } +} + +resource "aws_efs_mount_target" "mount_targets" { + for_each = toset(data.aws_subnets.public.ids) + file_system_id = resource.aws_efs_file_system.efs.id + subnet_id = each.value + security_groups = [resource.aws_security_group.efs_sg.id] +} + +resource "aws_security_group" "efs_sg" { + name = "efs_sg" + description = "Allow tarffic to efs" + vpc_id = data.aws_vpc.selected.id + + tags = { + Name = "efs_sg" + } +} + +resource "aws_vpc_security_group_ingress_rule" "allow_ipv4" { + security_group_id = aws_security_group.efs_sg.id + cidr_ipv4 = data.aws_vpc.selected.cidr_block + from_port = 80 + ip_protocol = "tcp" + to_port = 80 +} + + +resource "aws_vpc_security_group_egress_rule" "allow_all_traffic_ipv4" { + security_group_id = aws_security_group.efs_sg.id + cidr_ipv4 = "0.0.0.0/0" + ip_protocol = "-1" # semantically equivalent to all ports +} + +data "template_file" "deployment_yaml" { + template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") + + vars = { + filesystemid = "${resource.aws_efs_file_system.efs.id}" + } +} + +resource "local_file" "deployment_yaml" { + filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/deployment.yaml" + content = data.template_file.deployment_yaml.rendered +} + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/crash/" + when = create + } + + depends_on = [resource.local_file.deployment_yaml, resource.aws_efs_file_system.efs] +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..688f66d65 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf @@ -0,0 +1,13 @@ +output "account_id" { + value = local.account_id +} + +output "environment_variables" { + description = "Environment variables to be added to the IDE shell" + value = merge({ + VPC_ID = data.aws_vpc.selected.id + }, { + for index, id in data.aws_subnets.public.ids : "PUBLIC_SUBNET_${index + 1}" => id + } + ) +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh new file mode 100644 index 000000000..ac311489e --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment ui-new -n default > /dev/null 2>&1; then + kubectl delete deploy ui-new -n default +else + echo "delpoyment ui-new does not exist" +fi diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf new file mode 100644 index 000000000..565d04435 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf @@ -0,0 +1,32 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/image/" + when = create + } +} + diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..efa7cab69 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "account_id" { + value = local.account_id +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/deployment.yaml b/manifests/modules/troubleshooting/pod/image/deployment.yaml new file mode 100644 index 000000000..687f170ca --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ui-new + labels: + app: app-new +spec: + replicas: 1 + selector: + matchLabels: + app: app-new + template: + metadata: + annotations: + prometheus.io/path: /actuator/prometheus + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: app-new + spec: + securityContext: + fsGroup: 1000 + containers: + - name: ui + env: + - name: JAVA_OPTS + value: -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/urandom + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + image: "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 45 + periodSeconds: 20 + resources: + limits: + memory: 1.5Gi + requests: + cpu: 250m + memory: 1.5Gi + volumeMounts: + - mountPath: /tmp + name: tmp-volume + volumes: + - name: tmp-volume + emptyDir: + medium: Memory \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh new file mode 100644 index 000000000..53b68768d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment ui-private -n default > /dev/null 2>&1; then + kubectl delete deploy ui-private -n default +else + echo "delpoyment ui-private does not exist" +fi + diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl new file mode 100644 index 000000000..906b59f34 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ui-private + labels: + app: app-private +spec: + replicas: 1 + selector: + matchLabels: + app: app-private + template: + metadata: + annotations: + prometheus.io/path: /actuator/prometheus + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: app-private + spec: + securityContext: + fsGroup: 1000 + containers: + - name: ui + env: + - name: JAVA_OPTS + value: -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/urandom + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + image: ${image} + imagePullPolicy: Always + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 45 + periodSeconds: 20 + resources: + limits: + memory: 1.5Gi + requests: + cpu: 250m + memory: 1.5Gi + volumeMounts: + - mountPath: /tmp + name: tmp-volume + volumes: + - name: tmp-volume + emptyDir: + medium: Memory \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf new file mode 100644 index 000000000..35fdecbad --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf @@ -0,0 +1,185 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + +data "aws_region" "current" {} + +data "aws_eks_cluster" "cluster" { + name = var.eks_cluster_id +} + +data "aws_vpc" "selected" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } +} + +data "aws_eks_node_group" "default" { + cluster_name = data.aws_eks_cluster.cluster.id + node_group_name = "default" +} + +data "aws_ssm_parameter" "eks_ami" { + name = "/aws/service/eks/optimized-ami/${var.eks_cluster_version}/amazon-linux-2/recommended/image_id" +} + +data "aws_subnets" "selected" { + tags = { + env = var.addon_context.eks_cluster_id + } +} + +resource "aws_iam_role" "ecr_ec2_role" { + name = "ecr_ec2_role" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + Service = "ec2.amazonaws.com" + } + Action = "sts:AssumeRole" + }, + ] + }) + managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess", "arn:aws:iam::aws:policy/AmazonElasticContainerRegistryPublicPowerUser"] +} + +resource "aws_iam_instance_profile" "ecr_ec2" { + name = "ecr_ec2" + role = resource.aws_iam_role.ecr_ec2_role.name +} + +resource "aws_instance" "ui_to_ecr" { + ami = data.aws_ssm_parameter.eks_ami.value + instance_type = "t3.medium" + user_data = <<-EOF + #!/bin/bash + sudo yum update -y + sudo amazon-linux-extras install docker + sudo service docker start + sudo usermod -a -G docker ec2-user + docker pull public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0 + docker images | grep retail-store | awk '{ print $3 }' | xargs -I {} docker tag {} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 + aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com + docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 + EOF + subnet_id = element(data.aws_subnets.selected.ids, 0) + iam_instance_profile = resource.aws_iam_instance_profile.ecr_ec2.name + depends_on = [resource.aws_ecr_repository.ui] +} + +resource "aws_ecr_repository" "ui" { + name = "retail-sample-app-ui" + image_tag_mutability = "MUTABLE" + force_delete = true + +} + +data "aws_iam_policy_document" "private-registry" { + statement { + sid = "new policy" + effect = "Deny" + + principals { + type = "AWS" + identifiers = [data.aws_eks_node_group.default.node_role_arn] + } + + actions = [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "ecr:DescribeRepositories", + "ecr:GetRepositoryPolicy", + "ecr:ListImages", + "ecr:DeleteRepository", + "ecr:BatchDeleteImage", + "ecr:SetRepositoryPolicy", + "ecr:DeleteRepositoryPolicy", + ] + } +} + + +resource "aws_ecr_repository_policy" "example" { + repository = aws_ecr_repository.ui.name + policy = data.aws_iam_policy_document.private-registry.json + depends_on = [resource.aws_instance.ui_to_ecr] +} + +data "template_file" "deployment_yaml" { + template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl") + + vars = { + image = "${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } +} + + +resource "local_file" "deployment_yaml" { + filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/deployment.yaml" + content = data.template_file.deployment_yaml.rendered +} + +/* +resource "null_resource" "ui_to_ecr" { + + #provisioner "local-exec" { + # command = "aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com" + #} + + provisioner "local-exec" { + command = "docker pull public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0" + } + + provisioner "local-exec" { + command = "docker images | grep retail-store | awk '{ print $3 }' | xargs -I {} docker tag {} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } + + #provisioner "local-exec" { + # command = "sudo docker tag ${tag} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + #} + + provisioner "local-exec" { + command = "aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com && docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } + + depends_on = [resource.aws_ecr_repository.ui] +} +*/ + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/permissions/" + when = create + } + + depends_on = [resource.local_file.deployment_yaml, resource.aws_instance.ui_to_ecr] +} diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..efa7cab69 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "account_id" { + value = local.account_id +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/assets/rep-not-found.webp b/website/docs/troubleshooting/pod/assets/rep-not-found.webp new file mode 100644 index 0000000000000000000000000000000000000000..17bcc803804bc7e31531a1111cd13047092012ef GIT binary patch literal 33186 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 literal 0 HcmV?d00001 diff --git a/website/docs/troubleshooting/pod/assets/repo-found.webp b/website/docs/troubleshooting/pod/assets/repo-found.webp new file mode 100644 index 0000000000000000000000000000000000000000..8b343fd290f3a185a03db3fa9571cdbc69b16029 GIT binary patch literal 92912 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

UAmnd7h;lN+e*uR?i$W*XP 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 iK7XE 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 GIsXGY!AunZ literal 0 HcmV?d00001 diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md new file mode 100644 index 000000000..9d4e64508 --- /dev/null +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -0,0 +1,116 @@ +--- +title: "ImagePullBackOff - Public Image" +sidebar_position: 41 +--- + +In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR public image. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/image +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Create a new deployment named ui-new in default namespace +- Introduce an issue to the deployment spec, so we can learn how to troubleshoot these types of issues + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/image/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deployment ui-new -n default +NAME READY UP-TO-DATE AVAILABLE AGE +ui-new 0/1 1 0 75s +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment ui-new to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. To do so, we will use `kubectl` tool. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-new-5654dd8969-7w98k 0/1 ImagePullBackOff 0 13s +``` + +### Step 2 + +You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 48s default-scheduler Successfully assigned default/ui-new-5654dd8969-7w98k to ip-10-42-33-232.us-west-2.compute.internal + Normal BackOff 23s (x2 over 47s) kubelet Back-off pulling image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + Warning Failed 23s (x2 over 47s) kubelet Error: ImagePullBackOff + Normal Pulling 12s (x3 over 47s) kubelet Pulling image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + Warning Failed 12s (x3 over 47s) kubelet Failed to pull image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": rpc error: code = NotFound desc = failed to pull and unpack image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": failed to resolve reference "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0: not found + Warning Failed 12s (x3 over 47s) kubelet Error: ErrImagePull +``` + +### Step 3 + +From the events of the pod, we can see the Failed to pull image warning with error code NotFound. This gives us an idea that the referenced image in the pod/deployment spec was not able to be found at the path. Lets check the image used by the pod. + +```bash +$ kubectl get pod $POD -o jsonpath='{.spec.containers[*].image}' +public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0 +``` + +### Step 4 + +From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at https://gallery.ecr.aws/aws-containers . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui and since the image does not exist we will see Repository not found message as shown below. + +![RepoDoesNotExist](./assets/rep-not-found.webp) + +### Step 5 + +To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the URL https://gallery.ecr.aws/aws-containers/retail-store-sample-ui. You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. + +![RepoExist](./assets/repo-found.webp) + +Update the image in the deployment with correct reference + +```bash +$ kubectl patch deployment ui-new --patch '{"spec": {"template": {"spec": {"containers": [{"name": "ui", "image": "public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0"}]}}}}' +deployment.apps/ui-new patched +``` + +### Step 6 + +Check if the new pod is created and running successfully. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-new-77856467b-2z2s6 1/1 Running 0 13s +``` + +That concludes the public ECR ImagePullBackOff troubleshooting section. + +## Wrapping it up + +General troubleshooting workflow of the pod with ImagePullBackOff on public image includes: + +- Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. +- If not found, ensure that the image exists in the path referenced. +- For access denied, check the permissions on worker node role. +- For timeout on public images on ECR, ensure that the worker node is configured to reach the internet via IGW/TGW/NAT. + +References: +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md new file mode 100644 index 000000000..b9b1f8aee --- /dev/null +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -0,0 +1,193 @@ +--- +title: "ImagePullBackOff - ECR Private Image" +sidebar_position: 42 +--- + +In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR private image. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/permissions +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Create a ECR repo named retail-sample-app-ui. +- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 +- Create a new deployment named ui-private in default namespace +- Introduce an issue to the deployment spec, so we can learn how to troubleshoot this type of issues + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deploy ui-private -n default +NAME READY UP-TO-DATE AVAILABLE AGE +ui-private 0/1 1 0 4m25s +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment ui-private to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-private-7655bf59b9-jprrj 0/1 ImagePullBackOff 0 4m42s +``` + +### Step 2 + +You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 5m15s default-scheduler Successfully assigned default/ui-private-7655bf59b9-jprrj to ip-10-42-33-232.us-west-2.compute.internal + Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https://682844965773.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden + Warning Failed 3m53s (x4 over 5m14s) kubelet Error: ErrImagePull + Warning Failed 3m27s (x6 over 5m14s) kubelet Error: ImagePullBackOff + Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" +``` + +### Step 3 + +From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. + +```bash +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' +682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +``` + +### Step 4 + +From the image URI, we can see that the image is referenced from the account where our EKS cluster is in. Lets check the ECR repository to see if any such image exists. + +```bash +$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 +{ + "imageDetails": [ + { + "registryId": "682844965773", + "repositoryName": "retail-sample-app-ui", + "imageDigest": "sha256:b338785abbf5a5d7e0f6ebeb8b8fc66e2ef08c05b2b48e5dfe89d03710eec2c1", + "imageTags": [ + "0.4.0" + ], + "imageSizeInBytes": 268443135, + "imagePushedAt": "2024-10-11T14:03:01.207000+00:00", + "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json", + "artifactMediaType": "application/vnd.docker.container.image.v1+json" + } + ] +} +``` + +You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. + +:::info +Alternatively, you can also check the console for the same. Click the button below to open the ECR Console. Then click on retail-sample-app-ui repository and the image tag 0.4.0, you should then see the complete URI of the image which should match with the URI in deployment spec i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 + +::: + +### Step 5 + +As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. + +Get the IAM role attached to worker nodes in the managed node group of the cluster and list the IAM policies attached to it. + +```bash +$ ROLE_NAME=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole' --output text | cut -d'/' -f2` +$ aws iam list-attached-role-policies --role-name $ROLE_NAME +{ + "AttachedPolicies": [ + { + "PolicyName": "AmazonSSMManagedInstanceCore", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + }, + { + "PolicyName": "AmazonEC2ContainerRegistryReadOnly", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + }, + { + "PolicyName": "AmazonEKSWorkerNodePolicy", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" + }, + { + "PolicyName": "AmazonSSMPatchAssociation", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMPatchAssociation" + } + ] +} +``` + +You should see that the AWS managed policy "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" is attached to the worker node role and this policy should provide enough permissions to pull a Image from ECR preivate repository. What else could we check now? + +### Step 6 + +The perimissions to the ECR repository can be managed at both Identity and Resource level. The Identity level permissions are provided at IAM and the resource level permissions are provided at the repository level. As we confirmed that identity based permissions are good, the issue could be with resource level permissions. Lets the check the policy for ECR repo. + +```bash +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui +{ + "registryId": "682844965773", + "repositoryName": "retail-sample-app-ui", + "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam::682844965773:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" +} +``` + +You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. + +```bash +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query 'policyText' --output text > ecr-policy.json +$ jq '(.Statement[] | select(.Effect == "Deny")).Effect = "Allow"' ecr-policy.json > updated-ecr-policy.json +$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://updated-ecr-policy.json +$ rm ecr-policy.json updated-ecr-policy.json +``` + +You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. + +### Step 7 + +Now, check if the pods are running. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m +``` + +That concludes the private ECR ImagePullBackOff troubleshooting section. + +## Wrapping it up + +General troubleshooting workflow of the pod with ImagePullBackOff on private image includes: + +- Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. +- If not found, ensure that the image exists in the path referenced in the private ECR repositories. +- For access denied, check the permissions on worker node role and the ECR repository policy. +- For timeout on ECR, ensure that the worker node is configured to reach the ECR endpoint. + +References: +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html +- https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html diff --git a/website/docs/troubleshooting/pod/index.md b/website/docs/troubleshooting/pod/index.md new file mode 100644 index 000000000..1cdc069ac --- /dev/null +++ b/website/docs/troubleshooting/pod/index.md @@ -0,0 +1,14 @@ +--- +title: "Pod Issue Scenarios" +sidebar_position: 40 +chapter: true +sidebar_custom_props: { "module": true } +description: "Run deployments with diferent image paths/sources and persistent volume configurations, introduce the issues related to running those deployments" +--- + +::required-time + +In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. + +- Pod Issues such as readiness/liveness probe failures and scheduling issues will be coming soon under this section of troubleshooting module. + diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md new file mode 100644 index 000000000..b40d9389a --- /dev/null +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -0,0 +1,186 @@ +--- +title: "PodStuck - ContainerCreating" +sidebar_position: 43 +--- + +In this section we will learn how to troubleshoot the pod for one of the scenarios where it is stuck in ContainerCreating state. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/crash +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Install aws-efs-csi-driver addon in the EKS cluster. +- Create a EFS filesystem and mount targets. +- Create a deployment named efs-app backed by a persistent volume claim named efs-claim to leverage EFS as persistent volume, in the default namespace. + + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/crash/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deploy efs-app -n default +NAME READY UP-TO-DATE AVAILABLE AGE +efs-app 0/1 1 0 18m +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment efs-app to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +efs-app-5c4df89785-m4qz4 0/1 ContainerCreating 0 19m +``` + +### Step 2 + +You can see that the pod status is showing as ContainerCreating. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. +No mount target created for the file system fs-00a4069aec7924c8c is in available state yet, please retry in 5 minutes. +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. + Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. +Connection to the mount target IP address 10.42.41.35 timeout. Please retry in 5 minutes if the mount target is newly created. Otherwise check your VPC and security group configuration to ensure your file system is reachable via TCP port 2049 from your instance. +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. + Warning FailedMount 19m kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 32 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Could not start amazon-efs-mount-watchdog, unrecognized init system "aws-efs-csi-dri" +Mount attempt 1/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. +Mount attempt 2/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. +b'mount.nfs4: mount point /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount does not exist' +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have retry_nfs_mount_command item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [retry_nfs_mount_command = True]. + Warning FailedMount 3m33s (x6 over 23m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = DeadlineExceeded desc = context deadline exceeded +``` + +### Step 3 + +From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. +Connection to the mount target IP address x.x.x.x timeout.'. This gives us an idea that the EFS file system is failed to mount for the pods to use as persistent volume. With out which the pod cannot move to running state. Lets check the networking configuration of the node on which the pod is scheduled to run. + +In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. + +```bash +$ INSTANCE=`kubectl get node ($ kubectl get pod $POD -o jsonpath='{.spec.nodeName}') -o yaml` +$ SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` +$ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" +``` +You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. + +:::info +Alternatively, click the button below to open the EKS Console. Then navigate to eks-workshop cluster, Resources and select pods workloads. Select default instead of All namespaces in namespace drop down. Then click on efs-app pod and from their click on Node and then on Instance, which should take you to EC2 console. Click on Security and you should see the security groups attached to the worker node and the Outbound rules of it. + +::: + +### Step 4 + +Now, lets check the EFS file system networking configuration. + +In the below commands, we are +- Retrieving the Availability zone of the worker node using instance id. +- Retrieving the EFS id from the persistent volume claim. +- Retrieving the mount target ENI for the availability zone corresponding to the instance Id. +- Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group + +```bash +$ AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` +$ EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` +$ MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` +$ MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` +$ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[].IpPermissions[]" +[ + { + "IpProtocol": "tcp", + "FromPort": 80, + "ToPort": 80, + "UserIdGroupPairs": [], + "IpRanges": [ + { + "CidrIp": "10.42.0.0/16" + } + ], + "Ipv6Ranges": [], + "PrefixListIds": [] + } +] +``` + +You should see that the security group attached to the mount target of EFS have inbound rules only on port 80 from the VPC CIDR. However, for the mount to be successful the security group of mount target should allow traffic on port 2049. Which is why the mount request is timing out from the EKS worker node. + + +:::info +Alternatively, you can also check the console for the same. Click the button below to open the EFS Console. Then click on EFS file system Id which has name as eks-workshop-efs. Then click on Network to view mount targets for all availability zones and the security groups attached to the each mount target. + + +::: + +### Step 5 + +Lets add the inboud rule to EFS mount target security group to allow NFS traffic on port 2049 from VPC CIDR of the EKS cluster. + +In the below commands, we are + +- Retrieving the VPC of the EKS cluster and the CIDR of the VPC. +- Adding inbound rule to mount target security group allowing traffic on port 2049 from VPC CIDR. + +```bash +$ VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` +$ CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR +``` +After 3-4 minutes, you should notice that the pod in default namespace is in running state + +```bash +$ kubectl get pods $POD +NAME READY STATUS RESTARTS AGE +efs-app-5c4df89785-m4qz4 1/1 Running 0 102m +``` + +Since the EFS mount target security group allow traffic on port 2049 the worker nodes where able to successfully communicate with the mount targets and complete the mount of EFS to the pods. + +This concludes the pod stuck in ContainerCreating troubleshooting section. + +## Wrapping it up + +General, troubleshooting workflow of pods stuck in ContainerCreating state is to check pod events and for volume mount issues: + +- Check the volume claim used by the pod and identify the type of volume used. +- Then check the csi driver used for that volume and check the requiements to use that volume in EKS pods at https://docs.aws.amazon.com/eks/latest/userguide/storage.html +- Confirm that all the requiements mentioned in the corresponding storage type document are met. +- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues + From fed459fbac21ece4ca556588ed23bf9684dcb02f Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Tue, 5 Nov 2024 19:23:33 +0000 Subject: [PATCH 02/12] added hook scripts --- .../docs/troubleshooting/pod/image_pull_1.md | 6 +++-- .../docs/troubleshooting/pod/image_pull_2.md | 13 +++++----- website/docs/troubleshooting/pod/pod_stuck.md | 25 +++++++++++-------- .../troubleshooting/pod/tests/hook-fix-1.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-fix-2.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-fix-3.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-suite.sh | 11 ++++++++ website/test-durations.json | 5 +++- 8 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-1.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-2.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-3.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-suite.sh diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md index 9d4e64508..317c6115e 100644 --- a/website/docs/troubleshooting/pod/image_pull_1.md +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -1,6 +1,8 @@ --- title: "ImagePullBackOff - Public Image" sidebar_position: 41 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR public image. @@ -49,7 +51,7 @@ ui-new-5654dd8969-7w98k 0/1 ImagePullBackOff 0 13s You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. -```bash +```bash expectError=true timeout=20 $ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: @@ -95,7 +97,7 @@ deployment.apps/ui-new patched Check if the new pod is created and running successfully. -```bash +```bash timeout=180 hook=fix-1 hookTimeout=600 $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-new-77856467b-2z2s6 1/1 Running 0 13s diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index b9b1f8aee..47886b879 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -1,6 +1,8 @@ --- title: "ImagePullBackOff - ECR Private Image" sidebar_position: 42 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR private image. @@ -51,7 +53,7 @@ ui-private-7655bf59b9-jprrj 0/1 ImagePullBackOff 0 4m42s You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. -```bash +```bash expectError=true $ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: @@ -158,10 +160,9 @@ $ aws ecr get-repository-policy --repository-name retail-sample-app-ui You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. ```bash -$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query 'policyText' --output text > ecr-policy.json -$ jq '(.Statement[] | select(.Effect == "Deny")).Effect = "Allow"' ecr-policy.json > updated-ecr-policy.json -$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://updated-ecr-policy.json -$ rm ecr-policy.json updated-ecr-policy.json +$ export ROLE_ARN=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole'` +$ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow","Principal":{"AWS":'${ROLE_ARN}'},"Action":["ecr:BatchCheckLayerAvailability","ecr:BatchDeleteImage","ecr:BatchGetImage","ecr:CompleteLayerUpload","ecr:DeleteRepository","ecr:DeleteRepositoryPolicy","ecr:DescribeRepositories","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:InitiateLayerUpload","ecr:ListImages","ecr:PutImage","ecr:SetRepositoryPolicy","ecr:UploadLayerPart"]}]}' > ~/ecr-policy.json +$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://~/ecr-policy.json ``` You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. @@ -170,7 +171,7 @@ You can confirm if the ECR repo policy updated successfully, by using the above Now, check if the pods are running. -```bash +```bash timeout=180 hook=fix-2 hookTimeout=600 $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index b40d9389a..d27363700 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -1,6 +1,8 @@ --- title: "PodStuck - ContainerCreating" sidebar_position: 43 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod for one of the scenarios where it is stuck in ContainerCreating state. @@ -51,8 +53,8 @@ efs-app-5c4df89785-m4qz4 0/1 ContainerCreating 0 19m You can see that the pod status is showing as ContainerCreating. Lets describe the pod to see the events. -```bash -$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +```bash expectError=true +$ export POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: Type Reason Age From Message @@ -88,8 +90,9 @@ Connection to the mount target IP address x.x.x.x timeout.'. This gives us an id In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. ```bash -$ INSTANCE=`kubectl get node ($ kubectl get pod $POD -o jsonpath='{.spec.nodeName}') -o yaml` -$ SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` +$ export NODE=`kubectl get pod $POD -o jsonpath='{.spec.nodeName}'` +$ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut -d'/' -f5` +$ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" ``` You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. @@ -114,10 +117,10 @@ In the below commands, we are - Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group ```bash -$ AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` -$ EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` -$ MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` -$ MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` +$ export AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` +$ export EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` +$ export MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` +$ export MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` $ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[].IpPermissions[]" [ { @@ -159,13 +162,13 @@ In the below commands, we are - Adding inbound rule to mount target security group allowing traffic on port 2049 from VPC CIDR. ```bash -$ VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` -$ CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` +$ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` After 3-4 minutes, you should notice that the pod in default namespace is in running state -```bash +```bash timeout=180 hook=fix-3 hookTimeout=600 $ kubectl get pods $POD NAME READY STATUS RESTARTS AGE efs-app-5c4df89785-m4qz4 1/1 Running 0 102m diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-1.sh b/website/docs/troubleshooting/pod/tests/hook-fix-1.sh new file mode 100644 index 000000000..1c86ed001 --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-1.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 120 + + if kubectl get pods --selector="app=app-new" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-2.sh b/website/docs/troubleshooting/pod/tests/hook-fix-2.sh new file mode 100644 index 000000000..9c3ad3ba8 --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-2.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 180 + + if kubectl get pods --selector="app=app-private" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-3.sh b/website/docs/troubleshooting/pod/tests/hook-fix-3.sh new file mode 100644 index 000000000..bbd797ead --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-3.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 240 + + if kubectl get pods --selector="app=efs-app" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-suite.sh b/website/docs/troubleshooting/pod/tests/hook-suite.sh new file mode 100644 index 000000000..36ca4218e --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-suite.sh @@ -0,0 +1,11 @@ +set -e + +before() { + echo "noop" +} + +after() { + prepare-environment +} + +"$@" \ No newline at end of file diff --git a/website/test-durations.json b/website/test-durations.json index 30575364c..c618ef0ee 100644 --- a/website/test-durations.json +++ b/website/test-durations.json @@ -191,5 +191,8 @@ "/security/secrets-management/secrets-manager/external-secrets.md": 14963, "/security/secrets-management/secrets-manager/index.md": 281009, "/security/secrets-management/secrets-manager/mounting-secrets.md": 16049, - "/troubleshooting/alb/index.md": 16049 + "/troubleshooting/alb/index.md": 16049, + "/troubleshooting/pod/image_pull_1.md": 16049, + "/troubleshooting/pod/image_pull_2.md": 16049, + "/troubleshooting/pod/pod_stuck.md": 16049 } From ab282aa3affb941278531a8d4f5f7c0880c22bed Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Tue, 5 Nov 2024 22:11:18 +0000 Subject: [PATCH 03/12] fixed pre-commit errors --- .../pod/crash/.workshop/cleanup.sh | 2 -- .../pod/crash/.workshop/terraform/main.tf | 18 +++++----- .../pod/crash/.workshop/terraform/outputs.tf | 5 +-- .../pod/crash/.workshop/terraform/vars.tf | 2 +- .../pod/image/.workshop/cleanup.sh | 2 -- .../pod/image/.workshop/terraform/main.tf | 2 +- .../pod/image/.workshop/terraform/outputs.tf | 3 +- .../pod/image/.workshop/terraform/vars.tf | 2 +- .../troubleshooting/pod/image/deployment.yaml | 2 +- .../pod/permissions/.workshop/cleanup.sh | 2 -- .../permissions/.workshop/terraform/main.tf | 30 ++++++++-------- .../.workshop/terraform/outputs.tf | 3 +- .../permissions/.workshop/terraform/vars.tf | 2 +- .../docs/troubleshooting/pod/image_pull_1.md | 9 ++--- .../docs/troubleshooting/pod/image_pull_2.md | 34 +++++++++---------- website/docs/troubleshooting/pod/index.md | 3 +- website/docs/troubleshooting/pod/pod_stuck.md | 22 ++++++------ website/test-durations.json | 4 +-- 18 files changed, 73 insertions(+), 74 deletions(-) diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh index f37989081..403d252cf 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment efs-app -n default > /dev/null 2>&1; then kubectl delete deployment efs-app -n default else diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf index 06809a932..6bd5c988f 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } data "aws_vpc" "selected" { @@ -37,11 +37,11 @@ data "aws_subnets" "public" { } } -data "aws_region" "current" {} - +/* data "aws_eks_cluster" "cluster" { name = var.eks_cluster_id } +*/ module "eks_blueprints_addons" { source = "aws-ia/eks-blueprints-addons/aws" @@ -62,13 +62,13 @@ module "eks_blueprints_addons" { resource "aws_efs_file_system" "efs" { tags = { Name = "eks-workshop-efs" - } + } } resource "aws_efs_mount_target" "mount_targets" { - for_each = toset(data.aws_subnets.public.ids) - file_system_id = resource.aws_efs_file_system.efs.id - subnet_id = each.value + for_each = toset(data.aws_subnets.public.ids) + file_system_id = resource.aws_efs_file_system.efs.id + subnet_id = each.value security_groups = [resource.aws_security_group.efs_sg.id] } @@ -101,13 +101,13 @@ data "template_file" "deployment_yaml" { template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") vars = { - filesystemid = "${resource.aws_efs_file_system.efs.id}" + filesystemid = "resource.aws_efs_file_system.efs.id" } } resource "local_file" "deployment_yaml" { filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/deployment.yaml" - content = data.template_file.deployment_yaml.rendered + content = data.template_file.deployment_yaml.rendered } resource "null_resource" "kustomize_app" { diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf index 688f66d65..d50ab0d36 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf @@ -1,11 +1,12 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } output "environment_variables" { description = "Environment variables to be added to the IDE shell" value = merge({ - VPC_ID = data.aws_vpc.selected.id + VPC_ID = data.aws_vpc.selected.id }, { for index, id in data.aws_subnets.public.ids : "PUBLIC_SUBNET_${index + 1}" => id } diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh index ac311489e..37769eb30 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment ui-new -n default > /dev/null 2>&1; then kubectl delete deploy ui-new -n default else diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf index 565d04435..cd46cf5a1 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf index efa7cab69..269e7a3b0 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf @@ -1,3 +1,4 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/manifests/modules/troubleshooting/pod/image/deployment.yaml b/manifests/modules/troubleshooting/pod/image/deployment.yaml index 687f170ca..7e07e3ef8 100644 --- a/manifests/modules/troubleshooting/pod/image/deployment.yaml +++ b/manifests/modules/troubleshooting/pod/image/deployment.yaml @@ -58,4 +58,4 @@ spec: volumes: - name: tmp-volume emptyDir: - medium: Memory \ No newline at end of file + medium: Memory diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh index 53b68768d..068f0e83f 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment ui-private -n default > /dev/null 2>&1; then kubectl delete deploy ui-private -n default else diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf index 35fdecbad..b8aa2c22a 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } data "aws_region" "current" {} @@ -24,12 +24,14 @@ data "aws_eks_cluster" "cluster" { name = var.eks_cluster_id } +/* data "aws_vpc" "selected" { tags = { created-by = "eks-workshop-v2" env = var.addon_context.eks_cluster_id } } +*/ data "aws_eks_node_group" "default" { cluster_name = data.aws_eks_cluster.cluster.id @@ -42,19 +44,19 @@ data "aws_ssm_parameter" "eks_ami" { data "aws_subnets" "selected" { tags = { - env = var.addon_context.eks_cluster_id + env = var.addon_context.eks_cluster_id } } resource "aws_iam_role" "ecr_ec2_role" { - name = "ecr_ec2_role" + name = "ecr_ec2_role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { - Service = "ec2.amazonaws.com" + Service = "ec2.amazonaws.com" } Action = "sts:AssumeRole" }, @@ -69,9 +71,9 @@ resource "aws_iam_instance_profile" "ecr_ec2" { } resource "aws_instance" "ui_to_ecr" { - ami = data.aws_ssm_parameter.eks_ami.value - instance_type = "t3.medium" - user_data = <<-EOF + ami = data.aws_ssm_parameter.eks_ami.value + instance_type = "t3.medium" + user_data = <<-EOF #!/bin/bash sudo yum update -y sudo amazon-linux-extras install docker @@ -82,19 +84,19 @@ resource "aws_instance" "ui_to_ecr" { aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 EOF - subnet_id = element(data.aws_subnets.selected.ids, 0) + subnet_id = element(data.aws_subnets.selected.ids, 0) iam_instance_profile = resource.aws_iam_instance_profile.ecr_ec2.name - depends_on = [resource.aws_ecr_repository.ui] + depends_on = [resource.aws_ecr_repository.ui] } resource "aws_ecr_repository" "ui" { name = "retail-sample-app-ui" image_tag_mutability = "MUTABLE" - force_delete = true - + force_delete = true + } -data "aws_iam_policy_document" "private-registry" { +data "aws_iam_policy_document" "private_registry" { statement { sid = "new policy" effect = "Deny" @@ -126,7 +128,7 @@ data "aws_iam_policy_document" "private-registry" { resource "aws_ecr_repository_policy" "example" { repository = aws_ecr_repository.ui.name - policy = data.aws_iam_policy_document.private-registry.json + policy = data.aws_iam_policy_document.private_registry.json depends_on = [resource.aws_instance.ui_to_ecr] } @@ -141,7 +143,7 @@ data "template_file" "deployment_yaml" { resource "local_file" "deployment_yaml" { filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/deployment.yaml" - content = data.template_file.deployment_yaml.rendered + content = data.template_file.deployment_yaml.rendered } /* diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf index efa7cab69..269e7a3b0 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf @@ -1,3 +1,4 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md index 317c6115e..9a98ee4c7 100644 --- a/website/docs/troubleshooting/pod/image_pull_1.md +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -76,13 +76,13 @@ public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0 ### Step 4 -From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at https://gallery.ecr.aws/aws-containers . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui and since the image does not exist we will see Repository not found message as shown below. +From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at [aws-containers ECR](https://gallery.ecr.aws/aws-containers) . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case [image-uri](https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui) and since the image does not exist we will see Repository not found message as shown below. ![RepoDoesNotExist](./assets/rep-not-found.webp) ### Step 5 -To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the URL https://gallery.ecr.aws/aws-containers/retail-store-sample-ui. You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. +To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the [image-uri](https://gallery.ecr.aws/aws-containers/retail-store-sample-ui). You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. ![RepoExist](./assets/repo-found.webp) @@ -112,7 +112,8 @@ General troubleshooting workflow of the pod with ImagePullBackOff on public imag - Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. - If not found, ensure that the image exists in the path referenced. - For access denied, check the permissions on worker node role. -- For timeout on public images on ECR, ensure that the worker node is configured to reach the internet via IGW/TGW/NAT. +- For timeout on public images on ECR, ensure that the worker node networking is configured to reach the internet via IGW/TGW/NAT. References: -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html + +- [ECR-with-EKS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html) diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index 47886b879..d82fbb250 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -17,7 +17,7 @@ $ prepare-environment troubleshooting/pod/permissions The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: - Create a ECR repo named retail-sample-app-ui. -- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 +- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 - Create a new deployment named ui-private in default namespace - Introduce an issue to the deployment spec, so we can learn how to troubleshoot this type of issues @@ -60,11 +60,11 @@ Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 5m15s default-scheduler Successfully assigned default/ui-private-7655bf59b9-jprrj to ip-10-42-33-232.us-west-2.compute.internal - Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" - Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https://682844965773.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden + Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https:/"1234567890.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden Warning Failed 3m53s (x4 over 5m14s) kubelet Error: ErrImagePull Warning Failed 3m27s (x6 over 5m14s) kubelet Error: ImagePullBackOff - Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" ``` ### Step 3 @@ -72,8 +72,7 @@ Events: From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. ```bash -$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' -682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}'"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 ``` ### Step 4 @@ -81,11 +80,11 @@ $ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*]. From the image URI, we can see that the image is referenced from the account where our EKS cluster is in. Lets check the ECR repository to see if any such image exists. ```bash -$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 +$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 { "imageDetails": [ { - "registryId": "682844965773", + "registryId": "1234567890", "repositoryName": "retail-sample-app-ui", "imageDigest": "sha256:b338785abbf5a5d7e0f6ebeb8b8fc66e2ef08c05b2b48e5dfe89d03710eec2c1", "imageTags": [ @@ -100,7 +99,7 @@ $ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids ima } ``` -You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. +You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. :::info Alternatively, you can also check the console for the same. Click the button below to open the ECR Console. Then click on retail-sample-app-ui repository and the image tag 0.4.0, you should then see the complete URI of the image which should match with the URI in deployment spec i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 @@ -113,7 +112,7 @@ Alternatively, you can also check the console for the same. Click the button bel ### Step 5 -As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. +As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. Get the IAM role attached to worker nodes in the managed node group of the cluster and list the IAM policies attached to it. @@ -151,9 +150,9 @@ The perimissions to the ECR repository can be managed at both Identity and Resou ```bash $ aws ecr get-repository-policy --repository-name retail-sample-app-ui { - "registryId": "682844965773", + "registryId": "1234567890", "repositoryName": "retail-sample-app-ui", - "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam::682844965773:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" + "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam:"1234567890:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" } ``` @@ -165,7 +164,7 @@ $ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow $ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://~/ecr-policy.json ``` -You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. +You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. ### Step 7 @@ -177,7 +176,7 @@ NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m ``` -That concludes the private ECR ImagePullBackOff troubleshooting section. +That concludes the private ECR ImagePullBackOff troubleshooting section. ## Wrapping it up @@ -189,6 +188,7 @@ General troubleshooting workflow of the pod with ImagePullBackOff on private ima - For timeout on ECR, ensure that the worker node is configured to reach the ECR endpoint. References: -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html -- https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html + +- [ECR_on_EKS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html) +- [ECR_repo_policies](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) +- [EKS_networking](https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html) diff --git a/website/docs/troubleshooting/pod/index.md b/website/docs/troubleshooting/pod/index.md index 1cdc069ac..9ab5da433 100644 --- a/website/docs/troubleshooting/pod/index.md +++ b/website/docs/troubleshooting/pod/index.md @@ -8,7 +8,6 @@ description: "Run deployments with diferent image paths/sources and persistent v ::required-time -In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. +In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. - Pod Issues such as readiness/liveness probe failures and scheduling issues will be coming soon under this section of troubleshooting module. - diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index d27363700..63f566dc1 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -20,7 +20,6 @@ The preparation of the lab might take a couple of minutes and it will make the f - Create a EFS filesystem and mount targets. - Create a deployment named efs-app backed by a persistent volume claim named efs-claim to leverage EFS as persistent volume, in the default namespace. - ::: You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/crash/.workshop/terraform). @@ -62,13 +61,13 @@ Events: Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 Mounting command: mount Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount -Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. No mount target created for the file system fs-00a4069aec7924c8c is in available state yet, please retry in 5 minutes. Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 Mounting command: mount Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount -Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. Connection to the mount target IP address 10.42.41.35 timeout. Please retry in 5 minutes if the mount target is newly created. Otherwise check your VPC and security group configuration to ensure your file system is reachable via TCP port 2049 from your instance. Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. Warning FailedMount 19m kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 32 @@ -84,7 +83,7 @@ Warning: config file does not have fips_mode_enabled item in section mount.. You ### Step 3 -From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. +From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. Connection to the mount target IP address x.x.x.x timeout.'. This gives us an idea that the EFS file system is failed to mount for the pods to use as persistent volume. With out which the pod cannot move to running state. Lets check the networking configuration of the node on which the pod is scheduled to run. In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. @@ -95,6 +94,7 @@ $ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut $ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" ``` + You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. :::info @@ -110,8 +110,9 @@ Alternatively, click the button below to open the EKS Console. Then navigate to Now, lets check the EFS file system networking configuration. -In the below commands, we are -- Retrieving the Availability zone of the worker node using instance id. +In the below commands, we are + +- Retrieving the Availability zone of the worker node using instance id. - Retrieving the EFS id from the persistent volume claim. - Retrieving the mount target ENI for the availability zone corresponding to the instance Id. - Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group @@ -141,7 +142,6 @@ $ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[]. You should see that the security group attached to the mount target of EFS have inbound rules only on port 80 from the VPC CIDR. However, for the mount to be successful the security group of mount target should allow traffic on port 2049. Which is why the mount request is timing out from the EKS worker node. - :::info Alternatively, you can also check the console for the same. Click the button below to open the EFS Console. Then click on EFS file system Id which has name as eks-workshop-efs. Then click on Network to view mount targets for all availability zones and the security groups attached to the each mount target. @@ -166,7 +166,8 @@ $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.r $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` -After 3-4 minutes, you should notice that the pod in default namespace is in running state + +After 3-4 minutes, you should notice that the pod in default namespace is in running state ```bash timeout=180 hook=fix-3 hookTimeout=600 $ kubectl get pods $POD @@ -183,7 +184,6 @@ This concludes the pod stuck in ContainerCreating troubleshooting section. General, troubleshooting workflow of pods stuck in ContainerCreating state is to check pod events and for volume mount issues: - Check the volume claim used by the pod and identify the type of volume used. -- Then check the csi driver used for that volume and check the requiements to use that volume in EKS pods at https://docs.aws.amazon.com/eks/latest/userguide/storage.html +- Then check the csi driver used for that volume and check the requirements to use that volume in EKS pods at [EKS Storage](https://docs.aws.amazon.com/eks/latest/userguide/storage.html) - Confirm that all the requiements mentioned in the corresponding storage type document are met. -- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues - +- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at [EFS CSi Driver](https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues) diff --git a/website/test-durations.json b/website/test-durations.json index c618ef0ee..949335ff4 100644 --- a/website/test-durations.json +++ b/website/test-durations.json @@ -193,6 +193,6 @@ "/security/secrets-management/secrets-manager/mounting-secrets.md": 16049, "/troubleshooting/alb/index.md": 16049, "/troubleshooting/pod/image_pull_1.md": 16049, - "/troubleshooting/pod/image_pull_2.md": 16049, - "/troubleshooting/pod/pod_stuck.md": 16049 + "/troubleshooting/pod/image_pull_2.md": 16049, + "/troubleshooting/pod/pod_stuck.md": 16049 } From 67f7c057ed5a39bfccc9a6d3f3b6e8691e7b37fb Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 03:22:01 +0000 Subject: [PATCH 04/12] fixed pre-commit errors --- .../troubleshooting/pod/crash/.workshop/terraform/main.tf | 2 +- website/docs/troubleshooting/pod/image_pull_2.md | 6 ++++-- website/docs/troubleshooting/pod/pod_stuck.md | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf index 6bd5c988f..5237da270 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -101,7 +101,7 @@ data "template_file" "deployment_yaml" { template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") vars = { - filesystemid = "resource.aws_efs_file_system.efs.id" + filesystemid = resource.aws_efs_file_system.efs.id } } diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index d82fbb250..977bc0dcb 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -72,7 +72,8 @@ Events: From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. ```bash -$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}'"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' +"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" ``` ### Step 4 @@ -168,9 +169,10 @@ You can confirm if the ECR repo policy updated successfully, by using the above ### Step 7 -Now, check if the pods are running. +Now, restart the deployment and check if the pods are running. ```bash timeout=180 hook=fix-2 hookTimeout=600 +$ kubectl rollout restart deploy ui-private $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 63f566dc1..6cb04e953 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -164,6 +164,9 @@ In the below commands, we are ```bash $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ echo $VPC_ID +$ echo $CIDR +$ echo $MT_SG $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` From 668c661e2e5f03d364ffe4fa7213394d72ca15b0 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 17:17:17 +0000 Subject: [PATCH 05/12] fix pod crash --- website/docs/troubleshooting/pod/pod_stuck.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 6cb04e953..63f566dc1 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -164,9 +164,6 @@ In the below commands, we are ```bash $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` -$ echo $VPC_ID -$ echo $CIDR -$ echo $MT_SG $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` From 57c579f7e991d5b7e4176ea76bc4faf88ca21b6d Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 21:11:34 +0000 Subject: [PATCH 06/12] fixed the readme content --- .../docs/troubleshooting/pod/image_pull_2.md | 64 +++++++++++++++++-- website/docs/troubleshooting/pod/pod_stuck.md | 28 ++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index 977bc0dcb..1c53c11aa 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -149,16 +149,72 @@ You should see that the AWS managed policy "arn:aws:iam::aws:policy/AmazonEC2Con The perimissions to the ECR repository can be managed at both Identity and Resource level. The Identity level permissions are provided at IAM and the resource level permissions are provided at the repository level. As we confirmed that identity based permissions are good, the issue could be with resource level permissions. Lets the check the policy for ECR repo. ```bash -$ aws ecr get-repository-policy --repository-name retail-sample-app-ui +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query policyText --output text | jq . { - "registryId": "1234567890", - "repositoryName": "retail-sample-app-ui", - "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam:"1234567890:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "new policy", + "Effect": "Deny", + "Principal": { + "AWS": "arn:aws:iam::1234567890:role/EksNodeGroupRole" + }, + "Action": [ + "ecr:UploadLayerPart", + "ecr:SetRepositoryPolicy", + "ecr:PutImage", + "ecr:ListImages", + "ecr:InitiateLayerUpload", + "ecr:GetRepositoryPolicy", + "ecr:GetDownloadUrlForLayer", + "ecr:DescribeRepositories", + "ecr:DeleteRepositoryPolicy", + "ecr:DeleteRepository", + "ecr:CompleteLayerUpload", + "ecr:BatchGetImage", + "ecr:BatchDeleteImage", + "ecr:BatchCheckLayerAvailability" + ] + } + ] } ``` You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. +We will be using below json file to modify the ecr repository permissions. You can notice that the Effect is set to Allow for the Node IAM role. + +```json {6} +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "new policy", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::1234567890:role/EksNodeGroupRole" + }, + "Action": [ + "ecr:UploadLayerPart", + "ecr:SetRepositoryPolicy", + "ecr:PutImage", + "ecr:ListImages", + "ecr:InitiateLayerUpload", + "ecr:GetRepositoryPolicy", + "ecr:GetDownloadUrlForLayer", + "ecr:DescribeRepositories", + "ecr:DeleteRepositoryPolicy", + "ecr:DeleteRepository", + "ecr:CompleteLayerUpload", + "ecr:BatchGetImage", + "ecr:BatchDeleteImage", + "ecr:BatchCheckLayerAvailability" + ] + } + ] +} +``` + ```bash $ export ROLE_ARN=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole'` $ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow","Principal":{"AWS":'${ROLE_ARN}'},"Action":["ecr:BatchCheckLayerAvailability","ecr:BatchDeleteImage","ecr:BatchGetImage","ecr:CompleteLayerUpload","ecr:DeleteRepository","ecr:DeleteRepositoryPolicy","ecr:DescribeRepositories","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:InitiateLayerUpload","ecr:ListImages","ecr:PutImage","ecr:SetRepositoryPolicy","ecr:UploadLayerPart"]}]}' > ~/ecr-policy.json diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 63f566dc1..c628d72da 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -93,6 +93,19 @@ $ export NODE=`kubectl get pod $POD -o jsonpath='{.spec.nodeName}'` $ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut -d'/' -f5` $ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" +[ + { + "IpProtocol": "-1", + "UserIdGroupPairs": [], + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0" + } + ], + "Ipv6Ranges": [], + "PrefixListIds": [] + } +] ``` You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. @@ -165,6 +178,21 @@ In the below commands, we are $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR +{ + "Return": true, + "SecurityGroupRules": [ + { + "SecurityGroupRuleId": "sgr-05ae66b3cfaf2b03c", + "GroupId": "sg-0d69452207db88cde", + "GroupOwnerId": "682844965773", + "IsEgress": false, + "IpProtocol": "tcp", + "FromPort": 2049, + "ToPort": 2049, + "CidrIpv4": "10.42.0.0/16" + } + ] +} ``` After 3-4 minutes, you should notice that the pod in default namespace is in running state From 730da0e2cd56c48db4ad9d6b720158f5d8d34312 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Thu, 24 Oct 2024 18:36:22 +0000 Subject: [PATCH 07/12] pod troubleshooting scenarios --- .../pod/crash/.workshop/cleanup.sh | 27 +++ .../.workshop/terraform/deployment.yaml.tpl | 51 +++++ .../pod/crash/.workshop/terraform/main.tf | 124 +++++++++++ .../pod/crash/.workshop/terraform/outputs.tf | 13 ++ .../pod/crash/.workshop/terraform/vars.tf | 36 ++++ .../pod/image/.workshop/cleanup.sh | 9 + .../pod/image/.workshop/terraform/main.tf | 32 +++ .../pod/image/.workshop/terraform/outputs.tf | 3 + .../pod/image/.workshop/terraform/vars.tf | 36 ++++ .../troubleshooting/pod/image/deployment.yaml | 61 ++++++ .../pod/permissions/.workshop/cleanup.sh | 10 + .../.workshop/terraform/deployment.yaml.tpl | 61 ++++++ .../permissions/.workshop/terraform/main.tf | 185 +++++++++++++++++ .../.workshop/terraform/outputs.tf | 3 + .../permissions/.workshop/terraform/vars.tf | 36 ++++ .../pod/assets/rep-not-found.webp | Bin 0 -> 33186 bytes .../pod/assets/repo-found.webp | Bin 0 -> 92912 bytes .../docs/troubleshooting/pod/image_pull_1.md | 116 +++++++++++ .../docs/troubleshooting/pod/image_pull_2.md | 193 ++++++++++++++++++ website/docs/troubleshooting/pod/index.md | 14 ++ website/docs/troubleshooting/pod/pod_stuck.md | 186 +++++++++++++++++ 21 files changed, 1196 insertions(+) create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf create mode 100644 manifests/modules/troubleshooting/pod/image/deployment.yaml create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf create mode 100644 manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf create mode 100644 website/docs/troubleshooting/pod/assets/rep-not-found.webp create mode 100644 website/docs/troubleshooting/pod/assets/repo-found.webp create mode 100644 website/docs/troubleshooting/pod/image_pull_1.md create mode 100644 website/docs/troubleshooting/pod/image_pull_2.md create mode 100644 website/docs/troubleshooting/pod/index.md create mode 100644 website/docs/troubleshooting/pod/pod_stuck.md diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh new file mode 100644 index 000000000..f37989081 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment efs-app -n default > /dev/null 2>&1; then + kubectl delete deployment efs-app -n default +else + echo "Deployment efs-app does not exist." +fi + +if kubectl get pvc efs-claim -n default > /dev/null 2>&1; then + kubectl delete pvc efs-claim -n default +else + echo "PVC efs-claim does not exist." +fi +PV_NAME=$(kubectl get pv -o jsonpath='{.items[?(@.spec.claimRef.name=="efs-claim")].metadata.name}') +if [ -n "$PV_NAME" ]; then + kubectl delete pv "$PV_NAME" +else + echo "No PV associated with efs-claim." +fi + +if kubectl get storageclass efs-sc > /dev/null 2>&1; then + kubectl delete storageclass efs-sc +else + echo "Storage class efs-sc does not exist." +fi diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl new file mode 100644 index 000000000..609c1f1a4 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl @@ -0,0 +1,51 @@ +--- +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: efs-sc +provisioner: efs.csi.aws.com +parameters: + provisioningMode: efs-ap + fileSystemId: ${filesystemid} + directoryPerms: "700" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: efs-claim +spec: + accessModes: + - ReadWriteMany + storageClassName: efs-sc + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: efs-app + labels: + app: efs-app +spec: + replicas: 1 + selector: + matchLabels: + app: efs-app + template: + metadata: + labels: + app: efs-app + spec: + containers: + - name: app + image: centos + command: ["/bin/sh"] + args: ["-c", "while true; do echo $(date -u) >> /example/out.txt; sleep 5; done"] + volumeMounts: + - name: persistent-storage + mountPath: /example + volumes: + - name: persistent-storage + persistentVolumeClaim: + claimName: efs-claim \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf new file mode 100644 index 000000000..06809a932 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -0,0 +1,124 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + +data "aws_vpc" "selected" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } +} + +data "aws_subnets" "public" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } + + filter { + name = "tag:Name" + values = ["*Public*"] + } +} + +data "aws_region" "current" {} + +data "aws_eks_cluster" "cluster" { + name = var.eks_cluster_id +} + +module "eks_blueprints_addons" { + source = "aws-ia/eks-blueprints-addons/aws" + version = "1.16.2" + + enable_aws_efs_csi_driver = true + aws_efs_csi_driver = { + wait = true + } + + cluster_name = var.addon_context.eks_cluster_id + cluster_endpoint = var.addon_context.aws_eks_cluster_endpoint + cluster_version = var.eks_cluster_version + oidc_provider_arn = var.addon_context.eks_oidc_provider_arn +} + + +resource "aws_efs_file_system" "efs" { + tags = { + Name = "eks-workshop-efs" + } +} + +resource "aws_efs_mount_target" "mount_targets" { + for_each = toset(data.aws_subnets.public.ids) + file_system_id = resource.aws_efs_file_system.efs.id + subnet_id = each.value + security_groups = [resource.aws_security_group.efs_sg.id] +} + +resource "aws_security_group" "efs_sg" { + name = "efs_sg" + description = "Allow tarffic to efs" + vpc_id = data.aws_vpc.selected.id + + tags = { + Name = "efs_sg" + } +} + +resource "aws_vpc_security_group_ingress_rule" "allow_ipv4" { + security_group_id = aws_security_group.efs_sg.id + cidr_ipv4 = data.aws_vpc.selected.cidr_block + from_port = 80 + ip_protocol = "tcp" + to_port = 80 +} + + +resource "aws_vpc_security_group_egress_rule" "allow_all_traffic_ipv4" { + security_group_id = aws_security_group.efs_sg.id + cidr_ipv4 = "0.0.0.0/0" + ip_protocol = "-1" # semantically equivalent to all ports +} + +data "template_file" "deployment_yaml" { + template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") + + vars = { + filesystemid = "${resource.aws_efs_file_system.efs.id}" + } +} + +resource "local_file" "deployment_yaml" { + filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/deployment.yaml" + content = data.template_file.deployment_yaml.rendered +} + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/crash/" + when = create + } + + depends_on = [resource.local_file.deployment_yaml, resource.aws_efs_file_system.efs] +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..688f66d65 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf @@ -0,0 +1,13 @@ +output "account_id" { + value = local.account_id +} + +output "environment_variables" { + description = "Environment variables to be added to the IDE shell" + value = merge({ + VPC_ID = data.aws_vpc.selected.id + }, { + for index, id in data.aws_subnets.public.ids : "PUBLIC_SUBNET_${index + 1}" => id + } + ) +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh new file mode 100644 index 000000000..ac311489e --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment ui-new -n default > /dev/null 2>&1; then + kubectl delete deploy ui-new -n default +else + echo "delpoyment ui-new does not exist" +fi diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf new file mode 100644 index 000000000..565d04435 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf @@ -0,0 +1,32 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/image/" + when = create + } +} + diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..efa7cab69 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "account_id" { + value = local.account_id +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/deployment.yaml b/manifests/modules/troubleshooting/pod/image/deployment.yaml new file mode 100644 index 000000000..687f170ca --- /dev/null +++ b/manifests/modules/troubleshooting/pod/image/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ui-new + labels: + app: app-new +spec: + replicas: 1 + selector: + matchLabels: + app: app-new + template: + metadata: + annotations: + prometheus.io/path: /actuator/prometheus + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: app-new + spec: + securityContext: + fsGroup: 1000 + containers: + - name: ui + env: + - name: JAVA_OPTS + value: -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/urandom + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + image: "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 45 + periodSeconds: 20 + resources: + limits: + memory: 1.5Gi + requests: + cpu: 250m + memory: 1.5Gi + volumeMounts: + - mountPath: /tmp + name: tmp-volume + volumes: + - name: tmp-volume + emptyDir: + medium: Memory \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh new file mode 100644 index 000000000..53b68768d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +aws eks update-kubeconfig --name eks-workshop + +if kubectl get deployment ui-private -n default > /dev/null 2>&1; then + kubectl delete deploy ui-private -n default +else + echo "delpoyment ui-private does not exist" +fi + diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl new file mode 100644 index 000000000..906b59f34 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ui-private + labels: + app: app-private +spec: + replicas: 1 + selector: + matchLabels: + app: app-private + template: + metadata: + annotations: + prometheus.io/path: /actuator/prometheus + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: app-private + spec: + securityContext: + fsGroup: 1000 + containers: + - name: ui + env: + - name: JAVA_OPTS + value: -XX:MaxRAMPercentage=75.0 -Djava.security.egd=file:/dev/urandom + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + image: ${image} + imagePullPolicy: Always + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /actuator/health/liveness + port: 8080 + initialDelaySeconds: 45 + periodSeconds: 20 + resources: + limits: + memory: 1.5Gi + requests: + cpu: 250m + memory: 1.5Gi + volumeMounts: + - mountPath: /tmp + name: tmp-volume + volumes: + - name: tmp-volume + emptyDir: + medium: Memory \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf new file mode 100644 index 000000000..35fdecbad --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf @@ -0,0 +1,185 @@ +terraform { + required_providers { + # kubectl = { + # source = "gavinbunney/kubectl" + # version = ">= 1.14" + # } + } +} + +provider "aws" { + region = "us-east-1" + alias = "virginia" +} + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + +data "aws_region" "current" {} + +data "aws_eks_cluster" "cluster" { + name = var.eks_cluster_id +} + +data "aws_vpc" "selected" { + tags = { + created-by = "eks-workshop-v2" + env = var.addon_context.eks_cluster_id + } +} + +data "aws_eks_node_group" "default" { + cluster_name = data.aws_eks_cluster.cluster.id + node_group_name = "default" +} + +data "aws_ssm_parameter" "eks_ami" { + name = "/aws/service/eks/optimized-ami/${var.eks_cluster_version}/amazon-linux-2/recommended/image_id" +} + +data "aws_subnets" "selected" { + tags = { + env = var.addon_context.eks_cluster_id + } +} + +resource "aws_iam_role" "ecr_ec2_role" { + name = "ecr_ec2_role" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + Service = "ec2.amazonaws.com" + } + Action = "sts:AssumeRole" + }, + ] + }) + managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess", "arn:aws:iam::aws:policy/AmazonElasticContainerRegistryPublicPowerUser"] +} + +resource "aws_iam_instance_profile" "ecr_ec2" { + name = "ecr_ec2" + role = resource.aws_iam_role.ecr_ec2_role.name +} + +resource "aws_instance" "ui_to_ecr" { + ami = data.aws_ssm_parameter.eks_ami.value + instance_type = "t3.medium" + user_data = <<-EOF + #!/bin/bash + sudo yum update -y + sudo amazon-linux-extras install docker + sudo service docker start + sudo usermod -a -G docker ec2-user + docker pull public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0 + docker images | grep retail-store | awk '{ print $3 }' | xargs -I {} docker tag {} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 + aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com + docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 + EOF + subnet_id = element(data.aws_subnets.selected.ids, 0) + iam_instance_profile = resource.aws_iam_instance_profile.ecr_ec2.name + depends_on = [resource.aws_ecr_repository.ui] +} + +resource "aws_ecr_repository" "ui" { + name = "retail-sample-app-ui" + image_tag_mutability = "MUTABLE" + force_delete = true + +} + +data "aws_iam_policy_document" "private-registry" { + statement { + sid = "new policy" + effect = "Deny" + + principals { + type = "AWS" + identifiers = [data.aws_eks_node_group.default.node_role_arn] + } + + actions = [ + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "ecr:DescribeRepositories", + "ecr:GetRepositoryPolicy", + "ecr:ListImages", + "ecr:DeleteRepository", + "ecr:BatchDeleteImage", + "ecr:SetRepositoryPolicy", + "ecr:DeleteRepositoryPolicy", + ] + } +} + + +resource "aws_ecr_repository_policy" "example" { + repository = aws_ecr_repository.ui.name + policy = data.aws_iam_policy_document.private-registry.json + depends_on = [resource.aws_instance.ui_to_ecr] +} + +data "template_file" "deployment_yaml" { + template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/.workshop/terraform/deployment.yaml.tpl") + + vars = { + image = "${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } +} + + +resource "local_file" "deployment_yaml" { + filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/deployment.yaml" + content = data.template_file.deployment_yaml.rendered +} + +/* +resource "null_resource" "ui_to_ecr" { + + #provisioner "local-exec" { + # command = "aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com" + #} + + provisioner "local-exec" { + command = "docker pull public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0" + } + + provisioner "local-exec" { + command = "docker images | grep retail-store | awk '{ print $3 }' | xargs -I {} docker tag {} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } + + #provisioner "local-exec" { + # command = "sudo docker tag ${tag} ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + #} + + provisioner "local-exec" { + command = "aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com && docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0" + } + + depends_on = [resource.aws_ecr_repository.ui] +} +*/ + +resource "null_resource" "kustomize_app" { + triggers = { + always_run = timestamp() + } + + provisioner "local-exec" { + command = "kubectl apply -f ~/environment/eks-workshop/modules/troubleshooting/pod/permissions/" + when = create + } + + depends_on = [resource.local_file.deployment_yaml, resource.aws_instance.ui_to_ecr] +} diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf new file mode 100644 index 000000000..efa7cab69 --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "account_id" { + value = local.account_id +} \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf new file mode 100644 index 000000000..39eb0f89d --- /dev/null +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf @@ -0,0 +1,36 @@ +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_id" { + description = "EKS cluster name" + type = string + default = "eks-workshop" +} + +# tflint-ignore: terraform_unused_declarations +variable "eks_cluster_version" { + description = "EKS cluster version" + type = string +} + +# tflint-ignore: terraform_unused_declarations +variable "cluster_security_group_id" { + description = "EKS cluster security group ID" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "addon_context" { + description = "Addon context that can be passed directly to blueprints addon modules" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "tags" { + description = "Tags to apply to AWS resources" + type = any +} + +# tflint-ignore: terraform_unused_declarations +variable "resources_precreated" { + description = "Have expensive resources been created already" + type = bool +} \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/assets/rep-not-found.webp b/website/docs/troubleshooting/pod/assets/rep-not-found.webp new file mode 100644 index 0000000000000000000000000000000000000000..17bcc803804bc7e31531a1111cd13047092012ef GIT binary patch literal 33186 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 literal 0 HcmV?d00001 diff --git a/website/docs/troubleshooting/pod/assets/repo-found.webp b/website/docs/troubleshooting/pod/assets/repo-found.webp new file mode 100644 index 0000000000000000000000000000000000000000..8b343fd290f3a185a03db3fa9571cdbc69b16029 GIT binary patch literal 92912 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

UAmnd7h;lN+e*uR?i$W*XP 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 iK7XE z2*c(COxW6Y0=*MWDYj5KL-IOE@me({V5-5G*l5*?gyq5xJ7(MnQd)Xb1d;vZ@5Q)T zH=F>xlAYwKO@q$vm$#J2OtJu5{`;L-g6=p0#y`=DI_=r{)wAwnay8fn0M!pW&`LxI zt(U_|4Nz!_;bvCs*2~*w*#A~MEO`Niwq}-4#0|g_NgrjW%=x>#;*b1hzM}~@x?qL& z4sSbRm#3^h2lw}8JSnyLi_=_CzXrxz@zhK;U5A2y0``4f&>Cb67X>?=`Lom0j34M3 ze@}^3e>Um|{rkk6QuT!(ODjr`Qx^Jt=kt1{KUlzbb@II|%!T(2$(T6;(|%Vf+N%Y% zd^zr0{lZA<`DyfBfEhqs@OhS~aB_Xz0IKW+6r!RkFj6VbNtNIxTV$^di_tJ ziD%tIG5qPWSE!>M4&zC!U4eU0SjHSL$(I)MR8OT!yT#Z^?qox$m&^P%%UkV)!d|v~ z9U$M-p1rcV2G5~5{}_%cM5T9b9qb*kxp$ zUVV*FA>8TU;GdBZG2uNNmi?JtX^s%!D!17l^JRb6Xp8wZF(3}kcnQ)7%(xbnL`F7% zZ5-<%<}yVdchGsTFg-h_1^PQyW&jBiivmA0S^?$ zvUJQo>&WMFg9|HkswbeC0v;?fTLY6LT=$BjlO&yzQsAB*b7g4mS~kU|mW<_jGrk+x z6ikS=;6;$CXi!Is6jcl0}HL~x#)~ryZm$41Ea<}5vKi{yL!>0E(Eza zEXLH}>{BiVhgJ~Ogx?>pqnMyVsVQv2TnW})>jHjXGN=Vuu!>|?0_()0s759Rm`9p= z30k;y=5%oQBIu19YCinZ1rSaK+cf??^6s=4{Wv+mZ{Q%-4#7Uk#&{ZY#F-3#L8qPBj< zGoi8;NW5GI0uw;XWQBUmlDr0oZZ*A!le0YcZ>-kSrI_+7s?gbvB(zJtu@Ax*Zwu(j z@});iGwsk(EK26(iyJb=(&Jrj{$V2H-&Av&c^46?^&}88#RGNDQfpP;i#Q#%Jv4v| zs2J);U>3)VH4N}mmJj<)ZfP|xHD^iq3HLT>59`PT5HmhJbLHIrB$1-$JqIu}{u2y8 z^3;|*I736R93~!+StO|#j~5$Bj!hYlrK7OTk&ZVmcVUgk-fy^=mUrp|uVYDN1U_{{ zqVrrpxKXF8V>Xr}F^`8?%s^-n*p20@?pb3hFv`=;Gg{&$Efq}29dt~0`=1{THhnHy7EMr}M>cmWxq7=}BGyl2@dh z{o`Z9m2NX3uM8Art-0qORQM!}1!P6`wM1D}x7Q@4YV3QBOYS5TQzw`M1=e zVJEEXy}Fw;K5apQhzLSo52U|fzb-()YmS9kS+DUcf6MiGSTdm19ODD{4tWxo?zk18x z8Uz*F8c)(}a`?eSm!x-qXeocRae3NNc>r>5JWxVkVpS=yEQ??bu?~;Y zd=pv_a6`+Qd(viLw)QKUD{;if{c{q6ic~pjTTf*o<^h;yyA+qRUH{UnTq87A1$`r! zB|44A!xZ$?vVao)2_8SxS6q4-ZgyfLS9m}vRL>GGZJq)YgRsUQ+J#GMebU2!^j)ej z!1Sc}9J9U-_ctl;U)3X#%7Cfn-~}%Ir7p?wg72&dRe2_DO&Es{lr3zaK?oJuf4lMT zGzj~(_g^tJ2u=G+HuHFHmz?*ETW%kt;PuSUM6#ueE>FXx0E7 z(^4G3))-I1M$As6Vq&bZT}~L_RpB0Y4>s3! zSUlaEn2JD+)+=J2jqrmgnKACfz!D%?TAVMpsZqBj+Q)^BMbb|;@I(v!FTm11JC4AY z=v)i2;w@kHc9s)P>VEVzoe7*cx#CqZkDXb%Fd=sOG#57{ z&)dLD+Q)YV{$i4!O0q_Cvzx5yF&A|tN3t?Doq=E_V@uS-I?6N^{K>6Ji2d1(LcTSc?Ch#6BPiiG+nL zBbC6hY7ZX)aJ3C$`lx+;H)T_8ksr)GPxtL=L^E*=yD!ma2AU_{SXlQPcE$UKi*7dI zQ;jcX>CY^ZbYeT2mM?c~=pBc~?@!H^(R&Pai3!Yn8%~ckQKNK5ob-Yu+7hFFUcJ?t z;!fr;Xr_k;2H3z)2~2^SjNbY~7rtvR!#8>@9K4O&h)wCICD7?lb)e}NzB(prW zhl=?#QwCRE3}!i-fUW*tVA|+^Gr;>gcZrk1!RiY88I=b+1!)}`$nYW6O>jBI@~O{V z4|jEE=_I(6rC5yjwodFOd-B*jl9<0e)T{>4?$p?H1d$@U@Vvt=b7JO(+c&&D;Q;3x7fgv3>x1tN=e9xV#=FBR>YmVd(1h~%^Vz);JV-bjnZ~QY zNIx6op$E_VL2iOCmL>vxKPMud`5`4rw;M>XD(Wvu{AG z(}iuj2xn6+92+V~>(+*?)o@ib3J{4#M#@93Chs4&FCP;w2L)*Qk(1A*bVE?4Qx=<+A z1H@xFLA_A^7QWD|Egve=S;%ZNO?l-99hu!03|IU9N(#J6=9{f~qB($~GwBz8J$sY0 zcp{wc0GAMRj8bx$f}rd>Js+eI;9oUBfR3d!Mx4>jZ13*a*5y&7I{KpfxjGjrf_FS= zvLg7k&1OT60n6vfljTIp?_3BfjYgVZ#mBSw@PL?>JC1z@M8xGNgMmH?u->j&jv^IB z7*+6;0kE^t)<8DM?|{jbs=O8ig3e)(A_}2|HLBN(_^Y+MG@d$*(9Rq}=g>9B18U)I zH`H9@1WNBzYTvXp2UV?vIcQr5JzW@vW<8N|&La`euUCkoVi;$|&sF9v104A_k4HZ0 z9$+Rv=F}uhaC%lZ`o|U>*b5B}{MRq>9Li36QaG&@eP>QEyyMUZ(ZnC(M?B|LiXQCO zTxWVATgIi&_(P%&mulg6x5B?jy;#WCcYVc6;#a`qF|@zBud!V`QGLL|^9a3^0)Ya; zrK{+Wo}UaPo|n>K0eGZjsyQxq7=y9)78;FMa&Zl+_wsFZh`MMPPvR;sfc~u$8`uotZ$c~ndawjHFle9|Qh_QI*tRW_CpX!j1 zMP<2HmQP@4O_*HChSjABT3yx`LeYA1*>;;!jlSkrM@9ZZzdVu+L)@EcUw%z-nq|UQZYRZmG zws}j$6(mzvQf{8}?2VNl8X*DBfo-bMg3h4h7yo*=2BfrfUf3F8juTb7K@sQTZ;Pgc zWeO)iF`=R`&g-~D0hUB5x(d_6^a6~x^D`})C~(aFv?LFvd;lDh7}V~$I4QeJ>@GC# zE~XH#dcM9Ph~9hu)N(Sa1{@MBQ8NJm0H#CpbF!2xTjxT*SX~#2 zj_yTJF55Uj0FkBA z(ZOI9CYRs~m5OK4I6{x9C$Tvq#{dty={(6%9G7XltnDES>CmO0Hit56#rwf0S6NEt zVag&&k37BSjuNg2&*N^E*|i(lKUf%`M7Ws5KeERm*7M-}egDV~^qTE{BkbA6YR=DA z_g7~PK;)yATms1TjGg^>3IHGp;0qE4tMYCVP%nJJ4#?w+?Cmi_Dx*iHQl`FRym~gh zota%-N1nV$LMcsRci5V)_61OY!RrWC+^&{M^SuDj0Wp6)36i3++G!65`8GBBCH}iE zL0W#pd%|jPbGKhp!Za>)F8gmyBgUy>(krx4)7eX6I$BeO^}RVhgP6eNBM5?=+0?}Ee+LE^_C@sp7F z|JP;tj(;LjBpd`^5DzH}mkjL+i;3(1Knk{>>OV~7XIVdagp=ya8v=X%8v4}6xZPq~;uDh0qL zf-5)#=xwjH@I_tcSDbl7K!ZV|q)6CLEmtfwBs^P4c8RQHq_PCKBr{JxwYEDeq9{}- zmxO`;l#FG(PL@C{t8f1i zK^fVj_B(+}n#2McxvS9uk<^PKJ;Fz$1W~OjDk^05d42L*hN$R55{l1Mt5VhQHETBt|D}2fQK$$i! ztv0nVhHkFQAuQ_LjSt0YSX5SAPJrZbmFzG2VfLtjAfVZ3ZC~4$Cup;%SK(vTO-Pn! zz|uJ_d@Fn(V^*ZlECeP@tUOU>i5bNG0mWJ+0>Yg?%osL|wx+E>Iquiq^Dn5s`9zG4 zWo-CL3v;MioH_Mwpv}S12OBNfApriId``zP75>SJ#bCoTdS!aWUy+$>6B+bpZwEjM z7gS4>H=wScij;)lm-;+kn@c@Rw9H~wu7;YP{Aq4&@fkr9qHvA}hIs^8|FyF_Y0va6 z{nPb`N=d`DYY-w;GS><0a>wByRonQ|VZR(gMDKM_U1c7c_P8XZ;}xo4+dN&P(qZiycc|TCfjhC?g9eA_7}r4&AJ~fv%0VN9G>QcGKPI zl9dS%_)L+xk9Xd!-IKXpj{iPyu{~~5wIi(9ouM`qVc?1W4C}K|twkYD-w<{ds@Jc4 znKczg>J#>UC7Qu&e$!y@1M}tQu{nw!l4H_L*=(g^LpBVWE$9$#sQqTcVz^4J(4Gsu z=wpw5y^&%sQj%b?JJypCcW zAtvV{ow114{$)j~PRgAOnqf7}#CF2kPc$my?A{&V$2{X$DU|v-;1En0vg#W3wi=vz z4uF>(C(JY74cVaFdHY&@-8$eW%7;~3qIFzs?P*cw1j}DpIspVj!~eN?cm*9(RL*uB z0YMmK=O;`Cv3q`HQd_`i+3$*}n=rJZ*Cu!3>ckw=Mvl2hX_X21d)=vQaqi4G$CH-P7f;MG~0iC=*hige(jWF^rToO-5l3r|I27$urXQW{rjClAYfwkr6 z`9fI-08!4GHzS)Xoyi0oCqd95ewnx2{#CO0HP?KRZEQ-$i)lM8ahBnZ1U)d2q$G?8 zZWh<1X;Yx?eL^MngXXE2@oPVHKV8Nl7erAG0Ow{(uI_xP#c`BG`WQB_J>|IxTswZb zhkc*WWq@)=8eMJ~>^H*ogqqboGbtZ(W%b%98cZ&m+awiRvVX{Qg+~oWr?|^0K6}F~ zWt554jiTKongc(_+*~LC#|o{(KpdQthB!F+n<`m<+PY=xmEIQ}8u^%%Gz+s|rl}*) zlb9&m*pIflxS;M7o^PliD#Nmf<%8ph3hq`JAks4PH(3skc*EPv)>L~=Ni(nJL2@jdA%Fq8z zn_Vd=w`Tm+s8ct{ z@MNawWS`w$z@<>Bz!}$=ylsq+C|FaMg#UEy8a#au`0;LNH_@LI3OWqf)T#iAvu%LJ zgy^6g&B|NKTLLY-47|WNVKiD{x5^WwVls}k0qxgx;s|*3bUNuiw}4aHvqRdukw(u>v{B$qj(+4`aB6IHPOkA( zE=9fzo1C0clJA`Sav&N3B%?J_UFgDmfzOJ3C=Z|n#mOy3lMDW39&Wec-pW@A8PvV= zZ@YS|t#A(6ZQNuon(^ndj=IUpV|L~ztb6^WqDFLk!F(_X*aj;d7|0KFPY0=wHzdN)nPWzx_7Isp3iAWTc#d4rpM zQ+G%h9VYXKId-lXkZe*w*>S!)5i*A&ZNrl3s{PaImII((Fm^5dqqyWO)X)%+sZ~z5 zrpob$?kVo>d{1L$z|;Q#mOyF0i-Qsjf&@WR&5+B#zniVHZDA_TYBHNb;+o$Th};o>34_^^h3PeI)$Uk@SJn;}{=eMp~7@sT+E96$OlnF}0|8Ff16C zWKrKgGaQsD-NU<~mj#a9+aTrl4ee@y7Rbh_h=X{oV{D&~AX$`PfIUM}3#}0m9PZ4J z!)iUW6NCKxoH}*q%Va-S+61?#Q}cFg!O%q$>Xxy<0Ds^le|;zjG@!`af+$OItpAD;ATx(P&<2G=OOf{Y9XlGfET#X>OJQ zUz=tnR5}f03-&=9snN_-5@4m%R2!$}^;7TCfX{Zzf5tB?0uvP$gyb44uX_D?1_&G^ z=jXxwTR;8+WxL~6p#Md|kB`io_|yJO*mJ+bx<;bXm_JqLy=TFVAPBTozik0gM3o|} ztdq*j|5Dq}OVd%J%MS!qlSIG*{RLQc8&&j*jIRJ7dlpDDXt8jjTBexp|H8SFrrVhg zYw=B=hCt2_;%@eX87lF<9So&fN*Z5ja=wSY2tjI79R@V1OyU5@pV0bst_AmIdvLXq>+Deq3g2DTY{(z zf^aX>HUubU?|tiUdqDp~6!g?w-%Q>`!4~yP-*3MWEu15kvfm#4i*o93AV`(F@t`YV zS+a!0ScE1902m*6tHwKkwKyKKC-dAI+^w||+0f-mD#a_FE+%`!gfAQC8@ISsFpcv9 znS3-8gC7fJp;`L!?(lEm8-1BoiO-qrM)73suJU$C_OL-e=D!5AoF4I-8R<0#<*UMa zTlzqruD+_O5hOe}G?89eENfOeJ!H<)-v8`J&JgONGbjZ)p<*1B$blj-#9F^5C=1B| zoI=%j{KhSEc&ieVza49Xs9Fc<(Ci>>w)SrqlOH;Ci^rtFMU<=0vNsKl?wU3mDy6Ay z?4lq!{H*zYHCU_*!#H!#I^;Z+4OZ%1#}3 zxWiG4o+NdKp~aC)(oep7E0WGAueq7&uH~I(B0@^=fKGU_zC2Mm6$%ZBDSZ!c7H{Wu zMe3O(#N%u{S0CFi+HdB$#QTaAUFM5 zIK=9d>Kxtrm+$YZWFx5zAK7x(o4Q_ji;apY&3gWL$lZDz*>X}=E?l?kzVKGQMtjDc zKQ9Y19;NCFL#@4GFfud+W@vpTNi#1{bu)VUqCL;94KML{3#q6mh6&Mo#)+l2R6#+) zj1*R`_>2D&P@>UgS@QQ*lq~aYDbA>LOA6nSVu8tfC~21jdT3zC3eu;&L1LPF6a7y$ zkY0E}S$By}?Pkw18*Qw`R|jF$46~zw^LIiwUN$MA42FcNe|XbuWqQmK1aPoPQfON1 zsU)}p?;{Du1EpB6=JR1kLTVtmPAb%Ke*)sUzSw95i1p+l93j#4DuIx z(;&3pl`I{we%(d1Imd@mkaV3W$Rh2*?K?$NWV=o z577@CWGhw7*rgzFjalp6W}a>GRdALejrQb!)~^@nfuPsrgUwA|tX?N&?qBg{U-D&+ z`DeMm32|sYa0^~mQBCo0X8pQhZYoskRmO~PZBjYU`j*ldbEtz4ZOBTmYBkQ0gpEEG+{$l1|7`>#Uov~NW_<+ zDXU*OD7nG-&PzhN<8kv7G&v}d&o-i_8iUY)r!+>gxp6PhkA z%UxZM30a2`@C99tHzI&4O<)8Ygl8u7LYGFHetpA={QX^gR^{&qU91f*95~+{P?qK2Uyp!v1LWj3Qr7}-<;!OdH*~KEI{nDm-_?8in#o5J+lNlW^S#csvOwOX zhlzabZPrh1O|LX$MN2*c->87ZZx9B}8Z75)8$} z#+2m7x0DCgEqN5gva9W6+c%)Be4TV7OP&Ym+RfJIj%NOC9+!);L1_@#^XFWA55aY? z2GlTqoS!W$%}{j#a;nnJG_@=O?!=pb=-`w(rM!QY;LLzxp^ba#=OP91YZwRay$Ru&7)NNqZt=1p5gaLuW~QO zBgarq^y5xT`~g`Pyk+fv3CI_^d$I;pi0aLp9p0xb)Sp&sz&QpR2`E84Zq}g? zV*}j}$t`-87S2es@u%Yjjm~8?5z(^wENadIsj$W<@Zb3#N+$JRtgnhMq3S_UqjulM z!0H*Ft$4j{0sK4`#C4Y(8T8Nmjx^0H$E&2+5Hq_%HDCR2#Zbi4;zX{iBV+i%=Fl04 zm+4f9mpZ@&%Q1@siH-SaxQ;cG#sU(e?WQ@p;k3$zckl4vV;rikB&LR7X zW;k}`SW)`8!b~^#sAo>DQ1iAHsTk_&qfIn7Ul`3ihX-i#vcAl=Ht4$qwtS{>NSaF) z+Qb=#47Oj#wtoNB%!;(ryuQ;-kUDG3iW)cgy)zMx`Gf7BdIS%l%Dw&4tdrCi6B1}{ zV!bVj>1yh5yL50JdTyRoR&nk;zdz5m=0NtRcdYU$TbvBWS2jsLTYG^O45 z^wzI#Ay@or>hJP?<=AJ`fVzEQG?5eLD)cch82{m zM>|+qJ7o=3lFJ0<9Hi;E1IGo={79c<&kbSSn=OdKO)uez2|TeN9A%k3`nF z-DZO#WG(`SGT5%|2{Bk;2NeZkXlGG>jyQyR zG%;0yYFI-&$hT1kyr%Q&jnV@sKA4J#0ozp5qi#8!-C0~Qi>`rSmL1t%%xR&UlKJV= zIwhI)p?6UY^oPHl6EQRuzIuMMzq=doIVVy3!56<{M7YDs1S91fGpI?qfHXyH&!FRX zi-H4ro??=%wQ%~cBwGkO_>Bj&5l)pTbVVLQ;~ZIB5gUh!4tL`lo9mIM^BGv#yIkWc ze1!0l^$Ps3AAZ?i9J;Mn`6h^ggp6Qi7kP+~HZHPV$>q0jSmL8uj^~C*nH?N6y6JT;z_sy;+MeTWGa1=&Uvm0_7-BLzC6~ zIrV0GNik9(ghSus?`uE^v75xLK`pzLr@Dn)%=RVd4~FTtOiioETMRY+GTjvvU2-x1 zNK23sZy5iC!ji684o*{4ChabkH=8ulP` zybglqiHjcymKgAohEnSU)BSqB(1)R22Uz@)Hs4L5TUa(pk1Piqv$8fE56pLxB~JBR zgxol=NY)Y24uI2hd>vn`O3v8#HLm;FVa-N>tnSH4dzU18pu2lPthL)OvLRkR)T=42 zDkM6eVc(ngU?jpYk{U$oUeB|XEDlWugfXFU zv`h#|;uPUqe+tU#0A2c20nnt^1Z5O&f$i`gB47uShVw#i<-EyGgW52|@KyaPKA`2j zJ%b!I5QFRC&`@}zrKT!!){gC=#@?>5RE5vQM71U>Cmk_lS|b(OGtgl}ImAX*!{sdY zKlE(}dUr}_a*)vs!+qj8ZyEv$Io;K6W0ulrPFg8v-Qa%JYXPSTKmp%FL)QsnzVUgc zo=;Ga_AuCdJWeUyMjME}e?Q~k+6%g&Jkw5TB3X78FL+CUcth+oCNpijI=AK&k1A_Y z4^L1dtcH{okP{NbX<>3y1v!pXY*V)ybKy0YGt5DXy%JS3h*+|6p_HA0f2c5Q!jfn3 z>mG5i`?>siUu+8f__ZyQH=>b9_WrPb47Rf)%Pjyi49NPyY_9hpkKY2}+{#B3Pb%Xb zM{jzT*@M;zsXCefCpb|{#X0D}D>BlD8!9V@C@V6LnBjBVF&_OVo%P+nL((=*ZTqr^D;<;-E;2wPIb8rgXetC=nyIFO_>jWN0Um-E)I|(p zTke&)h4cDPYEnC0(KE?b>bJni zPKfnEF(TJwVX#YC9z3Ne$-GWHKy~M0?JdGJ0g>Y@R>OaU%C>xwG5~BsxC!vQt}#Mn z;kPEd#(_5jnLUEG*W;FZ$D8u5+%=+A|G_kFgvy={rPt>B<2UPw>$kj%;H>T3)|M%7 z6Z(23jvCL|iE%n!0^fgFkdc@w`to!wynkQsfzp3 zcp+5Nx$yCUZdQpSX}UhR%`hSn2zt#>mJZl|GQ*B(oa4r$;P@ESA1S#nw~?tLviJNO zIL9{Tl$AXEuWs2sF|2G`D&S8Ck_4*YCuQjE_fM=-6%0!ZAXVPs;l(Ocg0BA1U zVc$rO!R1Z`O@J5jp^c^u+7XXepu$Q;Hb_fN+v;uCcE&4VQjSvd&wh2c;~e*6oTGfI zz%@bdf1)^(ueB0;6*JpXe)`{UW9ET`lX(5YNA*bToU(Z)5R9uOtfv!6goUjxA3o0$ zV|5^HiZa8^?36pOV*b`AeI^G#*5<#sU=LpOWhXg2>4dDTm*x`$;m=9xL8r1e8=qc{_52oU}=ZCJf9vIT@xPRAX1QZ z-u_tH(mg7!q}Y>!(1R7|yA?ITbp>)4s3vR0gPr(e?GV9UHHGMfTO2GH#6$ zl~7G{joAM3FQ+!^mBlm!t^VW5rQN`tTP#+f9fpdsZ{pyfP0SYY2ZdByL*8|DTN=Px zX@R>5=dBmsE$10;0$7eqCBwe6}Y>KR4t8*tjjSY1tS$f$Ga?TJUwYrCxvu2@?rS?eFoq;*Eho zK?+frpSk-wjQO+lzUqg$aS-G}B=z~34ZyaQEc?cQ>S(-z((5Fk%e&P zS`D>+H3e$uIOCZ%rvGQQ=Mm-4O}&Kmi!(4<6$?1L6w@s+ zjsTTZW=s@J{54z zeqM!p;z=0yEb1eE0rT^~xpV>^m9VdJ?HMSs=H>$%^NBm=a*~YJ^8@Rx@{sjySydln zD{AW&DG>|))?O9S!{0+j3UKvh;G>Gj`Bc|JM;wj%&(+8oAIh2h`3iH=GCa)&oK%TG z`5euTek3Zrq3`H`nc1BNX{{A3Z~bUZc!Jiwv2>sD0}u!MD|9qKw!LXgga958W4~j^ z)T!ivuAWPqi#ff4r*`d<3VnlncvPB^lnkLe<-HDyijvFgujxih=&LJpFc-8N zr$Bcb1_8PCzH{A$=G{9V{LyvXNcv}E-$bluWD#+?VPgAIh!25KsM3hBO7$xIVacw4 zS!jd^=uKM{{J(je9izo!in?scs+ zmU^|Uw)ePoHfHuI7OReTdqRtgy1~i0m zX{F9%pPFzgow$>%QnfArHXs2~E4JwGe9l#@4?diZ=&|iVsDA@bb3r}?5J>Wi*a5Ec zlWzDt#&nPcs{q_S){GNuW8RZhoJ6G=vk@O3V3rUI&l*;h$rKy)g#~C;RSR*#T2cHR z4?qo1wbI>SBPSs*e&C9v{EcTv#U|21S2>8{-0u0z_f6%Zlh>Pg%IK&mxd=tHgG901 z#!gr+SLwSU#eoxoJRTim*qcXXB(ixi4%(kgW)&M5k&%j_ZxSBzw=4qvOaeps1@)+~ z%(OoM&z}q%6g2s{R3!gQ`L}CE=fa>)C4#1QuV%3gcMuA>p14BMGCg|NCVX6odGZXb zS7x@BkfLfkrjc7WYuke^u-;!LY;%hmJQKf7yUnXMpXx_>weR?+(4D*|PzR=%2-G+> zqw)`i(}|k={8C@}#TI|o&+n7Njj_J}0Iq!oSk!diu+^%_A-`mWqjjBP} zXJqd(Nau6*Z{3Y9m-uC3E_i#3!oB}FIPvgs!1=$zDYYGO@Z;n1HeAHcYu3sHcx_P8 z3mFfhFndOK)#7d4vU`9-5NYE!++%Bxiz}WoHC%(8PexjYUBNo1LRgcSS z3j?IMoRQuIzu)zUSeSrppu zZyOCAQy+_6`SX=k6GG-GH7jyi@S`=ByUUenMdm;$O`x=Q{vt4hVitD3MdRv;GaBP{ zi;$E|y^o^?KxS_mUncOO+Lf&$dOxf0c?0!%1J|UWo+&If$N`fE!2}JSd7T4kunIV z^EvPP!;$xWlt$P}agSv5th6f0(o^gp^2(Mi{X6ycP;178R~P;n&9T{{vV&>KMNMNw zS+sXFo;_z1G{5^~A#|DC{B_h!ep?PQ$;~^-GzdI$3FbG}pX4<==HQD#Yq43H3xTE4 zXtP6S1!n=#8Q)X+;3D6MaPs%!BZq6*v3gLS2vCJ%ONZw9Cx`}e-j8g7wkluz9l&wB5nGmw+sre4wK@HhvjQZKri zd|bToZ|p=h58$Ghb8vaMi8uk;jRrixY4eGpJE+Hj;IKD+wW~9<-ON_~7y;SxZ_rt$ zi=*mbCMVCuB4Xf<#QVCYBwr_(2*>wrHtw&(7KesNFq6h`NO47ZXNkx0?4#H|yC0$F z6+c$CafDwj^P5jFi5il6eHXgk&qYpFa3_T$=1#@du#m+WXw}3f`pZ0TCO<-$lrK6{ zyRL~biKE?t5BjyPId8Wh{S{i(rWjpPL_>ZBe;~Nevk9rnTL=>>iAx}=G`|L+_=`)V&}ggtA4^_ zyR|=2+d`nwboRyIVecW=hYJtevX)g!(Z}%jq{f`&-Fc9D{foB}m!>Sw2d#ge)dN8Q z{Q&B|`a1#sU(=q3xG}8>%HaJaDabIr8|kpwG(`GjBqD8U5g;Iy8H7t&gvaI-3wYJR zHNXx1Y6BBvN7iS7;+yIw%&^L4?Hzl717#D91u@i}s!`mN^LK@OPN-Eey8K$4>g;(g zFa6f;PFSSxq$I9m=T$1s`2&jqM<>Npz`B*LJ4WEoW*_7Jiwc3?s>W0;%1HKdOuj(^ zQ;y{PGEorvoUFFFNURK!9)0}fbFdP@Iz4wWdq#_-&B;^J2=m5>7sTe@Y8P(gyFazl z6kco50!FL#xf1%5-*7fOOCaiATH`L^4Ix7{o?|&nZhY#eN&mF-_JYGs5f+WYA(~sE zWiRM$gxG8r6NyZ|WLY{mr8N#MHOQb5cj;+;aVW@|kb2JMVe)GcM9tDnhv4F~Qg}D~ zF~hj6STzZOmo@CZf=I;<@)yA?8T}69V89?U@Q}&{U53`UCpBy}7&rG_I7c%MBXy0G z1pY?vS+4Q`mUR%F&AVh9rtJ-d7dyiBCTu<#1F6CMx8}5;r-jE2{A6jya{*-4!%f@w zzUmJ0IP@u-+?)2KO>`#U(*Qnm(dG)=#zxiaP4!X+BIgDiCW5BJ-|FGve$5#qf|e_6Ufm*7&FvKf*2el)|>&>TTVlbDUQ zg4g*-Nw*}U%?_THa9cYaLIQnMtjK?6G44uf+s)(U> zeMj+WRCPm7mza`QQG$rZY-?GK;9spRIaIC1G!H*}ivCT$P%t_*2eejJn;E{#2gcBe zS{7G{x?AE--Gu#4-LAGI|9;kUBwF8YVC27*%!aRL3>w(p)=hqjx+)34);Xs}o=&{9 z&C7%lS11#b62Nue0?QF#v5{=I(1{TUje(8WGM~$lDN8_~-H7G4Jz;7Mdo>QBhG|LY z(O!lH2d?g6%m$q`EZ8OBtM_2N({BQIUSP$B(RkQBOetH!91F!-BS%6aGKFcWfT$XM z>`WqZp>f~%qpu|$3O&xjv6EUsKoXZyA1`Di`p3JsAG@piU}83rBG+7;<*urq>$cG$ z9(69{Z5;`o7X3;T>kYXth)7*C*oqQIu@e#MjXCzWoL{%xIK{_(2?-~c3vP=h$=G=# zNLqVMKCJ}}#Ng5il^C|=ej4VUwkacy=?Ddo0!<@hDkxb9K4jBsl$Q9=R5MX4u8>Gn zSc)USMVwgJcjE3;KFxLT9i@W!f)EQZQI zZ<;$49@}>a8YH42mc#f+pi4D}9s>gc20vj}$Uuxyb5OO=!WV8R{Qtv?f(T&XS6$P6 zTtSQNK01umG*%cJ1Ik$D*yGo6en${tnOpOKc6_f;4@i<$uC;v~b2YBK{sn+HR?|2A zYWm8Buxhs%4Z@dK^TE}(&8)6bXtI-H80t^JI=UYitcYqdiDZTbX9KQRSCT)sYDM5i z+DW&Sr?l3D(tO{FuUnUn?KOE(tn+nzY5ptR{y{&KpaUprG$w(ud{Uh!9tA` zG+6ew63(XzBKF5UDswGM7v-?&nZL#YONUZyFRB|>x!GD!nK*>mTiWCu5SF5Zl*k4q z8#a9hia<{4LRO}?|Dz!pP+eV4^&0I?JQ`Tf8^@P$)4J`Td4-}kp6^mc1)pil<`^yu zO8MTnk~@A!!t*Hh$r|T&2iXPXm9lKKD!);SGK;Tvs2}W-O}!JPpQDDeg?;6?r0598`3nG%TA5s=<(Rs}^g@0%+6qzif4spVRtyq;&$OKuFsTH% zRpdo@y5foq^|`93qU<8kt5HlwE3{yJUjMS>KT0#A1585d!fz_Cb1yx9zDEN!PF}u2 zbM^iXq{q$!Xxe8kGF{?3fcX~Zp{5$tily>B_hFs|Q%zbASj{OD7&pe4#+S>}H_U3&~$;86Vv{zo-KN%WvF&b zGJESCzP@bdUuzHYW`ram+hDbjT+d4>R8q(Q~I9fvJRQE`X{CF|w4fP$9I2g6VB3~IM<&sBQew~haPhA$7*cVzoK2t^s;RHwxb zwrT2oevuiy?P#8|HT->Fn*CgnAV?;#dM# zi$q!DK~#OJAn}~`AM2=X;^2OW1-Zu3EUh$|c=yry9Fs6$7P1|1ELZb$AJ`9S(mRw- z)3$13AnlZ*ic9x8Jg)+85*cQ1emp+AWEDqg@x0{bxdRisl^}!&i)O?}95gLC9nA^h zZsqOToYk)ofexb}{y$Fj2}74|xd~Ml?48+Yi=Tw2eCM4jH|H8i+(OvZtZ=Rvx`XYk zGWhVoraKglt9lBpjPu-AnTECN`^C)^k-{pwO5r|n9XEbcUVky!%W$-smlCM=M$Yn8Q>o=EYs`q0DvlZi~fEn7S z^(C|70g7yX71)@pvNp}27Kzo3|K_x{PWsJ#$hf-C=l^0c&oMpNCGS4fFL#-XSp|aU zAN~nmHn*4%UP#psz|g+r*qZWgQ4L+;)|;(1;oT{r{)HSDk5Cs+&I8&3=De!J0Z(GOH`>1 zfS|t{YFn9WT+X_+k11L^j&j`NU(!*99X1uvlTePjIIb-{16iQlwN8|NJ4IU=OMD5% z#!Cx0LwE;)mLXWm0L_Oi;9VoGWd~gi4G{hNVbf zJ}ZUa5e!=F&00gYpkLdXh8Q3KB&tZf)DtK%yiXCDPfKNf2PeNV4FLdIOMkygwx#qOg$YQ&I5<&f3QY=EEcud?VK+IcBztv1hA7JUqmk0%?p< zBMX(|I?!{7K`&#ZW5vR1YP?D?6X!_dtP`oFCJ}ZNz&6f!xBcLgZzOEQrtH9?>r>aq z7VYM2%>yhz&Eq=IyLzkQd?yktEuryp7wYW6YNLj?O9ZFH0yXeT|vYDlyb+Et}d?0TZ1*>H6I-`Ajn{2l7ZQ}r}#OG`g7D;z<1<5{} ze+KEGp@nFoNI~8njEUJ$FU1lm<{fJ>RhZHmy1iF*pwe*#nQ=B}>b>fHJ9Czc0E6Jq zf0W;>@MEb^3goLp?}o+^zLCY&|4RS>0037I(w;;ui2$A@AahGku!ujcsO91%Q~GF+ zBk)IRpWV4!FSCFv{wE{~BR ze~%`5#Cvy?HS3bOZc*+cUx5Uzm(I+E40f-X{bS=Rx@27i|eLt809qe8!UiqrFl?eu1BWto;w z6xTxQ?kq3b4TP7j4kkFHk3nO4Rp*-#SUtTM`*qN`F|w${Lcn9INli`=3#yg=uK|N3 z6*yO96ue)s#)ED7!xTp7nV72?Al|yV1>D?CZT^3Ge0_p1f8bg{LGvTHrRf-3(&j!N zOxjq2T#taOW~(D`I)&TpTcxHxegg-GG68tbHnrJL^(kLk)-dWCs|+FW({gwx7@%ky z#jv*e9d~GX%x+`8wZA*|`cKA%5T-)BsUThHvC+O9UT`gs5YXStUfm*3jA1}%0#?Tv zQAD8Cz}_KTJ)A;EDQ9q#(k$}Rus1|jw@o|1b|;P9pD$7EX08=+#jo+wWlFkRE^XrU ztDy|igwgmnvjBF;&1XjBRqw`kVyi1FK(^~(%r_t}_ZX^{I`#}ZuIV%CAF0p^9FIIZ zqfdSH=jA7zk?;*BNRkYa{5rv|?g8jlaqB^zf7LB$7~z-eLB^^6-Tcf|N}lZ5GcG!6 zrmsru8{bvXd-dj|+2pxdx}t&?DvkSep3}^jhpK6g7O3Z1vOYlKVXhS=bvEEjcGpGH ziYQ03^L%9RTZCz9aXbLp{52}_7&DD0nRHwo)<)_`w`==0|0%^I1gA6J(A&O4k*(Nu-(xP zR*Lo_MGR_QCLPuJ0Lyrh;kseV^6dNV@oa(OJuqqM35OCn-8}rcGm7nJHG13 z=ha>nZ(+oz>ft*)k3=iaTi!GsGxKJj@ret_YkKXrSO(l2S%bb-@Y8sPrzmw9Gu^_X zRtZ90omR_ts9zk?>3l1lFM;Imr>FYyq2yk=c4~8X#vkNpM>;!rWN3C$mIC7Lfr?1J z#F`C`7lHC{T2KF(D<;gbj3PH41Pi+iaHxyiBXfJi2uq&mvWZzwwz7x3)kfq1Y!((3WTfciH7bQ5;|?28Gs z-X*pQ1E>U6U-SFvs?KZoVyUAZ%0>i=ZVG3qdACji*?vITdM(d;^A3Fq8?ugQgME@7 zUK|_V`_Z3s)mfQ}Kuj;+$o5_{tdEV{)?@mZWBH4fy8`Y}-W(F;q#n7l;#$f1rsccf2!er|uznHjx#e?4D28miTW znn#pRJ8*K{Y3l~zLl;Ib*)l|%0-dLCulE;`&nei}28rDtaz2Fny@hLfWCb~=9DQ!Z z_qEXr51j0+bCwTXyb5MUsTnW}e6BCoObR35J-0@$CoBf^#EKRs4Ox1jKuVdB0*@zN zU+#lgs7N0M7s0GE172Z9?>ge;XEbZNt6uZ-ISOkXOmLPwIDJcM%?fp&uZPNckY(AB0@k1!i3O~JL*^!w5a`yLFB~xSm&IW8W7{}>R z#lnqKTCfmu^qVR;@`8pIi z6z+|unM;I{pd~;y{kFuU2che+82>Z})-gn$9GP=EoMQ(!RxMu#slb5*RBJ1`76rSE z@3e_?+c#`41tMWxP;VBJrZEB?0akWh-JVp}kH-j>n)EIw$M_e*`JYoAt1ln}jkmf! z`id`fXb^#OndMVR{6RC2L)^BBvi$807Dkvb<8AcE(Gj)*b#yt_Tw76!Z%xEA>mj_c*ph290>}K1%{jgu3&P%}^NSxLy>befKp#Yh9VJ1HpW;!ytp|vWl99@sF41 zTtOj^a7+CElT0MT!9h|JCksM$;2sk(^F0l^I`pLY33+iDcz7vQHSB_gu4ygaMgVI6 zi=8oau|y@u3;GXz9=^P>AeqNj$cr)SH0b6%YqdwBoslct@cc%rzoPTPq>W%eo1X;q z%HCY(XYA?_DqgRZVKB+MB zeUQoSS5znn$7R1sJ)F?Z_196g0x7}spZDP^fR;#x<^$#qH=O^G8hCD%_otv^!3r~%C-J?CC_zDfBD3>LT7K$%D?%8ih6=N$d*+7w~9hZ}yzFuv%4 zm@RfErLyv+N*8x{UwYph&uJjtpV*R7oevzQQlBpqTjn!^=G}Xu zPxXy0*>^j6W_K!dDQM;qn6W3brJiW<%;0EH@{rxK$cuUs)8xERyfZiqEKew6?y@JE z8Hk~WQmkVVFKM;N9(fECO{XwGgJ5QMXnfVYg*rVNc`s?Ye78@yhQfkX-Fa#g!5R+v z)9NE(a=wAy;O@l3vI@W=Fs$^`YTH7okT-oQvJ6^6*9Bq%b;Dw@`2s33Vb%qfvKALl zDwmDRXZolq6=@!&DU5yIcC)L6&G=FF+N7k``2~${K~m*fY6Ph*I^mm-v=^xCh#T*0 zbASN`+kly(HJs(FWCUL=dapdRDX`J~s3l_xOZa7Rz?d8MX`ql2v&w$y+cW|W2{Lzz zA;qhT$=#jH64tntRE(+edzAiKsJ&r($lOx4$IYqv1)TM-s`_Ndv)Ugiv@l#~9GWYk zMIA2WP0C{I$&x3yHgAg;OWQR(CnOGbBK^Oslr7hV;y?4AFq<1Y<17IwD+CC%tXXiV z6_{iqFlR)k7GNUZ$`9Q386DM1#;HX%up*mUi>L(>j-`wfX@`|=(XW_>N$$#8(l9c+ z0d__#+rXxq4u$?#7^bjqFTEUG1owdcOy};RU3^G^2m43S9oHQWu=fuEX7Vh@;m0M| z`I}hl`}g>ZV6rV-pqW%_`^&1#kG<<^H{y`b)Q3JI*ZgCNXz~~-n?vg+jbXHjy#E5w zK|~jdT!{P5W<$=yWdNJRGSL>vwz$FqPa|$hyqqh{z`qyEVPSoe}8kF*hj!&?x zNp7Ba@HALFC`Nvl?tE&|3Gyde(M-JOC4F`Gaz{W8u)<#2R^%v9h%|zhxYt;-^R=8| zlVVW*`@rjoO3+!Rk78;l`zE@<3x6A`v{S0`tl_x_yF}fA(Cm`hh ziNMWIsW)~(N`Y^9^XVLMv#^O#%>X>5YR?;f2bOSwA;tBm3h8x&dL$5?`Ts>7F_|V*#ywxwI5l)s|r>sITc2MJK%G}~h z(IVEzpm~=!=G14cU-No~4Pcd-^_JE~5&p&;s%I&4SQLTo8{&(1zgNaf6_D}IlWqD- zS2!*&!u{UCAyS3`d0|)hkpWmuY{M(9bR5+%xbNFs{v4S%=Xmq2dHUA~-+G|_(H6!} zY+|ATrVUchpVE=H{G~}GzGDxeC_x~$_wyr_;B>VAw$?k5rm)Puml%%)sN5FER02}9 zLkMhq*3EX0JA1bmA8OVY1Zge?S30xUdzQ2P9%ZUTW$*HaYt?*>M`SC;C15N-ideOy zw(Fc*vl$4_dPj2!u#(KigCcReqa9d_x?H5{y1yOiVfHueHV#{=SC{Ijenl&44Gspk{0056w zj=QdO$xhc>TAl?yw?hoNMxt_fV^jv}LK^pbpR%V7Ed^deW0m=bj1ZtSL@ohj>7%-2 z(wbMA=pCIo!NsyMdi6lr^c0#CyRm2xCDVYKm+!)gy-L)G!CU^gh*fHw`q>#SB6a3*|d`dIWX=Zkfbbmym9V+>FDtnbcXu z2F3@7$HOq52|zjn$f1oixXtrqPo+BtOIP{4{u{VYSIRukI`yX-6k!F$?v5$I$|-i6 zxtL=acZ7z-nZ+>WKAqckM1a}B4fhD%+Y*#5yAtT!3xKOq0BnQH4+B$;xXUaqP=WOP z^vYZl?8(fnm9DI8yHEJ*;8^S7qNv2E+-es|Ml_u%ZLetlbT<^)F03Mmc|-@y1Yc4y zEF&Z#gS)5q-YU|&T?|&hYlbEUSl934vnSZ9eP{^zrk^{8uTQ9+C6Y^Zi!yL9Nd7l; zkTmxGc5<<`N*>a*ekev5m~`yZrUVRtEi!5q?J`CV-tv3Cherg$J`+DX$$F_eBbq(k z->nTzj&Na`vq|t1F4LAWvt5Cf2*wBJrpNY>KFC?W>_K=gj5JLst)Bq~UYN%+L;u8I z1`4+qsW#!`R+}JninRW9T&UM&_+j1r(tsw9BzU*$3rx(os6oeYmuBtstZ{G5e|ZoLCv@+TJ3=J|*kkp?Qo;1%+!YvB%)caZ4eT_$;D%JUnUWIFIHDA=vgjcG6p z4QffpvP3AUtuwm8)8ST`A%9o^Apr{N zQ1!6Qg;ok>88QV+T(EH4%CG*0&Lg@&{E-g}fAS+d#X4}BMOl9H;}^vf=1Mb&(A3?lecXa02%=aABInxi?Qz^`YZ!A& zE+Cz8F|O@BUhgLb7^O=*Dk`Vr0BA zLDO*R1j9Idqonl0_Xz*3+xY8DwME)U55!#4m&+02QedpVU&q8&y3Ft2GHY@B1LP`M z1oD7T(GzaS%lKimvJ~YjoEv?n;;D2(UArQLo7)9RS_;Zf8+eZ0e7yY}X}ASs7XkRC z7LaX`xLiDVD+-q$A^~L7CyNZqtg?yb!Pn?Pbj0acC}X|gS2fajiaIo!pn9D00AEq9 z#X$3saYdkT$st$~nZ3LA0vsg2cNR08f~h3`OE|XI4-17-zEfCNFEkf4_9^AXCF3XIr$?J! zbqypy_;_%>cKd%s#V;2AzIQ|KzuT(l;GFV$+4_X5F0p!^T@80ipc7BR26(#0ahKL6 zm8x^KZ3jlbWt&M9(rHvv{egp$NkatUm92ErBWf2Hrbv&n9f>~|>f=JEM=h-!TA#^L zZ-DPmabWMD=Z>!w82>6t1DPUE!t4)CPrAz2t7%TN>(PWa3QZF69;D%k!BeN6;&RbA zIWiohu&zM9YscRBttU0&uGOR^B6Am?`a<0ciQ~%)*E`&$?eEjnfs_i*Df$75CbQ2F zuq=)cxFUTsCr6jV!NAyFHV@-Qa@eLZu>9#!n2?E&HlEVtgQYbiMm}w>M(mr(<9rDt zGw%w`SR&oZ#>;b>@g&akPtL5HX^iabo=2Hln#UI@4VL0R0vKNk)T{LF;vFFw$0^8a&#?B(R?yQZS(_bYHw8b+|u9I!swrk>q$+qn#+pfvBZA_Z#G`S}8 zWNYfq@9jR^hr9oYwf6q(wZ1izW1^ayrYX>(`pAAO*b3bnry-v+)RP-O5>q|Wa~-eQ z6p!?%5&gWKv~mC837fCZW^q~+_O<@3fJQq?Kh`K?s*W>NS_9mAels^UcT>|u3#@S4 zEDxtX!#W&Ie~!vKAsR&n`gaZ3S&lQ9W1TUjLG&oWDM8~!x>+ug6;O`8-WoOdLIqe6 zUiJzMsELnH+>NA!a4QF31mVdS`>A8)`*wCQa$87}gWqPGfc(TJ;Dcr%eO_n4%7v>V z10>SQYvp3nZB5713YIu3i;eC`V|jAzyK&sNJI#}` z!9X?CW6 z-WL1lBxQ$d;qJ^S|4yft+{tEoSRqZf`tzv@72Y^);za_Azuz0j{3q$!y7}uRzkJ!@ zFP9H2O2<)eYkwRsX#I;HI2EvXwqdu;2)_F4nd})ggG(g; zD|D@XIf@q7;+ZRi83dMr0`0#wxXpDEIo&xj?k)!#wjdwoM|qwh}+rV~gP&RWmAQv(Gfs*n3Xz3pwdeZh*Nkj+3L%`c!Z(r8|i% zve0hvWrzThN5gnUiaAWMjTzuchcXI4?G@l2N&0027244)jR&FK@kol5%V- z*~vOk|12DpdD_BbZ<=5)MiZiSY-e+A38MmeZ@k#eeUtTn_mgk2zN18jPoh}47?c}m zAZz%j9)_|-#Er9CftMZs#PVh}=}6{1uT8QebkLAfb^Rb=e0~DQMk)&k&_z3>x*u|% zrp_*d-+z-;*@pk<*L`oO;B^=FX#dJE26kH%Tj$v4g);b8@35yA$Xw3AjNpEkjJt1g z##t@>>=P*%(bq^ZMNtkiW7eIbz>4*br*d0Vk*Vj>DC$6f7Biz(phb{xGb(ufl}9-u z)zCSYd6Y7v-ue9`77|`5rM4-b{dUN%flL-q%^GLRe>-0`Gxe-Lrxq=c1GiPsv$M%N zoMcXyF+~;_&#vP!)Wi+0Imxq7Kz*Z=W(|6+ZTu`&P{fG3a6k&}|8-&}{mtEC@H}1& z*%N`vD>6!l7PQCM)Ipe&N9;^%y7o*uE?v8SY7|zs^RTPG7FEB*aNS8&u||V0IrRyC`{qWyiL1AqyVTEWFWnmeM%5B5Zi;L0;6F{tu;oJ_J)D)#o(H`(Kb&Y;0_PrIxD z$#=~sbPHO_Gtojdh-^~k)6FWy|7?!Y*Rn{*H|(7MA(66JCmalsmXWYj14UeI#g?MJ zLrvG2VjI`j&_q3QD$vk-amMTOeMVG)n>A;THSuRqJ-R%rW#=W@M72=Eajq0r(xISB z`16YKDY;@NBCt+yh3zo)s9+w7Tg9Y?PiY!~Kvb+!`i|IeclFlNSP?q0SNT{InnJ}k zhr-?WgE8wX1Idkx&Gn5He2HdrYF1r_nNA&Eih>5Nm!Uli3516TjyzBl#odvI4Mn}` zQ3FNFYe1}LpvijtvjSORPU`Dg7i z#^41J3e{W7Tjjbilb=nTt^1*Zk#`58@OF;q89c?Ukc-+-x=T39AF z|3}P|Dy{;lu+?8m5iq#RF6(j2$#xJrd zbzDB$=G0rz%7=;ZcKf74lB4FFeOPSajXqg6x(sCf0cRlpJPnd3rR4?JEcQl@? z#=ba78__$sdw3(5l9vjba+5qzskZlAF6}SxsrLDZm!UKC2*v{MtYuPJ?P4mc@WzzC zSTo;;?ZJuw!=m$7D2HH-J@i_|>g^@?GUGp-qMs644rhgwI9`)qwlCNoT__XH8L*3k z>_LbJecLL}jZ~89h1=7?NZvS&Hm92N7^>T^-c`O+DmN4!*c}`CzxPgA5$>#Np3|Z{@md=02z}rJRjU){!UY) zThpWbjvOdA7Fn$y^2@u<-Cr!IVg6ijysma}_~DukttJLT+<}%-Rp~gXmFdvfdVoJZ z5-lN2M!#0lNK)8xrmma1~~aLO`hwS(E;gt7J#cI&eBJc#O=LPt%Zgx@aZ zjlK~XhtSoEHP_WgBB*mhp@OXQJI2T@=ZL2*)nh$~!hO4;GkttRxQnq0{oHq{qP|Ec zbU=$c3-QcTu#zBl3BJLk9a!C=qdOG|%E2(R|D1>V=C#s2cV*)daV>F%o=w1JQEi2G z$ZuI2_(WNL*n7uhkJ?BL_scKs;&f}c0)qbf39jBNLElUiB^x znu^?wlV`&o9Iyrk#<@9Bi(!DSn zxW#&#Nj?#3F;Um&LDifLpI9?+bPg5}A4XrA(PmuDW)Uk*^O5TtYix}eqhV1XAz7{2 zQD0^M>L_LMmr#3`@e$h%eJoW2$>e$h$b_-6EPELa5fF37=kHw6_+0`t34bl+{g2^>-}nM&P0aC674D`Ik`sr&tW$f#j2LUVH-wzF8)l~#$Ud{ z_H(tk=55qvIzgiVCSl`HkO81Ddwr}ue>?W->yh*LZVpFJhgd85z2otBuW;`l!OmFC zQeQ^6DWPrU*n%F-A8m=Vv7&wl>K=kYr_!mom`7gSKKg>nm>e)0D1U}yilB2eu0JuiiR2nL;a$RGi~} z1Dv1Zi5q&SSUw9*vq_@o`! z3_Lp{gpR4tzfw4fiwObN2!jkG0#OsX1ZWo%5&WoH&gPB#1B^h6M@Tyo*RaiCbGNGs zfQ(RQW(Vf8#UO-g=a20>5<7h~$}Mvq^tQ$2!~Jx<$;h+!=sT(LiB6}x-`e^3(t^Em z#}!2a);rYJKlgDhLz%xJ$v;FBMN{?ADD^<$R_gRd%1`tI#zPQ8dp7S6uh-WpPck7`V77kWp;`w^E1X=?P zsoJo{s#D>o#2Or9olNZvRH`^7vvge_;NIF*!mq0P68W3=7;$EZk9&uh_&R~wRF@yxl3@;y09ait~s=-dW|Zj8bR{O>6mBcO(LNQVEwU;Oo6Qq&_*kV8`i>K!ycrb&TbOLlmaAeL<>>SKxdI> z!7HRRSeVUy$_-2}4)YvWGVxiG9j~Dl&F$my*L~faPTMZ-m;(zMxw2$~obsm|N2tm7 zO9lqVFv5d~*7kYv(Qbzqo4RG{QejD^kltN`l+*I302duLfMW_(6+9B$i_vJ6#>pZL z^7-HQ5Gw>oLz+xeXXHRa`bT7?SomLPwav`ra>veRCOgK@Wm*cxWP)$&?s=(gBWW;y zSU{-3>|s&$Ye$dEDPPMyA=YSK@8Hi>MckAkIHvC*Yne?MKuMg4N)y~$k7AKM{6C?{ z4FuR%CMDGDGAsm*Z{H`>?H6BY1o`xih>9H!4X_UyTp@i#7l!q!C|c&8+)f_bvU6PW zT5_3!OFU(^`_zG->^{&_OPTBZJ;p)5GbIgzPruM8+hzCsOnjdc?N_0QVCW=m;aIA% z@tusLt5!fftWTlINK`TTl#&6JnL}7wtm#Puw=3&kZ_ckl=zCK=B6(tY+mt>hsL?`h z0m}T|3kI*Qdm~v?$h8)Q9GNYLG%JB?aP^ zIL({E%r(gcr9eXAjgV2yqj6d|Lfo)EZy%T2d3%flpTn_q;6p6OsV!P7(GCp zSsKNUe#co8U~a|vn54=0Pgl8t(H1K%E74F_J0O1f9qU6tz6xmr6nHZhl=mlaWhW1w zp`Q1ywYJ%k`2(cU=SU?e8(6MalvEP1O&tb}G2iQ`6~I>ZZ9y*?^dlS4P+LUmdQ&ua zU9cJE0aYH0FHkxK0Tv=}J^`C&DLO_b?i}+c;Ho+cOUz??)?_dD@~Esjqj*?UIPSdJQDGX5=?Eb+pxYY2^Gp;vAKi&VVO+^}6BE(!xi zYIh7yN3-LGtM?58V+K|x9M%#lLh$rHdqEgm6?)_t8UmZf46%@7-Mrh4B(Jc5Ykp0i zFP+m}Oz8nq97MVM zFFm2PhOThIb1(?I)M-^KLT~+cs+eA0&5?Na?VZkqp~(G`(p4jY(9faGCgf)0o2OJi zQp}uJir_x}aT1N(pHq>`q=Db9sB+R8;z#(pUu5lrMnuXH0iL##FzQV%rm{^Q8UCwB z7ARYhF;*O2Ie?_Q84!HdYoPj19Y!Q-dAZJxHAXEQ2p-|4m{fyB3mV>GtyqIv{LtB-n%$m>`U;%H zA#;V0!Z&9=JnSn4dMIHsnx&7l+Uy(-cro3Dj`&iPsH=kz zXb1nmi2ikf0H2El;XIG<;6!2rmj%i~uRue(4o~ux1*-}pbhgsN`HNS+L?oEoUqt(> zDxY7rk{Elo$}V4G^G-{T<<8HP!hiYMgkl$in{O|@2f2eaw|sJF_%{O#Vl_I@dPkri zb61p=TMTWIt1i#Rl+SbgI@*m|aj1eZlmF&KWz0xabWz|Lb3qKL-Dyp1%FXvk-W-h2 zqKn(+nU>y3bS7>$8Q(=IF=E+lI+o4nyB3jJLL_Z6{g@5r$v4(v6^ai}P(8i} zBo=m(soRK&yA!rx3Ka2{zxy#O(QDu-*@?*{+V)fzJVS`wtl3;X+@9}IoyMVuvG>=r?hv?AjQZ*wJOS1yw zUl*-~oIY4lvnA>JRC4~R+nP2 z|4ulGM!%M5%A$v#vF<#xiK#dP(#P!9NQ<6$fxi2pxp{K~QejHU|*=s8tBhA{3 z%FvQI(bIvbJpwna*d~_?olERM)9Gh13SF6g$JWDY5`2pt3K0%dl*h#Cca&*jLJf&7 zwE^z0jdHQ%HOwY2;nr(=!g2Cny$kYAGZ z#97>~I}w}O>{a3JTSsOLodW_Emkvf`z#q$p&M;j!e|nq^b#4U~tL9AVq9i0BFqv}9+_8Jh zbnla27BLqU%I8Zv#tw{s-YkopaR+-?=Ws>$2jQ0Xgua>@#Ue=gAd#e>$%UTe4`9+= zs2DvjfRmA;%AZL=>$Zz~M%YP!=rz}>jltHM7@vxG=3)0c&EZQgV%v90_SD6rf?6$X zhvTx4$%7DdT%T^dLrawT@9*V$j0~|0tT$|q)mY{RSb0I{9x^;%GyIydkoCwL)^L>< z;g^QNNmkXH18?>h^?`1W2WoV6byy|{WTugFWUiMGhZCx^eT-Ez!aj?MY16f@VOhth zQuj+j*hx-&WqE4w{bBx`vpJL;VKfH$xsph@88IOym$r&jhxl<$(D-+l)%itNy!L>6 zljQX%@V6rym|lplg=0{a*uKxIhdnGTlrQ>^%rwFu4U&hCceAi}RdMk02h6liWBzzW zN1jinw*8rcYN*V<$Xv^4x>}}s_tt8cCO)UMad3<(wfGGUiiU{+)W0DOfV4&VEGqN4 zzNqEsI%z0SZ)LosIda&7HA!$bq;rX)dkHo(q*PjM$DXgwlv+BF+(+hE3Fts&obg=# zuHc{)c-&!&%!;d|PCtML{`BN#lPo{ACcf^!Br`%a3A9+2y#>up1vAk>Dhw=QO^22U zTljk&e9R!;pp}V)9zL-V*o9uX5@a^DySf^Nv`WBPWxDS_y<=;~AYoNhV#vLEj+&z5 z8i3@!Cv~qU;93-?iD9MlnLi9Vr|PS%a&%q!HL}NKp{?+hqbmo8PRh%yZ}s>$sYhH{ znR7d_r?=^AaA`=skKbrG`on}r15t$oI`J3#4Zt(2bH0cZB%+_6|6br)$Xif)p*oxVs%j~9a%Eg;V9---QrV(F!cUiW&BO*#$O1NGIQo=8^|AX`d(^u_U7&iauNg5 zb}zZkb*fv`RXB7Cl-(CC$Nu?gy#4+!+q%Qo9gS2AVv5^(J3hYNaj_hE)k#}_QO^+_ zXw!cUQY1jM+pPKAD3A^h!Ao#~%bU%tCr(VBZJ<3Mn8PfIEHEH5ys2ty1y`b+MjKJb zg-Ep{IPODz@DviFj~-QuEwyrHdxgNlp{-7<$^*`zQud6I0jQKOHO2$opO-#U&#kzP zrD69g6D)aaO|O}ZAP5<+4Y656NuWuO`=aD`PLj=Mej{UNG@SodF3w$%5UJQcUz23jp?DHts=TuXaI^*jer(e%A6`4Q)$-aWc|K#ca GIsXGY!AunZ literal 0 HcmV?d00001 diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md new file mode 100644 index 000000000..9d4e64508 --- /dev/null +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -0,0 +1,116 @@ +--- +title: "ImagePullBackOff - Public Image" +sidebar_position: 41 +--- + +In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR public image. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/image +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Create a new deployment named ui-new in default namespace +- Introduce an issue to the deployment spec, so we can learn how to troubleshoot these types of issues + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/image/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deployment ui-new -n default +NAME READY UP-TO-DATE AVAILABLE AGE +ui-new 0/1 1 0 75s +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment ui-new to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. To do so, we will use `kubectl` tool. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-new-5654dd8969-7w98k 0/1 ImagePullBackOff 0 13s +``` + +### Step 2 + +You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 48s default-scheduler Successfully assigned default/ui-new-5654dd8969-7w98k to ip-10-42-33-232.us-west-2.compute.internal + Normal BackOff 23s (x2 over 47s) kubelet Back-off pulling image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + Warning Failed 23s (x2 over 47s) kubelet Error: ImagePullBackOff + Normal Pulling 12s (x3 over 47s) kubelet Pulling image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0" + Warning Failed 12s (x3 over 47s) kubelet Failed to pull image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": rpc error: code = NotFound desc = failed to pull and unpack image "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": failed to resolve reference "public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0": public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0: not found + Warning Failed 12s (x3 over 47s) kubelet Error: ErrImagePull +``` + +### Step 3 + +From the events of the pod, we can see the Failed to pull image warning with error code NotFound. This gives us an idea that the referenced image in the pod/deployment spec was not able to be found at the path. Lets check the image used by the pod. + +```bash +$ kubectl get pod $POD -o jsonpath='{.spec.containers[*].image}' +public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0 +``` + +### Step 4 + +From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at https://gallery.ecr.aws/aws-containers . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui and since the image does not exist we will see Repository not found message as shown below. + +![RepoDoesNotExist](./assets/rep-not-found.webp) + +### Step 5 + +To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the URL https://gallery.ecr.aws/aws-containers/retail-store-sample-ui. You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. + +![RepoExist](./assets/repo-found.webp) + +Update the image in the deployment with correct reference + +```bash +$ kubectl patch deployment ui-new --patch '{"spec": {"template": {"spec": {"containers": [{"name": "ui", "image": "public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0"}]}}}}' +deployment.apps/ui-new patched +``` + +### Step 6 + +Check if the new pod is created and running successfully. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-new-77856467b-2z2s6 1/1 Running 0 13s +``` + +That concludes the public ECR ImagePullBackOff troubleshooting section. + +## Wrapping it up + +General troubleshooting workflow of the pod with ImagePullBackOff on public image includes: + +- Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. +- If not found, ensure that the image exists in the path referenced. +- For access denied, check the permissions on worker node role. +- For timeout on public images on ECR, ensure that the worker node is configured to reach the internet via IGW/TGW/NAT. + +References: +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md new file mode 100644 index 000000000..b9b1f8aee --- /dev/null +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -0,0 +1,193 @@ +--- +title: "ImagePullBackOff - ECR Private Image" +sidebar_position: 42 +--- + +In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR private image. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/permissions +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Create a ECR repo named retail-sample-app-ui. +- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 +- Create a new deployment named ui-private in default namespace +- Introduce an issue to the deployment spec, so we can learn how to troubleshoot this type of issues + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deploy ui-private -n default +NAME READY UP-TO-DATE AVAILABLE AGE +ui-private 0/1 1 0 4m25s +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment ui-private to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-private-7655bf59b9-jprrj 0/1 ImagePullBackOff 0 4m42s +``` + +### Step 2 + +You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 5m15s default-scheduler Successfully assigned default/ui-private-7655bf59b9-jprrj to ip-10-42-33-232.us-west-2.compute.internal + Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https://682844965773.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden + Warning Failed 3m53s (x4 over 5m14s) kubelet Error: ErrImagePull + Warning Failed 3m27s (x6 over 5m14s) kubelet Error: ImagePullBackOff + Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" +``` + +### Step 3 + +From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. + +```bash +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' +682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +``` + +### Step 4 + +From the image URI, we can see that the image is referenced from the account where our EKS cluster is in. Lets check the ECR repository to see if any such image exists. + +```bash +$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 +{ + "imageDetails": [ + { + "registryId": "682844965773", + "repositoryName": "retail-sample-app-ui", + "imageDigest": "sha256:b338785abbf5a5d7e0f6ebeb8b8fc66e2ef08c05b2b48e5dfe89d03710eec2c1", + "imageTags": [ + "0.4.0" + ], + "imageSizeInBytes": 268443135, + "imagePushedAt": "2024-10-11T14:03:01.207000+00:00", + "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json", + "artifactMediaType": "application/vnd.docker.container.image.v1+json" + } + ] +} +``` + +You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. + +:::info +Alternatively, you can also check the console for the same. Click the button below to open the ECR Console. Then click on retail-sample-app-ui repository and the image tag 0.4.0, you should then see the complete URI of the image which should match with the URI in deployment spec i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 + +::: + +### Step 5 + +As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. + +Get the IAM role attached to worker nodes in the managed node group of the cluster and list the IAM policies attached to it. + +```bash +$ ROLE_NAME=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole' --output text | cut -d'/' -f2` +$ aws iam list-attached-role-policies --role-name $ROLE_NAME +{ + "AttachedPolicies": [ + { + "PolicyName": "AmazonSSMManagedInstanceCore", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" + }, + { + "PolicyName": "AmazonEC2ContainerRegistryReadOnly", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + }, + { + "PolicyName": "AmazonEKSWorkerNodePolicy", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" + }, + { + "PolicyName": "AmazonSSMPatchAssociation", + "PolicyArn": "arn:aws:iam::aws:policy/AmazonSSMPatchAssociation" + } + ] +} +``` + +You should see that the AWS managed policy "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" is attached to the worker node role and this policy should provide enough permissions to pull a Image from ECR preivate repository. What else could we check now? + +### Step 6 + +The perimissions to the ECR repository can be managed at both Identity and Resource level. The Identity level permissions are provided at IAM and the resource level permissions are provided at the repository level. As we confirmed that identity based permissions are good, the issue could be with resource level permissions. Lets the check the policy for ECR repo. + +```bash +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui +{ + "registryId": "682844965773", + "repositoryName": "retail-sample-app-ui", + "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam::682844965773:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" +} +``` + +You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. + +```bash +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query 'policyText' --output text > ecr-policy.json +$ jq '(.Statement[] | select(.Effect == "Deny")).Effect = "Allow"' ecr-policy.json > updated-ecr-policy.json +$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://updated-ecr-policy.json +$ rm ecr-policy.json updated-ecr-policy.json +``` + +You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. + +### Step 7 + +Now, check if the pods are running. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m +``` + +That concludes the private ECR ImagePullBackOff troubleshooting section. + +## Wrapping it up + +General troubleshooting workflow of the pod with ImagePullBackOff on private image includes: + +- Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. +- If not found, ensure that the image exists in the path referenced in the private ECR repositories. +- For access denied, check the permissions on worker node role and the ECR repository policy. +- For timeout on ECR, ensure that the worker node is configured to reach the ECR endpoint. + +References: +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html +- https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html +- https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html diff --git a/website/docs/troubleshooting/pod/index.md b/website/docs/troubleshooting/pod/index.md new file mode 100644 index 000000000..1cdc069ac --- /dev/null +++ b/website/docs/troubleshooting/pod/index.md @@ -0,0 +1,14 @@ +--- +title: "Pod Issue Scenarios" +sidebar_position: 40 +chapter: true +sidebar_custom_props: { "module": true } +description: "Run deployments with diferent image paths/sources and persistent volume configurations, introduce the issues related to running those deployments" +--- + +::required-time + +In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. + +- Pod Issues such as readiness/liveness probe failures and scheduling issues will be coming soon under this section of troubleshooting module. + diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md new file mode 100644 index 000000000..b40d9389a --- /dev/null +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -0,0 +1,186 @@ +--- +title: "PodStuck - ContainerCreating" +sidebar_position: 43 +--- + +In this section we will learn how to troubleshoot the pod for one of the scenarios where it is stuck in ContainerCreating state. + +:::tip Before you start +Prepare your environment for this section: + +```bash timeout=600 wait=300 +$ prepare-environment troubleshooting/pod/crash +``` + +The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: + +- Install aws-efs-csi-driver addon in the EKS cluster. +- Create a EFS filesystem and mount targets. +- Create a deployment named efs-app backed by a persistent volume claim named efs-claim to leverage EFS as persistent volume, in the default namespace. + + +::: + +You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/crash/.workshop/terraform). + +Now let's verify if the deployment is created, so we can start troubleshooting the scenario. + +```bash +$ kubectl get deploy efs-app -n default +NAME READY UP-TO-DATE AVAILABLE AGE +efs-app 0/1 1 0 18m +``` + +If you get the same output, it means you are ready to start the troubleshooting. + +The task for you in this troubleshooting section is to find the cause for the deployment efs-app to be in 0/1 ready state and to fix it, so that the deployment will have one pod ready and running. + +## Let's start the troubleshooting + +### Step 1 + +First, we need to verify the status of our pods. + +```bash +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +efs-app-5c4df89785-m4qz4 0/1 ContainerCreating 0 19m +``` + +### Step 2 + +You can see that the pod status is showing as ContainerCreating. Lets describe the pod to see the events. + +```bash +$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +$ kubectl describe pod $POD | awk '/Events:/,/^$/' +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. +No mount target created for the file system fs-00a4069aec7924c8c is in available state yet, please retry in 5 minutes. +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. + Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. +Connection to the mount target IP address 10.42.41.35 timeout. Please retry in 5 minutes if the mount target is newly created. Otherwise check your VPC and security group configuration to ensure your file system is reachable via TCP port 2049 from your instance. +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. + Warning FailedMount 19m kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 32 +Mounting command: mount +Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount +Output: Could not start amazon-efs-mount-watchdog, unrecognized init system "aws-efs-csi-dri" +Mount attempt 1/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. +Mount attempt 2/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. +b'mount.nfs4: mount point /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount does not exist' +Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have retry_nfs_mount_command item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [retry_nfs_mount_command = True]. + Warning FailedMount 3m33s (x6 over 23m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = DeadlineExceeded desc = context deadline exceeded +``` + +### Step 3 + +From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. +Connection to the mount target IP address x.x.x.x timeout.'. This gives us an idea that the EFS file system is failed to mount for the pods to use as persistent volume. With out which the pod cannot move to running state. Lets check the networking configuration of the node on which the pod is scheduled to run. + +In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. + +```bash +$ INSTANCE=`kubectl get node ($ kubectl get pod $POD -o jsonpath='{.spec.nodeName}') -o yaml` +$ SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` +$ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" +``` +You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. + +:::info +Alternatively, click the button below to open the EKS Console. Then navigate to eks-workshop cluster, Resources and select pods workloads. Select default instead of All namespaces in namespace drop down. Then click on efs-app pod and from their click on Node and then on Instance, which should take you to EC2 console. Click on Security and you should see the security groups attached to the worker node and the Outbound rules of it. + +::: + +### Step 4 + +Now, lets check the EFS file system networking configuration. + +In the below commands, we are +- Retrieving the Availability zone of the worker node using instance id. +- Retrieving the EFS id from the persistent volume claim. +- Retrieving the mount target ENI for the availability zone corresponding to the instance Id. +- Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group + +```bash +$ AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` +$ EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` +$ MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` +$ MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` +$ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[].IpPermissions[]" +[ + { + "IpProtocol": "tcp", + "FromPort": 80, + "ToPort": 80, + "UserIdGroupPairs": [], + "IpRanges": [ + { + "CidrIp": "10.42.0.0/16" + } + ], + "Ipv6Ranges": [], + "PrefixListIds": [] + } +] +``` + +You should see that the security group attached to the mount target of EFS have inbound rules only on port 80 from the VPC CIDR. However, for the mount to be successful the security group of mount target should allow traffic on port 2049. Which is why the mount request is timing out from the EKS worker node. + + +:::info +Alternatively, you can also check the console for the same. Click the button below to open the EFS Console. Then click on EFS file system Id which has name as eks-workshop-efs. Then click on Network to view mount targets for all availability zones and the security groups attached to the each mount target. + + +::: + +### Step 5 + +Lets add the inboud rule to EFS mount target security group to allow NFS traffic on port 2049 from VPC CIDR of the EKS cluster. + +In the below commands, we are + +- Retrieving the VPC of the EKS cluster and the CIDR of the VPC. +- Adding inbound rule to mount target security group allowing traffic on port 2049 from VPC CIDR. + +```bash +$ VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` +$ CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR +``` +After 3-4 minutes, you should notice that the pod in default namespace is in running state + +```bash +$ kubectl get pods $POD +NAME READY STATUS RESTARTS AGE +efs-app-5c4df89785-m4qz4 1/1 Running 0 102m +``` + +Since the EFS mount target security group allow traffic on port 2049 the worker nodes where able to successfully communicate with the mount targets and complete the mount of EFS to the pods. + +This concludes the pod stuck in ContainerCreating troubleshooting section. + +## Wrapping it up + +General, troubleshooting workflow of pods stuck in ContainerCreating state is to check pod events and for volume mount issues: + +- Check the volume claim used by the pod and identify the type of volume used. +- Then check the csi driver used for that volume and check the requiements to use that volume in EKS pods at https://docs.aws.amazon.com/eks/latest/userguide/storage.html +- Confirm that all the requiements mentioned in the corresponding storage type document are met. +- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues + From 79db7d973f76c62aa3c957e4346de89053528616 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Tue, 5 Nov 2024 19:23:33 +0000 Subject: [PATCH 08/12] added hook scripts --- .../docs/troubleshooting/pod/image_pull_1.md | 6 +++-- .../docs/troubleshooting/pod/image_pull_2.md | 13 +++++----- website/docs/troubleshooting/pod/pod_stuck.md | 25 +++++++++++-------- .../troubleshooting/pod/tests/hook-fix-1.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-fix-2.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-fix-3.sh | 21 ++++++++++++++++ .../troubleshooting/pod/tests/hook-suite.sh | 11 ++++++++ website/test-durations.json | 5 +++- 8 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-1.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-2.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-fix-3.sh create mode 100644 website/docs/troubleshooting/pod/tests/hook-suite.sh diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md index 9d4e64508..317c6115e 100644 --- a/website/docs/troubleshooting/pod/image_pull_1.md +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -1,6 +1,8 @@ --- title: "ImagePullBackOff - Public Image" sidebar_position: 41 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR public image. @@ -49,7 +51,7 @@ ui-new-5654dd8969-7w98k 0/1 ImagePullBackOff 0 13s You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. -```bash +```bash expectError=true timeout=20 $ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: @@ -95,7 +97,7 @@ deployment.apps/ui-new patched Check if the new pod is created and running successfully. -```bash +```bash timeout=180 hook=fix-1 hookTimeout=600 $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-new-77856467b-2z2s6 1/1 Running 0 13s diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index b9b1f8aee..47886b879 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -1,6 +1,8 @@ --- title: "ImagePullBackOff - ECR Private Image" sidebar_position: 42 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod ImagePullBackOff error for a ECR private image. @@ -51,7 +53,7 @@ ui-private-7655bf59b9-jprrj 0/1 ImagePullBackOff 0 4m42s You can see that the pod status is showing as ImagePullBackOff. Lets describe the pod to see the events. -```bash +```bash expectError=true $ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: @@ -158,10 +160,9 @@ $ aws ecr get-repository-policy --repository-name retail-sample-app-ui You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. ```bash -$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query 'policyText' --output text > ecr-policy.json -$ jq '(.Statement[] | select(.Effect == "Deny")).Effect = "Allow"' ecr-policy.json > updated-ecr-policy.json -$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://updated-ecr-policy.json -$ rm ecr-policy.json updated-ecr-policy.json +$ export ROLE_ARN=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole'` +$ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow","Principal":{"AWS":'${ROLE_ARN}'},"Action":["ecr:BatchCheckLayerAvailability","ecr:BatchDeleteImage","ecr:BatchGetImage","ecr:CompleteLayerUpload","ecr:DeleteRepository","ecr:DeleteRepositoryPolicy","ecr:DescribeRepositories","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:InitiateLayerUpload","ecr:ListImages","ecr:PutImage","ecr:SetRepositoryPolicy","ecr:UploadLayerPart"]}]}' > ~/ecr-policy.json +$ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://~/ecr-policy.json ``` You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. @@ -170,7 +171,7 @@ You can confirm if the ECR repo policy updated successfully, by using the above Now, check if the pods are running. -```bash +```bash timeout=180 hook=fix-2 hookTimeout=600 $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index b40d9389a..d27363700 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -1,6 +1,8 @@ --- title: "PodStuck - ContainerCreating" sidebar_position: 43 +chapter: true +sidebar_custom_props: { "module": true } --- In this section we will learn how to troubleshoot the pod for one of the scenarios where it is stuck in ContainerCreating state. @@ -51,8 +53,8 @@ efs-app-5c4df89785-m4qz4 0/1 ContainerCreating 0 19m You can see that the pod status is showing as ContainerCreating. Lets describe the pod to see the events. -```bash -$ POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` +```bash expectError=true +$ export POD=`kubectl get pods -o jsonpath='{.items[*].metadata.name}'` $ kubectl describe pod $POD | awk '/Events:/,/^$/' Events: Type Reason Age From Message @@ -88,8 +90,9 @@ Connection to the mount target IP address x.x.x.x timeout.'. This gives us an id In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. ```bash -$ INSTANCE=`kubectl get node ($ kubectl get pod $POD -o jsonpath='{.spec.nodeName}') -o yaml` -$ SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` +$ export NODE=`kubectl get pod $POD -o jsonpath='{.spec.nodeName}'` +$ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut -d'/' -f5` +$ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" ``` You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. @@ -114,10 +117,10 @@ In the below commands, we are - Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group ```bash -$ AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` -$ EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` -$ MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` -$ MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` +$ export AZ=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[*].Instances[*].[Placement.AvailabilityZone]" --output text` +$ export EFS=`kubectl get pv $(kubectl get pvc efs-claim -o jsonpath='{.spec.volumeName}') -o jsonpath='{.spec.csi.volumeHandle}' | cut -d':' -f1` +$ export MT_ENI=`aws efs describe-mount-targets --file-system-id $EFS --query "MountTargets[?AvailabilityZoneName=='$AZ'].[NetworkInterfaceId]" --output text` +$ export MT_SG=`aws ec2 describe-network-interfaces --network-interface-ids $MT_ENI --query "NetworkInterfaces[*].[Groups[*].GroupId]" --output text` $ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[].IpPermissions[]" [ { @@ -159,13 +162,13 @@ In the below commands, we are - Adding inbound rule to mount target security group allowing traffic on port 2049 from VPC CIDR. ```bash -$ VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` -$ CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` +$ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` After 3-4 minutes, you should notice that the pod in default namespace is in running state -```bash +```bash timeout=180 hook=fix-3 hookTimeout=600 $ kubectl get pods $POD NAME READY STATUS RESTARTS AGE efs-app-5c4df89785-m4qz4 1/1 Running 0 102m diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-1.sh b/website/docs/troubleshooting/pod/tests/hook-fix-1.sh new file mode 100644 index 000000000..1c86ed001 --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-1.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 120 + + if kubectl get pods --selector="app=app-new" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-2.sh b/website/docs/troubleshooting/pod/tests/hook-fix-2.sh new file mode 100644 index 000000000..9c3ad3ba8 --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-2.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 180 + + if kubectl get pods --selector="app=app-private" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-fix-3.sh b/website/docs/troubleshooting/pod/tests/hook-fix-3.sh new file mode 100644 index 000000000..bbd797ead --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-fix-3.sh @@ -0,0 +1,21 @@ +set -Eeuo pipefail + +before() { + echo "noop" +} + +after() { + sleep 240 + + if kubectl get pods --selector="app=efs-app" 2>&1 | grep -q "Running"; then + echo "Success: The pod is now in running state" + exit 0 + fi + + >&2 echo "pod is not in running state, when expected to be running" + exit 1 +} + + + +"$@" \ No newline at end of file diff --git a/website/docs/troubleshooting/pod/tests/hook-suite.sh b/website/docs/troubleshooting/pod/tests/hook-suite.sh new file mode 100644 index 000000000..36ca4218e --- /dev/null +++ b/website/docs/troubleshooting/pod/tests/hook-suite.sh @@ -0,0 +1,11 @@ +set -e + +before() { + echo "noop" +} + +after() { + prepare-environment +} + +"$@" \ No newline at end of file diff --git a/website/test-durations.json b/website/test-durations.json index 30575364c..c618ef0ee 100644 --- a/website/test-durations.json +++ b/website/test-durations.json @@ -191,5 +191,8 @@ "/security/secrets-management/secrets-manager/external-secrets.md": 14963, "/security/secrets-management/secrets-manager/index.md": 281009, "/security/secrets-management/secrets-manager/mounting-secrets.md": 16049, - "/troubleshooting/alb/index.md": 16049 + "/troubleshooting/alb/index.md": 16049, + "/troubleshooting/pod/image_pull_1.md": 16049, + "/troubleshooting/pod/image_pull_2.md": 16049, + "/troubleshooting/pod/pod_stuck.md": 16049 } From 8f2bbb4cb0dc638b358e53a0723cf8ea069c6077 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Tue, 5 Nov 2024 22:11:18 +0000 Subject: [PATCH 09/12] fixed pre-commit errors --- .../pod/crash/.workshop/cleanup.sh | 2 -- .../pod/crash/.workshop/terraform/main.tf | 18 +++++----- .../pod/crash/.workshop/terraform/outputs.tf | 5 +-- .../pod/crash/.workshop/terraform/vars.tf | 2 +- .../pod/image/.workshop/cleanup.sh | 2 -- .../pod/image/.workshop/terraform/main.tf | 2 +- .../pod/image/.workshop/terraform/outputs.tf | 3 +- .../pod/image/.workshop/terraform/vars.tf | 2 +- .../troubleshooting/pod/image/deployment.yaml | 2 +- .../pod/permissions/.workshop/cleanup.sh | 2 -- .../permissions/.workshop/terraform/main.tf | 30 ++++++++-------- .../.workshop/terraform/outputs.tf | 3 +- .../permissions/.workshop/terraform/vars.tf | 2 +- .../docs/troubleshooting/pod/image_pull_1.md | 9 ++--- .../docs/troubleshooting/pod/image_pull_2.md | 34 +++++++++---------- website/docs/troubleshooting/pod/index.md | 3 +- website/docs/troubleshooting/pod/pod_stuck.md | 22 ++++++------ website/test-durations.json | 4 +-- 18 files changed, 73 insertions(+), 74 deletions(-) diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh index f37989081..403d252cf 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment efs-app -n default > /dev/null 2>&1; then kubectl delete deployment efs-app -n default else diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf index 06809a932..6bd5c988f 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } data "aws_vpc" "selected" { @@ -37,11 +37,11 @@ data "aws_subnets" "public" { } } -data "aws_region" "current" {} - +/* data "aws_eks_cluster" "cluster" { name = var.eks_cluster_id } +*/ module "eks_blueprints_addons" { source = "aws-ia/eks-blueprints-addons/aws" @@ -62,13 +62,13 @@ module "eks_blueprints_addons" { resource "aws_efs_file_system" "efs" { tags = { Name = "eks-workshop-efs" - } + } } resource "aws_efs_mount_target" "mount_targets" { - for_each = toset(data.aws_subnets.public.ids) - file_system_id = resource.aws_efs_file_system.efs.id - subnet_id = each.value + for_each = toset(data.aws_subnets.public.ids) + file_system_id = resource.aws_efs_file_system.efs.id + subnet_id = each.value security_groups = [resource.aws_security_group.efs_sg.id] } @@ -101,13 +101,13 @@ data "template_file" "deployment_yaml" { template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") vars = { - filesystemid = "${resource.aws_efs_file_system.efs.id}" + filesystemid = "resource.aws_efs_file_system.efs.id" } } resource "local_file" "deployment_yaml" { filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/deployment.yaml" - content = data.template_file.deployment_yaml.rendered + content = data.template_file.deployment_yaml.rendered } resource "null_resource" "kustomize_app" { diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf index 688f66d65..d50ab0d36 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/outputs.tf @@ -1,11 +1,12 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } output "environment_variables" { description = "Environment variables to be added to the IDE shell" value = merge({ - VPC_ID = data.aws_vpc.selected.id + VPC_ID = data.aws_vpc.selected.id }, { for index, id in data.aws_subnets.public.ids : "PUBLIC_SUBNET_${index + 1}" => id } diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh index ac311489e..37769eb30 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/image/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment ui-new -n default > /dev/null 2>&1; then kubectl delete deploy ui-new -n default else diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf index 565d04435..cd46cf5a1 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf index efa7cab69..269e7a3b0 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/outputs.tf @@ -1,3 +1,4 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/image/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/manifests/modules/troubleshooting/pod/image/deployment.yaml b/manifests/modules/troubleshooting/pod/image/deployment.yaml index 687f170ca..7e07e3ef8 100644 --- a/manifests/modules/troubleshooting/pod/image/deployment.yaml +++ b/manifests/modules/troubleshooting/pod/image/deployment.yaml @@ -58,4 +58,4 @@ spec: volumes: - name: tmp-volume emptyDir: - medium: Memory \ No newline at end of file + medium: Memory diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh index 53b68768d..068f0e83f 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/cleanup.sh @@ -1,7 +1,5 @@ #!/bin/bash -aws eks update-kubeconfig --name eks-workshop - if kubectl get deployment ui-private -n default > /dev/null 2>&1; then kubectl delete deploy ui-private -n default else diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf index 35fdecbad..b8aa2c22a 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/main.tf @@ -15,7 +15,7 @@ provider "aws" { data "aws_caller_identity" "current" {} locals { - account_id = data.aws_caller_identity.current.account_id + account_id = data.aws_caller_identity.current.account_id } data "aws_region" "current" {} @@ -24,12 +24,14 @@ data "aws_eks_cluster" "cluster" { name = var.eks_cluster_id } +/* data "aws_vpc" "selected" { tags = { created-by = "eks-workshop-v2" env = var.addon_context.eks_cluster_id } } +*/ data "aws_eks_node_group" "default" { cluster_name = data.aws_eks_cluster.cluster.id @@ -42,19 +44,19 @@ data "aws_ssm_parameter" "eks_ami" { data "aws_subnets" "selected" { tags = { - env = var.addon_context.eks_cluster_id + env = var.addon_context.eks_cluster_id } } resource "aws_iam_role" "ecr_ec2_role" { - name = "ecr_ec2_role" + name = "ecr_ec2_role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { - Service = "ec2.amazonaws.com" + Service = "ec2.amazonaws.com" } Action = "sts:AssumeRole" }, @@ -69,9 +71,9 @@ resource "aws_iam_instance_profile" "ecr_ec2" { } resource "aws_instance" "ui_to_ecr" { - ami = data.aws_ssm_parameter.eks_ami.value - instance_type = "t3.medium" - user_data = <<-EOF + ami = data.aws_ssm_parameter.eks_ami.value + instance_type = "t3.medium" + user_data = <<-EOF #!/bin/bash sudo yum update -y sudo amazon-linux-extras install docker @@ -82,19 +84,19 @@ resource "aws_instance" "ui_to_ecr" { aws ecr get-login-password | docker login --username AWS --password-stdin ${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.id}.amazonaws.com docker push ${resource.aws_ecr_repository.ui.repository_url}:0.4.0 EOF - subnet_id = element(data.aws_subnets.selected.ids, 0) + subnet_id = element(data.aws_subnets.selected.ids, 0) iam_instance_profile = resource.aws_iam_instance_profile.ecr_ec2.name - depends_on = [resource.aws_ecr_repository.ui] + depends_on = [resource.aws_ecr_repository.ui] } resource "aws_ecr_repository" "ui" { name = "retail-sample-app-ui" image_tag_mutability = "MUTABLE" - force_delete = true - + force_delete = true + } -data "aws_iam_policy_document" "private-registry" { +data "aws_iam_policy_document" "private_registry" { statement { sid = "new policy" effect = "Deny" @@ -126,7 +128,7 @@ data "aws_iam_policy_document" "private-registry" { resource "aws_ecr_repository_policy" "example" { repository = aws_ecr_repository.ui.name - policy = data.aws_iam_policy_document.private-registry.json + policy = data.aws_iam_policy_document.private_registry.json depends_on = [resource.aws_instance.ui_to_ecr] } @@ -141,7 +143,7 @@ data "template_file" "deployment_yaml" { resource "local_file" "deployment_yaml" { filename = "/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/permissions/deployment.yaml" - content = data.template_file.deployment_yaml.rendered + content = data.template_file.deployment_yaml.rendered } /* diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf index efa7cab69..269e7a3b0 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/outputs.tf @@ -1,3 +1,4 @@ output "account_id" { - value = local.account_id + value = local.account_id + description = "account id env variable" } \ No newline at end of file diff --git a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf index 39eb0f89d..7e0b2f7ab 100644 --- a/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf +++ b/manifests/modules/troubleshooting/pod/permissions/.workshop/terraform/vars.tf @@ -2,7 +2,7 @@ variable "eks_cluster_id" { description = "EKS cluster name" type = string - default = "eks-workshop" + default = "eks-workshop" } # tflint-ignore: terraform_unused_declarations diff --git a/website/docs/troubleshooting/pod/image_pull_1.md b/website/docs/troubleshooting/pod/image_pull_1.md index 317c6115e..9a98ee4c7 100644 --- a/website/docs/troubleshooting/pod/image_pull_1.md +++ b/website/docs/troubleshooting/pod/image_pull_1.md @@ -76,13 +76,13 @@ public.ecr.aws/aws-containers/retailing-store-sample-ui:0.4.0 ### Step 4 -From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at https://gallery.ecr.aws/aws-containers . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui and since the image does not exist we will see Repository not found message as shown below. +From the image URI, we can see that the image is referenced from public ECR repository of aws. Lets check if image named retailing-store-sample-ui with tag 0.4.0 exists at [aws-containers ECR](https://gallery.ecr.aws/aws-containers) . Search for the "retailing-store-sample-ui" and you will notice that no such image repository shows up. You can also easily verify the image existence in public ecr by using the image URI on browser. In our case [image-uri](https://gallery.ecr.aws/aws-containers/retailing-store-sample-ui) and since the image does not exist we will see Repository not found message as shown below. ![RepoDoesNotExist](./assets/rep-not-found.webp) ### Step 5 -To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the URL https://gallery.ecr.aws/aws-containers/retail-store-sample-ui. You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. +To resolve the issue, we will have to update the deployment/pod spec with correct image reference. In our case it is public.ecr.aws/aws-containers/retail-store-sample-ui:0.4.0. Before we update the deployment, lets verify if this image exists using above mentioned method i.e. to hit the [image-uri](https://gallery.ecr.aws/aws-containers/retail-store-sample-ui). You should be able to see the retail-store-sample-ui image with multiple tags available. Out of which we are going to use 0.4.0. ![RepoExist](./assets/repo-found.webp) @@ -112,7 +112,8 @@ General troubleshooting workflow of the pod with ImagePullBackOff on public imag - Check the pod events for a clue on cause of the issue such as not found, access denied or timeout. - If not found, ensure that the image exists in the path referenced. - For access denied, check the permissions on worker node role. -- For timeout on public images on ECR, ensure that the worker node is configured to reach the internet via IGW/TGW/NAT. +- For timeout on public images on ECR, ensure that the worker node networking is configured to reach the internet via IGW/TGW/NAT. References: -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html + +- [ECR-with-EKS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html) diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index 47886b879..d82fbb250 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -17,7 +17,7 @@ $ prepare-environment troubleshooting/pod/permissions The preparation of the lab might take a couple of minutes and it will make the following changes to your lab environment: - Create a ECR repo named retail-sample-app-ui. -- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 +- Create a EC2 instance and push retail store sample app image in to the ECR repo from the instance using tag 0.4.0 - Create a new deployment named ui-private in default namespace - Introduce an issue to the deployment spec, so we can learn how to troubleshoot this type of issues @@ -60,11 +60,11 @@ Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 5m15s default-scheduler Successfully assigned default/ui-private-7655bf59b9-jprrj to ip-10-42-33-232.us-west-2.compute.internal - Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" - Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https://682844965773.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden + Normal Pulling 3m53s (x4 over 5m15s) kubelet Pulling image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Warning Failed 3m53s (x4 over 5m14s) kubelet Failed to pull image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to pull and unpack image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": failed to resolve reference "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0": unexpected status from HEAD request to https:/"1234567890.dkr.ecr.us-west-2.amazonaws.com/v2/retail-sample-app-ui/manifests/0.4.0: 403 Forbidden Warning Failed 3m53s (x4 over 5m14s) kubelet Error: ErrImagePull Warning Failed 3m27s (x6 over 5m14s) kubelet Error: ImagePullBackOff - Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" + Normal BackOff 4s (x21 over 5m14s) kubelet Back-off pulling image "1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" ``` ### Step 3 @@ -72,8 +72,7 @@ Events: From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. ```bash -$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' -682844965773.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}'"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 ``` ### Step 4 @@ -81,11 +80,11 @@ $ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*]. From the image URI, we can see that the image is referenced from the account where our EKS cluster is in. Lets check the ECR repository to see if any such image exists. ```bash -$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 +$ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids imageTag=0.4.0 { "imageDetails": [ { - "registryId": "682844965773", + "registryId": "1234567890", "repositoryName": "retail-sample-app-ui", "imageDigest": "sha256:b338785abbf5a5d7e0f6ebeb8b8fc66e2ef08c05b2b48e5dfe89d03710eec2c1", "imageTags": [ @@ -100,7 +99,7 @@ $ aws ecr describe-images --repository-name retail-sample-app-ui --image-ids ima } ``` -You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. +You should see that the image path we have in deployment i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 have a valid registryId i.e. account-number, valid repositoryName i.e. "retail-sample-app-ui" and valid imageTag i.e. "0.4.0". Which confirms the path of the image is correct and is not a wrong reference. :::info Alternatively, you can also check the console for the same. Click the button below to open the ECR Console. Then click on retail-sample-app-ui repository and the image tag 0.4.0, you should then see the complete URI of the image which should match with the URI in deployment spec i.e. account_id.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 @@ -113,7 +112,7 @@ Alternatively, you can also check the console for the same. Click the button bel ### Step 5 -As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. +As we confirmed that the image URI is correct, lets check the permissions of the kubelet and confirm if the permissions required to pull images from ECR exists. Get the IAM role attached to worker nodes in the managed node group of the cluster and list the IAM policies attached to it. @@ -151,9 +150,9 @@ The perimissions to the ECR repository can be managed at both Identity and Resou ```bash $ aws ecr get-repository-policy --repository-name retail-sample-app-ui { - "registryId": "682844965773", + "registryId": "1234567890", "repositoryName": "retail-sample-app-ui", - "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam::682844965773:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" + "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam:"1234567890:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" } ``` @@ -165,7 +164,7 @@ $ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow $ aws ecr set-repository-policy --repository-name retail-sample-app-ui --policy-text file://~/ecr-policy.json ``` -You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. +You can confirm if the ECR repo policy updated successfully, by using the above get-repository-policy command. ### Step 7 @@ -177,7 +176,7 @@ NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m ``` -That concludes the private ECR ImagePullBackOff troubleshooting section. +That concludes the private ECR ImagePullBackOff troubleshooting section. ## Wrapping it up @@ -189,6 +188,7 @@ General troubleshooting workflow of the pod with ImagePullBackOff on private ima - For timeout on ECR, ensure that the worker node is configured to reach the ECR endpoint. References: -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html -- https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html -- https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html + +- [ECR_on_EKS](https://docs.aws.amazon.com/AmazonECR/latest/userguide/ECR_on_EKS.html) +- [ECR_repo_policies](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html) +- [EKS_networking](https://docs.aws.amazon.com/eks/latest/userguide/eks-networking.html) diff --git a/website/docs/troubleshooting/pod/index.md b/website/docs/troubleshooting/pod/index.md index 1cdc069ac..9ab5da433 100644 --- a/website/docs/troubleshooting/pod/index.md +++ b/website/docs/troubleshooting/pod/index.md @@ -8,7 +8,6 @@ description: "Run deployments with diferent image paths/sources and persistent v ::required-time -In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. +In this section we will learn how to troubleshoot some of the most common pod issues which prevent the containerized application from running inside the EKS cluster, such as ImagePullBackOff and stuck in ContainerCreating state. - Pod Issues such as readiness/liveness probe failures and scheduling issues will be coming soon under this section of troubleshooting module. - diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index d27363700..63f566dc1 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -20,7 +20,6 @@ The preparation of the lab might take a couple of minutes and it will make the f - Create a EFS filesystem and mount targets. - Create a deployment named efs-app backed by a persistent volume claim named efs-claim to leverage EFS as persistent volume, in the default namespace. - ::: You can view the Terraform that applies these changes [here](https://github.com/VAR::MANIFESTS_OWNER/VAR::MANIFESTS_REPOSITORY/tree/VAR::MANIFESTS_REF/manifests/modules/troubleshooting/pod/crash/.workshop/terraform). @@ -62,13 +61,13 @@ Events: Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 Mounting command: mount Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount -Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". The file system mount target ip address cannot be found, please pass mount target ip address via mount options. No mount target created for the file system fs-00a4069aec7924c8c is in available state yet, please retry in 5 minutes. Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. Warning FailedMount 26m (x3 over 26m) kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 1 Mounting command: mount Mounting arguments: -t efs -o accesspoint=fsap-0488d7b0bd9c26425,tls fs-00a4069aec7924c8c:/ /var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount -Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. +Output: Failed to resolve "fs-00a4069aec7924c8c.efs.us-west-2.amazonaws.com". Cannot connect to file system mount target ip address 10.42.41.35. Connection to the mount target IP address 10.42.41.35 timeout. Please retry in 5 minutes if the mount target is newly created. Otherwise check your VPC and security group configuration to ensure your file system is reachable via TCP port 2049 from your instance. Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False].Warning: config file does not have fips_mode_enabled item in section mount.. You should be able to find a new config file in the same folder as current config file /etc/amazon/efs/efs-utils.conf. Consider update the new config file to latest config file. Use the default value [fips_mode_enabled = False]. Warning FailedMount 19m kubelet MountVolume.SetUp failed for volume "pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0" : rpc error: code = Internal desc = Could not mount "fs-00a4069aec7924c8c:/" at "/var/lib/kubelet/pods/b2db07f9-0bae-4324-98e6-e4c978a0bef5/volumes/kubernetes.io~csi/pvc-719c8ef2-5bdb-4638-b4db-7d59b53d21f0/mount": mount failed: exit status 32 @@ -84,7 +83,7 @@ Warning: config file does not have fips_mode_enabled item in section mount.. You ### Step 3 -From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. +From the events of the pod, we can see the ' Cannot connect to file system mount target ip address x.x.x.x. Connection to the mount target IP address x.x.x.x timeout.'. This gives us an idea that the EFS file system is failed to mount for the pods to use as persistent volume. With out which the pod cannot move to running state. Lets check the networking configuration of the node on which the pod is scheduled to run. In the below commands, we are getting the instance id of the node where pod is scheduled and then fetching the security groups attached to that node and further checking the egress rules to see if there are limitations on destination. @@ -95,6 +94,7 @@ $ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut $ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" ``` + You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. :::info @@ -110,8 +110,9 @@ Alternatively, click the button below to open the EKS Console. Then navigate to Now, lets check the EFS file system networking configuration. -In the below commands, we are -- Retrieving the Availability zone of the worker node using instance id. +In the below commands, we are + +- Retrieving the Availability zone of the worker node using instance id. - Retrieving the EFS id from the persistent volume claim. - Retrieving the mount target ENI for the availability zone corresponding to the instance Id. - Retrieving the security groups attached to the mount target ENI and checking the inbound rules of the security group @@ -141,7 +142,6 @@ $ aws ec2 describe-security-groups --group-ids $MT_SG --query "SecurityGroups[]. You should see that the security group attached to the mount target of EFS have inbound rules only on port 80 from the VPC CIDR. However, for the mount to be successful the security group of mount target should allow traffic on port 2049. Which is why the mount request is timing out from the EKS worker node. - :::info Alternatively, you can also check the console for the same. Click the button below to open the EFS Console. Then click on EFS file system Id which has name as eks-workshop-efs. Then click on Network to view mount targets for all availability zones and the security groups attached to the each mount target. @@ -166,7 +166,8 @@ $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.r $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` -After 3-4 minutes, you should notice that the pod in default namespace is in running state + +After 3-4 minutes, you should notice that the pod in default namespace is in running state ```bash timeout=180 hook=fix-3 hookTimeout=600 $ kubectl get pods $POD @@ -183,7 +184,6 @@ This concludes the pod stuck in ContainerCreating troubleshooting section. General, troubleshooting workflow of pods stuck in ContainerCreating state is to check pod events and for volume mount issues: - Check the volume claim used by the pod and identify the type of volume used. -- Then check the csi driver used for that volume and check the requiements to use that volume in EKS pods at https://docs.aws.amazon.com/eks/latest/userguide/storage.html +- Then check the csi driver used for that volume and check the requirements to use that volume in EKS pods at [EKS Storage](https://docs.aws.amazon.com/eks/latest/userguide/storage.html) - Confirm that all the requiements mentioned in the corresponding storage type document are met. -- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues - +- Further check for troubleshooting guide of that CSI driver if exists. For example, to check mount issues of EFS with EKS there is a troubleshooting guide at [EFS CSi Driver](https://repost.aws/knowledge-center/eks-troubleshoot-efs-volume-mount-issues) diff --git a/website/test-durations.json b/website/test-durations.json index c618ef0ee..949335ff4 100644 --- a/website/test-durations.json +++ b/website/test-durations.json @@ -193,6 +193,6 @@ "/security/secrets-management/secrets-manager/mounting-secrets.md": 16049, "/troubleshooting/alb/index.md": 16049, "/troubleshooting/pod/image_pull_1.md": 16049, - "/troubleshooting/pod/image_pull_2.md": 16049, - "/troubleshooting/pod/pod_stuck.md": 16049 + "/troubleshooting/pod/image_pull_2.md": 16049, + "/troubleshooting/pod/pod_stuck.md": 16049 } From 3245a57f0be4040a96ee49cf688c9b73a1bda7e3 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 03:22:01 +0000 Subject: [PATCH 10/12] fixed pre-commit errors --- .../troubleshooting/pod/crash/.workshop/terraform/main.tf | 2 +- website/docs/troubleshooting/pod/image_pull_2.md | 6 ++++-- website/docs/troubleshooting/pod/pod_stuck.md | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf index 6bd5c988f..5237da270 100644 --- a/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf +++ b/manifests/modules/troubleshooting/pod/crash/.workshop/terraform/main.tf @@ -101,7 +101,7 @@ data "template_file" "deployment_yaml" { template = file("/home/ec2-user/environment/eks-workshop/modules/troubleshooting/pod/crash/.workshop/terraform/deployment.yaml.tpl") vars = { - filesystemid = "resource.aws_efs_file_system.efs.id" + filesystemid = resource.aws_efs_file_system.efs.id } } diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index d82fbb250..977bc0dcb 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -72,7 +72,8 @@ Events: From the events of the pod, we can see the 'Failed to pull image' warning, with cause as 403 Forbidden. This gives us an idea that the kubelet faced access denied while trying to pull the image used in the deployment. Lets get the URI of the image used in the deployment. ```bash -$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}'"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0 +$ kubectl get deploy ui-private -o jsonpath='{.spec.template.spec.containers[*].image}' +"1234567890.dkr.ecr.us-west-2.amazonaws.com/retail-sample-app-ui:0.4.0" ``` ### Step 4 @@ -168,9 +169,10 @@ You can confirm if the ECR repo policy updated successfully, by using the above ### Step 7 -Now, check if the pods are running. +Now, restart the deployment and check if the pods are running. ```bash timeout=180 hook=fix-2 hookTimeout=600 +$ kubectl rollout restart deploy ui-private $ kubectl get pods NAME READY STATUS RESTARTS AGE ui-private-7655bf59b9-s9pvb 1/1 Running 0 65m diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 63f566dc1..6cb04e953 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -164,6 +164,9 @@ In the below commands, we are ```bash $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` +$ echo $VPC_ID +$ echo $CIDR +$ echo $MT_SG $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` From d1b5c26d4ed90432e51a0c3e4431a650987b2084 Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 17:17:17 +0000 Subject: [PATCH 11/12] fix pod crash --- website/docs/troubleshooting/pod/pod_stuck.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 6cb04e953..63f566dc1 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -164,9 +164,6 @@ In the below commands, we are ```bash $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` -$ echo $VPC_ID -$ echo $CIDR -$ echo $MT_SG $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR ``` From 1e13ac9fdecd29053c431498aae3dd3bfcc3d6fa Mon Sep 17 00:00:00 2001 From: Raghuveerareddy Pagilla Date: Wed, 6 Nov 2024 21:11:34 +0000 Subject: [PATCH 12/12] fixed the readme content --- .../docs/troubleshooting/pod/image_pull_2.md | 64 +++++++++++++++++-- website/docs/troubleshooting/pod/pod_stuck.md | 28 ++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/website/docs/troubleshooting/pod/image_pull_2.md b/website/docs/troubleshooting/pod/image_pull_2.md index 977bc0dcb..1c53c11aa 100644 --- a/website/docs/troubleshooting/pod/image_pull_2.md +++ b/website/docs/troubleshooting/pod/image_pull_2.md @@ -149,16 +149,72 @@ You should see that the AWS managed policy "arn:aws:iam::aws:policy/AmazonEC2Con The perimissions to the ECR repository can be managed at both Identity and Resource level. The Identity level permissions are provided at IAM and the resource level permissions are provided at the repository level. As we confirmed that identity based permissions are good, the issue could be with resource level permissions. Lets the check the policy for ECR repo. ```bash -$ aws ecr get-repository-policy --repository-name retail-sample-app-ui +$ aws ecr get-repository-policy --repository-name retail-sample-app-ui --query policyText --output text | jq . { - "registryId": "1234567890", - "repositoryName": "retail-sample-app-ui", - "policyText": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [ {\n \"Sid\" : \"new policy\",\n \"Effect\" : \"Deny\",\n \"Principal\" : {\n \"AWS\" : \"arn:aws:iam:"1234567890:role/eksctl-eks-workshop-nodegroup-defa-NodeInstanceRole-Fa4f8r6uT7UD\"\n },\n \"Action\" : [ \"ecr:UploadLayerPart\", \"ecr:SetRepositoryPolicy\", \"ecr:PutImage\", \"ecr:ListImages\", \"ecr:InitiateLayerUpload\", \"ecr:GetRepositoryPolicy\", \"ecr:GetDownloadUrlForLayer\", \"ecr:DescribeRepositories\", \"ecr:DeleteRepositoryPolicy\", \"ecr:DeleteRepository\", \"ecr:CompleteLayerUpload\", \"ecr:BatchGetImage\", \"ecr:BatchDeleteImage\", \"ecr:BatchCheckLayerAvailability\" ]\n } ]\n}" + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "new policy", + "Effect": "Deny", + "Principal": { + "AWS": "arn:aws:iam::1234567890:role/EksNodeGroupRole" + }, + "Action": [ + "ecr:UploadLayerPart", + "ecr:SetRepositoryPolicy", + "ecr:PutImage", + "ecr:ListImages", + "ecr:InitiateLayerUpload", + "ecr:GetRepositoryPolicy", + "ecr:GetDownloadUrlForLayer", + "ecr:DescribeRepositories", + "ecr:DeleteRepositoryPolicy", + "ecr:DeleteRepository", + "ecr:CompleteLayerUpload", + "ecr:BatchGetImage", + "ecr:BatchDeleteImage", + "ecr:BatchCheckLayerAvailability" + ] + } + ] } ``` You should see that the ECR repository policy has Effect as Deny and the Principal as the EKS managed node role. Which is restricting the kubelet from pulling images in this repository. Lets change the effect to allow and see if the kubelet is able to pull the image. +We will be using below json file to modify the ecr repository permissions. You can notice that the Effect is set to Allow for the Node IAM role. + +```json {6} +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "new policy", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::1234567890:role/EksNodeGroupRole" + }, + "Action": [ + "ecr:UploadLayerPart", + "ecr:SetRepositoryPolicy", + "ecr:PutImage", + "ecr:ListImages", + "ecr:InitiateLayerUpload", + "ecr:GetRepositoryPolicy", + "ecr:GetDownloadUrlForLayer", + "ecr:DescribeRepositories", + "ecr:DeleteRepositoryPolicy", + "ecr:DeleteRepository", + "ecr:CompleteLayerUpload", + "ecr:BatchGetImage", + "ecr:BatchDeleteImage", + "ecr:BatchCheckLayerAvailability" + ] + } + ] +} +``` + ```bash $ export ROLE_ARN=`aws eks describe-nodegroup --cluster-name eks-workshop --nodegroup-name default --query 'nodegroup.nodeRole'` $ echo '{"Version":"2012-10-17","Statement":[{"Sid":"new policy","Effect":"Allow","Principal":{"AWS":'${ROLE_ARN}'},"Action":["ecr:BatchCheckLayerAvailability","ecr:BatchDeleteImage","ecr:BatchGetImage","ecr:CompleteLayerUpload","ecr:DeleteRepository","ecr:DeleteRepositoryPolicy","ecr:DescribeRepositories","ecr:GetDownloadUrlForLayer","ecr:GetRepositoryPolicy","ecr:InitiateLayerUpload","ecr:ListImages","ecr:PutImage","ecr:SetRepositoryPolicy","ecr:UploadLayerPart"]}]}' > ~/ecr-policy.json diff --git a/website/docs/troubleshooting/pod/pod_stuck.md b/website/docs/troubleshooting/pod/pod_stuck.md index 63f566dc1..c628d72da 100644 --- a/website/docs/troubleshooting/pod/pod_stuck.md +++ b/website/docs/troubleshooting/pod/pod_stuck.md @@ -93,6 +93,19 @@ $ export NODE=`kubectl get pod $POD -o jsonpath='{.spec.nodeName}'` $ export INSTANCE=`kubectl get node $NODE -o jsonpath='{.spec.providerID}' | cut -d'/' -f5` $ export SG=`aws ec2 describe-instances --instance-ids $INSTANCE --query "Reservations[].Instances[].SecurityGroups[].GroupId" --output text` $ aws ec2 describe-security-groups --group-ids $SG --query "SecurityGroups[].IpPermissionsEgress[]" +[ + { + "IpProtocol": "-1", + "UserIdGroupPairs": [], + "IpRanges": [ + { + "CidrIp": "0.0.0.0/0" + } + ], + "Ipv6Ranges": [], + "PrefixListIds": [] + } +] ``` You can see that the egress rules have no limitations. IpProtocol -1 indicates all protocols and the CidrIp indicates the destination as 0.0.0.0/0. So the communication from the worker node is not restricted and should be able to reach the EFS mount target. @@ -165,6 +178,21 @@ In the below commands, we are $ export VPC_ID=`aws eks describe-cluster --name eks-workshop --query "cluster.resourcesVpcConfig.vpcId" --output text` $ export CIDR=`aws ec2 describe-vpcs --vpc-ids $VPC_ID --query "Vpcs[*].CidrBlock" --output text` $ aws ec2 authorize-security-group-ingress --group-id $MT_SG --protocol tcp --port 2049 --cidr $CIDR +{ + "Return": true, + "SecurityGroupRules": [ + { + "SecurityGroupRuleId": "sgr-05ae66b3cfaf2b03c", + "GroupId": "sg-0d69452207db88cde", + "GroupOwnerId": "682844965773", + "IsEgress": false, + "IpProtocol": "tcp", + "FromPort": 2049, + "ToPort": 2049, + "CidrIpv4": "10.42.0.0/16" + } + ] +} ``` After 3-4 minutes, you should notice that the pod in default namespace is in running state