Which part of my AWS EKS setup isn't running correctly? - amazon-web-services

I have setup an EKS cluster and configured it to run 6 or so different microservices in their own pods. I am using an ALB as the ingress to said pods and have noticed that sometimes the connection to the pods will time out. I am struggling to determine exactly what the cause of this is.
The pods work as expected for the first X amount of requests but once they have been left for a while and then I try to make a new request, the connection will time out. Could this be due to the ALB or am I missing something with Kubernetes?
One of the deployments looks like this:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: challengepasswordlookupservice
labels:
app: challengepasswordlookupservice
spec:
replicas: 1
selector:
matchLabels:
app: challengepasswordlookupservice
template:
metadata:
labels:
app: challengepasswordlookupservice
spec:
containers:
- name: challengepasswordlookupservice
image: *withheld*
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: challengepasswordlookupservice
spec:
type: NodePort
selector:
app: challengepasswordlookupservice
ports:
- protocol: TCP
port: 80
targetPort: 80
And the ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: golf-high-service-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":{ "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-west-2:206106816545:certificate/8d91b886-9d57-4fcf-b016-04959cf4d97d
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=60
spec:
rules:
- host: "*withheld*"
http:
paths:
- path: "/*"
pathType: Prefix
backend:
service:
name: ssl-redirect
port:
name: use-annotation
- path: "/*"
pathType: Prefix
backend:
service:
name: challengepasswordlookupservice
port:
number: 80

Try to increase the idle_timeout.timeout_seconds=60 to something relevant like maybe 1800 inside the annotations and then try it out.
I believe you'll want the load-balancer-attributes annotation set to idle_timeout.timeout_seconds=1800
https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/8c2fbfd478a77f983afde2bb5a3ce2f06957e75d/internal/alb/lb/attributes.go#L20

The issue was with the ALB. On AWS, an ALB requires 1 subnet in at least two different availability zones. One of the subnets that was attached did not have an internet gateway attached and thus was not establishing a connection when the request was routed to this subnet.

Related

How to keep LoadBalancer[ALB] even after we delete Ingress Manifest in AWS EKS?

When we launch the EKS Cluster using the below manifest, it is creating ALB. We have a default ALB that we are using, let's call it EKS-ALB. The Hosted zone is routing traffic to this EKS-ALB. We gave tag ingress.k8s.aws/resource:LoadBalancer, ingress.k8s.aws/stack:test-alb, elbv2.k8s.aws/cluster: EKS. But when we delete the manifest, it is deleting the default ALB and we need to reconfigure hosted zone again with New ALB which will get created in next deployment. Is there any way to block Ingress-controller not deleting ALB, but only deleting the listeners and Target Group?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-nginx-rule
namespace: test
annotations:
alb.ingress.kubernetes.io/group.name: test-alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
alb.ingress.kubernetes.io/healthcheck-path: /index.html
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/security-groups: eks-test-alb-sg
spec:
ingressClassName: alb
rules:
- host: test.eks.abc.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: test-svc
port:
number: 5005
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-dep
namespace: test
labels:
app: test
spec:
replicas: 1
restartPolicy:
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: test
image: Imagepath
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5005
resources:
requests:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: test-svc
namespace: test
labels:
app: test
spec:
type: NodePort
ports:
- port: 5005
targetPort: 80
protocol: TCP
selector:
app: test
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: test-scaler
namespace: test
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: test-dep
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 60
---
In order to achieve the existing ALB not being deleted with group.name annotation enabled, we need to meet following conditions:
ALB should be tagged with below 3 tags:
alb.ingress.kubernetes.io/group.name: test-alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: instance
Create a dummy ingress with the same group name with the below manifest.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-nginx-rule
namespace: test
annotations:
alb.ingress.kubernetes.io/group.name: test-alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
alb.ingress.kubernetes.io/healthcheck-path: /index.html
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/security-groups: eks-test-alb-sg
spec:
ingressClassName: alb
rules:
- host: dummy.eks.abc.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: test-svc
port:
number: 5005
After deploying the above manifest, an ingress will be created using the same ALB and listener will have rule of if host is dummy.eks.abc.com, it will return 443. It's create and forget type of manifest, so after creating this ingress, even after we delete all the running deployment services (except the dummy manifest file above), the ALB will remain.

AWS EKS configure HTTPS listener

