部署本地K8s服务时curl返回301 Moved Permanently问题求助
背景
kubectl版本:1.24- Docker版本:20.10.17
- 操作系统:MacOS Monterey v12.4
问题详情
按照教程搭建本地K8s部署与服务,已完成以下操作:
$ 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
执行curl http://localhost未得到预期的Hello world!,返回:
<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>
docker ps显示两个容器运行正常:
$ 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
curl -v http://localhost发现请求被重定向至https://localhost/,sudo lsof -i -P | grep LISTEN | grep :80显示本地nginx监听80端口。
已尝试操作
- 改用端口5001创建部署与服务,仍出现301错误
- 确认Pods运行正常,问题依旧
- 发现节点角色为
control-plane而非教程中的control-plane,master,LoadBalancer的EXTERNAL-IP为<pending>,不确定是否相关 - 使用教程中的YAML文件重新创建部署与服务,问题未解决
- 将kubectl降级至v1.22,重新操作后仍出现301错误
排查与解决步骤
定位端口占用问题
本地80端口被nginx占用,导致curl http://localhost访问的是本地nginx服务,而非K8s部署的simple-webapp。通过NodePort访问K8s服务
从kubectl get services结果可知,服务的NodePort为30582,直接访问该端口即可:curl http://localhost:30582此方式可绕过本地80端口的占用问题,直接访问K8s服务。
验证容器内服务状态
进入任意Pod,测试容器内服务是否正常响应:kubectl exec -it simple-webapp-5d47556b5-jkvsc -- curl http://localhost:5000若返回
Hello world!,说明容器内服务正常,问题仅出在外部访问的端口映射环节。解决本地80端口占用(可选)
若希望通过80端口访问K8s服务,可停止本地nginx服务,或修改K8s服务的端口映射:kubectl delete service simple-webapp kubectl create service loadbalancer simple-webapp --tcp=8080:5000之后访问
http://localhost:8080即可。关于EXTERNAL-IP
的说明
Docker Desktop在Mac环境下,LoadBalancer类型的服务不会分配EXTERNAL-IP,默认通过NodePort方式暴露服务,因此无需纠结该状态,直接使用NodePort访问即可。
内容的提问来源于stack exchange,提问作者Richie Thomas

