0

I'm having trouble accessing my K8S service...

I'm running the service in K3D on an ec2 instance in AWS. I have deployed a simple HTTP rest API to this and I want to access it via a browser. I have a security group that allows internet traffic ingress on port 8080 (and a bunch of other ports).

Here are the important bits of my K3D config:

apiVersion: k3d.io/v1alpha2
kind: Simple
name: lab
servers: 1
agents: 3
image: rancher/k3s:v1.20.4-k3s1
ports:
  - port: 6443:6443
    nodeFilters:
      - server[0]
  - port: 8080:80
    nodeFilters:
      - loadbalancer
  - port: 8443:443
    nodeFilters:
      - loadbalancer
  - port: 30000:32500
    nodeFilters:
      - loadbalancer
options:
  k3d:
    disableLoadbalancer: false
  k3s:
    extraServerArgs:
      - --no-deploy=traefik

And, I start my cluster with this command

k3d cluster create --config k3d-config.yaml

This configuration routes inbound traffic on the host's port 8080 to port 80 on the loadbalancer container (and configures other routes too). The output of docker ps shows this config seems correct (as does other testing):

CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS
a299613b8229        rancher/k3d-proxy:v4.4.0   "/bin/sh -c nginx-pr…"   33 minutes ago      Up 32 minutes       0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp, 0.0.0.0:38713->6443/tcp, 0.0.0.0:30000->32500/tcp   k3d-lab-serverlb

I'm using nginx ingress, rather than the default traefik ingress. My nginx ingress is deployed with a bare-metal configuration (from the github project) with the following change:

nginx-ingress-deploy.yaml

spec:
  type: LoadBalancer
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https

This exposes the ingress controller on port 80 on the load-balancer, allowing me to hit port 80 on the load-balancer node and have it routed to the ingress controller, which will in turn route traffic on layer-7 according to the ingress configuration of my services. At least, I think that's what it is doing.

Finally, I have a service, configured with the following service and ingress yaml:

apiVersion: v1
kind: Service
metadata:
  name: corpora
  namespace: corpora
spec:
  type: ClusterIP
  selector:
    app: corpora
  ports:
    - port: 80
      targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: corpora
  namespace: corpora
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
        - path:  /corpora(/|$)(.*)
          backend:
            serviceName: corpora
            servicePort: 80

This should set up the service on port 80 with an ingress controller that routes /corpora to it.

This is all good. I can look at my corpora ingress controller and I get this beauty:

NAME      CLASS    HOSTS   ADDRESS        PORTS   AGE
corpora   <none>   *       192.168.16.4   80      42m

So, when I:

curl http://192.168.16.4/corpora

I get the expected result.

All good and well -- everything works. Except it doesn't. I still can't access this in a browser. When I go to `http://:8080/corpora I get no response (where public-ip is the public IP address of the ec2 instance). Trying this using curl:

$ curl -v http://<public-ip>:8080/corpora
*   Trying 35.179.93.189:8080...
* TCP_NODELAY set
* Connected to 35.179.93.189 (35.179.93.189) port 8080 (#0)
> GET /corpora HTTP/1.1
> Host: 35.179.93.189:8080
> User-Agent: curl/7.68.0
> Accept: */*
>
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

My terraform configuration opens the security-group up to port 8080 like this:

variable "ports" {
  type = list(any)
  default = [
    { from = 22, to = 22 },
    { from = 80, to = 80 },
    { from = 8080, to = 8080 },
    { from = 443, to = 443 },
    { from = 8443, to = 8443 },
    { from = 30000, to = 32767 }
  ]
}

resource "aws_security_group" "k3d" {
  vpc_id = var.vpc.id
  tags   = module.tags.tags

  dynamic "ingress" {
    for_each = var.ports
    content {
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      from_port   = ingress.value.from
      to_port     = ingress.value.to
    }
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

I do have the sg open for this port, and docker shows that 8080 is mapped to 80 on the internal lb, so I've no idea what's happening. I don't get a response if I curl localhost:8080 either.

I have the code for all of this on github if anyone wants to take a look. It's in the 'config' branch. It's all configured via make. There are directories to build the ami with packer, build the infra with terraform, log onto the machine, run k3d, install ingress, and run the sample app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.