目录
一、前端页面显示 503 Service Temporarily Unavailable
时间:2023-04-19 k8s 版本:v1.18.4
问题背景
Kubernetes 中的前端项目 Pod 运行正常,但访问通过 Ingress 代理的域名时页面出现“503 Service Temporarily Unavailable”的错误,查看 log 日志也无报错信息。
解决方案
我最初是 service.yaml 和 ingress.yaml 里的 name 名称为 gtp,然后我又修改为 gpt,在修改前没 kubectl delete 原来的资源,当我删除原来的为 gtp 名称的 ingress 和 service 资源后,前端页面就可以正常访问了。
原理
问题出在修改资源名称时未删除旧资源。当我将名称从 gtp
修改为 gpt
时,应该首先使用 kubectl delete
删除旧的资源(即原先的 Ingress 和 Service),然后再应用新的资源配置。如果没有删除旧资源,可能会导致以下问题:
-
Ingress 混淆:如果旧的 Ingress 和新的 Ingress 都存在,它们可能会争夺同一个域名和路径。这可能导致 Ingress 控制器在处理请求时混淆,从而选择错误的后端服务。当你删除了旧的 Ingress 资源后,Ingress 控制器开始将流量正确路由到新的后端服务。
-
后端服务冲突:类似地,如果旧的 Service 和新的 Service 都存在且监听相同的端口,可能会导致端口冲突或 Kubernetes 无法正确将流量路由到预期的后端服务。删除旧的 Service 资源后,Ingress 控制器可以将流量路由到正确的后端服务。
总之,当你修改资源名称时,务必确保先删除旧资源,以避免出现混淆和冲突。在应用新的资源配置之前,使用 kubectl delete
删除旧资源,然后再使用 kubectl apply
应用新资源配置。这样可以确保 Ingress 控制器将流量正确路由到新的后端服务。
二、Dockfile 构建镜像失败:When using COPY with more than one source file, the destination must be a directory and end with a /
问题背景
COPY 根据通配符 * 匹配到多个多个文件,所以语法错误,镜像构建不成功,push 到镜像仓库失败。
解决方案
在 COPY 最后面加个 / 即可。
原理
COPY
指令的语法是 COPY <src> <dest>
,其中 <src>
是要复制的源文件或目录,<dest>
是目标路径。在这个例子中,.
表示当前目录,所以 COPY . .
的含义是将构建上下文的当前目录中的所有文件和目录复制到容器的工作目录(由 WORKDIR
指令设置)。
与 COPY target/*.jar .
有以下几点区别:
-
COPY . .
是将整个构建上下文的当前目录的内容复制到容器的工作目录。而COPY target/*.jar .
仅复制target
目录下所有的.jar
文件到容器的工作目录。 -
COPY . .
不需要指定目标路径以/
结尾,因为它是在将整个目录复制到另一个目录。而COPY target/*.jar .
复制多个文件时需要以/
结尾,表示目标是一个目录。
使用哪种 COPY
取决于您的需求。如果您需要将整个构建上下文的所有文件复制到容器中,可以使用 COPY . .
。如果您只需要复制特定的文件或目录,可以使用类似 COPY target/*.jar .
的语法。
三、前端页面显示 502 Bad Gateway
时间:2023-08-3 k8s 版本:v1.25.4
问题背景
新建了个 service 资源类型为 nodePort 后端指定一组 pod 标签,service 创建成功;使用 Nginx 代理了这个 nodePort 端口使外部可以访问,结果访问前端页面显示 502 Bad Gateway。
解决方案
1. 查看 Nginx 错误日志:
2023/08/03 15:01:52 [error] 29229#29229: *1116307 connect() failed (111: Connection refused) while connecting to upstream, client: 10.22.11.237, server: valetorder.xxx.com, request: "GET / HTTP/1.1", upstream: "http://10.0.4.173:31193/", host: "valetorder.uat.dusto-yc.com"
2023/08/03 15:01:52 [error] 29229#29229: *1116307 connect() failed (111: Connection refused) while connecting to upstream, client: 10.22.11.237, server: valetorder.xxx.com, request: "GET / HTTP/1.1", upstream: "http://10.0.4.172:31193/", host: "valetorder.uat.dusto-yc.com"
初步排查是否后端服务器(upstream)正常运行,并且监听了配置文件中指定的端口(例如:31193)
2. 查看后端 pod 的运行状态
是 running 状态,无异常
3. 判断 service 与指定的 pod 是否关联了
[root@idc-master-01 yaml]# kubectl describe svc -n uat valet-order-uat-out
Name: valet-order-uat-out
Namespace: uat
Labels: app.kubernetes.io/name=valet-order-uat
io.cattle.field/appId=valet-order-uat
Annotations: <none>
Selector: app=valet-order-uat
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.102.177.78
IPs: 10.102.177.78
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 31193/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
[root@idc-master-01 yaml]# kubectl get pods --selector app=valet-order-uat -n uat
No resources found in uat namespace.
Endpoints 为空且查找不到有 app=valet-order-uat 标签的 pod,那就是 service 资源有问题。
4. 修改 service 资源中的 selector 字段的值
指定 pod 资源文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: valet-order-uat
vvv: 1.0.1
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/name: valet-order-uat
我在 service 中的 selector 选择了 app: valet-order-uat 标签,导致没有匹配到,改为 app.kubernetes.io/name: valet-order-uat 即可。
最终页面成功访问。
原理
上面 Pod 资源中的 spec.selector.matchLabels
使用的是一个复合标签,即 app.kubernetes.io/name: valet-order-uat
。而在 Service 资源中的 selector
使用的是简单的单个标签 app: valet-order-uat
。
由于标签的匹配规则是精确匹配,所以 Service 的 selector
并不会与 Pod 资源的 spec.selector.matchLabels
完全匹配。因此,Service 将不会与该 Pod 直接关联,且不会将流量导向该 Pod。
当 Pod 资源中的 metadata.labels
和 spec.selector.matchLabels
同时打了不同的标签,Service 将只会根据 spec.selector.matchLabels
来选择与之关联的 Pod。
在 Kubernetes 中,Service 的 selector
字段用于选择与之关联的 Pod。selector
字段包含一个标签键值对的 map,其中定义了 Service 要选择哪些标签的 Pod 与之关联。而 Pod 的 metadata.labels
字段是用来标识 Pod 的特性和属性的标签。
当 Service 创建或更新时,它会根据 spec.selector.matchLabels
字段的标签键值对来选择与之匹配的 Pod。Pod 的 metadata.labels
字段中的标签不会影响这个选择过程。
文章评论