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.