Home > Back-end >  "301 Moved Permanently" when trying to curl a local k8s service
"301 Moved Permanently" when trying to curl a local k8s service

Time:07-26

Background:

  • kubectl version- 1.24
  • Docker version- 20.10.17
  • MacOS Monterey v12.4

Question:

I'm following this tutorial, trying to set up a local k8s deployment service. I successfully ran the following commands:

$ kubectl config use-context docker-desktop
Switched to context "docker-desktop".

$ kubectl get nodes
NAME             STATUS   ROLES           AGE    VERSION
docker-desktop   Ready    control-plane   154m   v1.24.1

$ kubectl create deployment simple-webapp \
  --image training/webapp \
  --replicas=2 \
  --port=5000
deployment.apps/simple-webapp created

$ kubectl get deployments
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
simple-webapp   2/2     2            2           3m23s

$ kubectl create service loadbalancer simple-webapp \
  --tcp=80:5000
service/simple-webapp created

$ kubectl get services
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1       <none>        443/TCP        156m
simple-webapp   LoadBalancer   10.109.168.49   <pending>     80:30582/TCP   9m34s

However, when I try to run curl http://localhost as mentioned in the tutorial, instead of getting the expected output (Hello world!), I get:

<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.21.2</center>
</body>
</html>

I'm brand-new to k8s and have no idea where to start diagnosing the problem. Not sure if this is useful info, but I ran docker ps and it looks like there are two k8s-related docker containers currently running:

$ docker ps
CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS          PORTS     NAMES
411b7110b315   training/webapp   "python app.py"   11 minutes ago   Up 11 minutes             k8s_webapp_simple-webapp-5d47556b5-jkvsc_default_9893ef1a-4bc5-43f3-80ac-151d567a89f6_0
9752c12315cc   training/webapp   "python app.py"   11 minutes ago   Up 11 minutes             k8s_webapp_simple-webapp-5d47556b5-269s8_default_5c50b3f8-57a9-4066-bd66-498cd30c758c_0

I do see nginx referenced in the curl output, does this mean that the 301 redirect is coming from inside the training/webapp process from the Docker container? If so, how would I fix this?

EDIT: I tried creating both the deployment and service on a different port (5001 instead of 5000), since when I followed part 1 of the tutorial I ran into problems with port 5000 already being in use. That worked for part 1 of the tutorial, however unfortunately it didn't solve my problem for part 2- I ran into the same 301 redirect problem when using both port 5000 and 5001.

EDIT 2: When I run kubectl get pods, I see the following:

$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
simple-webapp-5d47556b5-sg9h4   1/1     Running   0          32s
simple-webapp-5d47556b5-xw2nh   1/1     Running   0          32s

I continue to see the 301 redirect even after running curl to confirm the pods are up.

EDIT 3: I do notice that when I run kubectl get nodes, the single node has a role of control-plane, not control-plane,master as noted in the tutorial. I also notice that running kubectl get services shows that the EXTERNAL-IP of the loadbalancer is pending, not localhost as expected from the tutorial. Are either of these facts relevant?

EDIT 4: Further down in the tutorial, we delete both the deployment and service that were previously created, and we re-create them using deployment.yml and service.yml files, alongside the commands kubectl apply -f deployment.yml and kubectl apply -f service.yml. When I copy/paste the YAML from the tutorial into new files with the specified filenames, I get the same 301 Redirect error.

EDIT 5: In this Hacker News comment thread, I saw that Kubernetes had removed support for Docker as of v1.24. I had previously upgraded my kubectl Homebrew version to 1.24 because my prior version didn't support the --replicas flag. When I read this thread, I downgraded to v1.22 (the previous version), verified the version was correct via kubectl version, deleted/recreated the previously-created deployment and service, and tried curl again. I still get the 301 redirect error.

EDIT 6: Here's the full output of curl -v http://localhost:

curl -v http://localhost 
*   Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.21.2
< Date: Mon, 25 Jul 2022 04:53:40 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
< Location: https://localhost/
< 
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.21.2</center>
</body>
</html>
* Connection #0 to host localhost left intact

Looks like it's trying to redirect from http to https? Could this be some setting within the training/webapp Docker image?

Also, here's the result of sudo lsof -i -P | grep LISTEN | grep :80:

$ sudo lsof -i -P | grep LISTEN | grep :80
nginx     3582   richiethomas    6u  IPv4 0x63a69bc74912e747      0t0    TCP *:80 (LISTEN)
nginx     3582   richiethomas    7u  IPv6 0x63a69bbdb3ebcbe7      0t0    TCP *:80 (LISTEN)
nginx     3701   richiethomas    6u  IPv4 0x63a69bc74912e747      0t0    TCP *:80 (LISTEN)
nginx     3701   richiethomas    7u  IPv6 0x63a69bbdb3ebcbe7      0t0    TCP *:80 (LISTEN)

CodePudding user response:

You should be able to access the service using http://nodename/nodeip:30581

simple-webapp   LoadBalancer   10.109.168.49   <pending>     80:30582/TCP   9m34s

Note; Change the service type to NodePort from Loadbalancer. Loadbalancer only works on cloud providers like AWS, Azure etc.

CodePudding user response:

It looks like you already have nginx running on port 80(and 443) on your system. Likely, another docker container outside kubernetes, or directly on your system. It already has taken port 80, hence your LoadBalancer is in pending state.

Either stop that nginx service or use another port like 8080 for your LoadBalancer:

$ kubectl create service loadbalancer simple-webapp \
       --tcp=8080:5000

The training/webapp does not use nginx.

  • Related