I want to secure my web service running on Kubernetes (EKS). It is running on port 80 .I want to run this on port 443.
When I apply the YAML file (for service and ingress), on AWS console I still have it listening on port 80 (and not on 443):
This is my YAML file:
How can I let it works? Thanks for you time!
#SERVICE LOGGER
apiVersion: v1
kind: Service
metadata:
name: load-balancer-api-logger
namespace: servicename-core-ns
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-central-1:786543355018:certificate/acdff29d4-7a32-42f1-8f11-1d4f495a5c77
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
service.beta.kubernetes.io/force-ssl-redirect: "true"
spec:
selector:
app: api-logger
type: NodePort
ports:
- protocol: TCP
port: 443
targetPort: 5000
selector:
app.kubernetes.io/name: api-logger
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-articor
namespace: servicename-core-ns
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: instance
alb.ingress.kubernetes.io/healthcheck-path: "/healthcheckep"
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
alb.ingress.kubernetes.io/ssl-redirect: '443'
spec:
rules:
- host: logger.domainname.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: load-balancer-api-logger
port:
number: 80
Please consider that if I try to manually set the ALB to work with HTTPS it works fine. What I'm trying to achive here is to configure it via YAML file.
You should configure all settings in Ingress object. The following spec also don't repeat the default value set by the controller:
apiVersion: v1
kind: Service
metadata:
name: load-balancer-api-logger
namespace: servicename-core-ns
spec:
selector:
app: api-logger
type: NodePort
ports:
- protocol: TCP
port: 443
targetPort: 5000
selector:
app.kubernetes.io/name: api-logger
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-articor
namespace: servicename-core-ns
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: "/healthcheckep"
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:786543355018:certificate/acdff29d4-7a32-42f1-8f11-1d4f495a5c77
spec:
rules:
- host: logger.domainname.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: load-balancer-api-logger
port:
number: 443

Setting up a gRPC server with. AWS Load Balancer and Ingress

I'm working on a side project, and trying to deploy a simple Hello, World! gRPC application on K8s with ALB. I'm having issues reaching my deployed container.
My deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-grpc-service
labels:
app: sample-grpc-service
spec:
replicas: 1
selector:
matchLabels:
app: sample-grpc-service
template:
metadata:
labels:
app: sample-grpc-service
spec:
containers:
- name: sample-grpc-service
image: samplegrpcservice
ports:
- containerPort: 50051
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 200m
memory: 512Mi
My service.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-grpc-service
spec:
type: NodePort
selector:
app: sample-grpc-service
ports:
- name: sample-grpc-service
protocol: TCP
port: 50051
targetPort: 50051
My ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: "sample-grpc-service-ingress"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
alb.ingress.kubernetes.io/inbound-cidrs: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=120
alb.ingress.kubernetes.io/backend-protocol-version: GRPC
alb.ingress.kubernetes.io/healthcheck-path: /
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/success-codes: '12'
labels:
app: sample-grpc-private-ingress
spec:
rules:
- host: sample-grpc-service.my-domain.com
http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: "sample-grpc-service"
servicePort: 50051
I've followed the guides here and here, and the error I'm getting on the client's side is
_InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses"
debug_error_string = "{"created":"#1637251095.787769000","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3159,"referenced_errors":[{"created":"#1637251095.787768000","description":"failed to connect to all addresses","file":"src/core/lib/transport/error_utils.cc","file_line":147,"grpc_status":14}]}"
Which I'm guessing means it can't find the host address. When running shell on the running remote container I see that my application is up. When running ipython locally on the container I'm able to talk to the gRPC endpoints with localhost, so I know someone there is listening...
I've looked in AWS console and the Route53 is in place, I also see the ALB, but the target group is acting weird.. First, the health-check status code is 200 instead of 12, and all it's monitored instances are showing as unhealthy...
Any thoughts, comments, or suggestions are most welcome!

AWS EKS Fargate Ingress Has No Address

