Background:
kubectlversion- 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.