Updated
So, I followed the AWS docs on how to setup an EKS cluster with Fargate using the eksctl tool. That all went smoothly but when I get to the part where I deploy my actual app, I get no endpoints and the ingress controller has no address associated with it. As seen here:
NAME HOSTS ADDRESS PORTS AGE
testapp-ingress * 80 129m
So, I can't hit it externally. But the test app (2048 game) had an address from the elb associated with the ingress. I thought it might be the subnet-tags as suggested here and my subnets weren't tagged the right way so I tagged them the way suggested in that article. Still no luck.
This is the initial article I followed to get set up. I've performed all the steps and only hit a wall with the alb: https://docs.aws.amazon.com/eks/latest/userguide/fargate-getting-started.html#fargate-gs-next-steps
This is the alb article I've followed: https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html
I followed the steps to deploy the sample app 2048 and that works just fine. I've made my configs very similar and it should work. I've followed all of the steps. Here are my old configs, new config below:
deployment yaml>>>
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "testapp-deployment"
namespace: "testapp-qa"
spec:
selector:
matchLabels:
app: "testapp"
replicas: 5
template:
metadata:
labels:
app: "testapp"
spec:
containers:
- image: xxxxxxxxxxxxxxxxxxxxxxxxtestapp:latest
imagePullPolicy: Always
name: "testapp"
ports:
- containerPort: 80
---
service yaml>>>
apiVersion: v1
kind: Service
metadata:
name: "testapp-service"
namespace: "testapp-qa"
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
type: NodePort
selector:
app: "testapp"
---
ingress yaml >>>
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "testapp-ingress"
namespace: "testapp-qa"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
labels:
app: testapp-ingress
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: "testapp-service"
servicePort: 80
---
namespace yaml>>>
apiVersion: v1
kind: Namespace
metadata:
name: "testapp-qa"
Here are some of the logs from the ingress controller>>
E0316 22:32:39.776535 1 controller.go:217] kubebuilder/controller "msg"="Reconciler error" "error"="failed to reconcile targetGroups due to failed to reconcile targetGroup targets due to Unable to DescribeInstanceStatus on fargate-ip-xxxxxxxxxxxx.ec2.internal: InvalidInstanceID.Malformed: Invalid id: \"fargate-ip-xxxxxxxxxxxx.ec2.internal\"\n\tstatus code: 400, request id: xxxxxxxxxxxx" "controller"="alb-ingress-controller" "request"={"Namespace":"testapp-qa","Name":"testapp-ingress"}
E0316 22:36:28.222391 1 controller.go:217] kubebuilder/controller "msg"="Reconciler error" "error"="failed to reconcile targetGroups due to failed to reconcile targetGroup targets due to Unable to DescribeInstanceStatus on fargate-ip-xxxxxxxxxxxx.ec2.internal: InvalidInstanceID.Malformed: Invalid id: \"fargate-ip-xxxxxxxxxxxx.ec2.internal\"\n\tstatus code: 400, request id: xxxxxxxxxxxx" "controller"="alb-ingress-controller" "request"={"Namespace":"testapp-qa","Name":"testapp-ingress"}
Per the suggestion in the comments from #Michael Hausenblas, I've added an annotation to my service for the alb ingress.
Now that my ingress controller is using the correct ELB, I checked the logs because I still can't hit my app's /healthcheck. The logs:
E0317 16:00:45.643937 1 controller.go:217] kubebuilder/controller "msg"="Reconciler error" "error"="failed to reconcile targetGroups due to failed to reconcile targetGroup targets due to Unable to DescribeInstanceStatus on fargate-ip-xxxxxxxxxxx.ec2.internal: InvalidInstanceID.Malformed: Invalid id: \"fargate-ip-xxxxxxxxxxx.ec2.internal\"\n\tstatus code: 400, request id: xxxxxxxxxxx-3a7d-4794-95fb-a18835abe0d3" "controller"="alb-ingress-controller" "request"={"Namespace":"testapp-qa","Name":"testapp"}
I0317 16:00:47.868939 1 rules.go:82] testapp-qa/testapp-ingress: modifying rule 1 on arn:aws:elasticloadbalancing:us-east-1:xxxxxxxxxxx:listener/app/xxxxxxxxxxx-testappqa-testappin-b879/xxxxxxxxxxx/6b41c0d3ce97ae6b
I0317 16:00:47.890674 1 rules.go:98] testapp-qa/testapp-ingress: rule 1 modified with conditions [{ Field: "path-pattern", Values: ["/*"] }]
Update
I've updated my config. I don't have any more errors but still unable to hit my endpoints to test if my app is accepting traffic. It might have something to do with fargate or on the AWS side I'm not seeing. Here's my updated config:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: "testapp"
namespace: "testapp-qa"
spec:
selector:
matchLabels:
app: "testapp"
replicas: 5
template:
metadata:
labels:
app: "testapp"
spec:
containers:
- image: 673312057223.dkr.ecr.us-east-1.amazonaws.com/wood-testapp:latest
imagePullPolicy: Always
name: "testapp"
ports:
- containerPort: 9898
---
apiVersion: v1
kind: Service
metadata:
name: "testapp"
namespace: "testapp-qa"
annotations:
alb.ingress.kubernetes.io/target-type: ip
spec:
ports:
- port: 80
targetPort: 9898
protocol: TCP
name: http
type: NodePort
selector:
app: "testapp"
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "testapp-ingress"
namespace: "testapp-qa"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/healthcheck-path: /healthcheck
labels:
app: testapp
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: "testapp"
servicePort: 80
---
apiVersion: v1
kind: Namespace
metadata:
name: "testapp-qa"
In your service, try adding the following annotation:
annotations:
alb.ingress.kubernetes.io/target-type: ip
And also you'd need to explicitly tell the Ingress resource via the alb.ingress.kubernetes.io/healthcheck-path annotation where/how to perform the health checks for the target group. See the ALB Ingress controller docs for the annotation semantics.

Unable to create ingress and load balancer in k8s

I have created one load balancer service using the following configuration:-
apiVersion: v1
kind: Service
metadata:
name: dealer-service-elb
namespace: staging
labels:
service: dealer-service-elb
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
spec:
type: LoadBalancer
selector:
service: dealer-service
ports:
- name: 'http'
port: 80
targetPort: 3000
protocol: 'TCP'
and my aws alb looks like this:-
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dealer-service-ingress
labels:
app: dealer-service
namespace: staging
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/healthcheck-path: /dealers-service/v1/health
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: dealer-service
servicePort: 80
But when I checked my ingress using kubectl command:-
I did not find my ingress url:-
NAME HOSTS ADDRESS PORTS AGE
dealer-service-ingress * 80 34m