我正在使用 Kubernetes 和 Docker 运行一个 dotnet core 应用程序。
设置如下:
APP
在 dotnet core 应用程序中,我通过在 Program.cs 中设置以下内容让 Kestrel 服务器侦听端口 8080:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel(options =>
{
options.Listen(IPAddress.Loopback, 8080);
})
.Build();
我已经在本地测试了应用程序构建,端点按预期工作
localhost:8080/api/test
。
Docker 镜像
在 Dockerfile 中我有以下内容:
EXPOSE 8080
我理解这意味着容器是使用暴露的 8080 端口构建的。
问题1:……这是否一定意味着容器的8080映射到应用程序的8080?如果没有,我该如何映射它?
库伯内特斯(MINIKUBE)
在 Kubernetes 中(在 Minikube 上本地运行),然后我使用复制控制器创建 3 个 pod,每个 pod 包含 1 个带有应用程序的 docker 容器。我的 RC 文件如下所示:
{
"apiVersion": "v1",
"kind": "ReplicationController",
"spec": {
"replicas": 3,
"selector": {
"app": "myApp"
},
"template": {
"metadata": {
"labels": {
"app": "myApp"
}
},
"spec": {
"containers": [
{
"name": "my-app",
"image": "myname/myapp:1.0",
"ports": [
{
"containerPort": 8080
}
]
}
]
}
}
}
}
注意
"ports": [{ "containerPort": 8080 }]
。按照我的理解,这意味着我要暴露的容器端口是8080。
然后我有一个 Kubernetes 服务,它通过端点公开我的 3 个 Pod 的 8080 端口
[minikubeIPAddress]:30001
:
{
"apiVersion": "v1",
"kind": "Service",
"spec": {
"type": "NodePort",
"ports": [
{
"port": 8080,
"nodePort": 30001,
"protocol": "TCP"
}
],
"selector": {
"app": "myApp"
}
}
}
当我尝试到达端点时
[minikubeIPAddress]:30001/api/test
我收到“无法访问站点”错误。
今天早上我使用默认 HTTP 端口 80 时它可以正常工作。 唯一所做的更改是端口号。
问题 2:...我在这里错过了什么吗?这里是否有一个连接仍映射到默认端口 80?
任何帮助将不胜感激。
使用“targetPort”来指示您的 pod 正在侦听哪个端口。你的 yaml 规范应该是这样的:
---
apiVersion: v1
kind: Service
metadata:
name: myApp
spec:
selector:
app: myApp
ports:
- name: http
port: 8080
targetPort: 8080
nodePort: 30001
经过多次尝试和错误,我找到了解决方案。
根据 @johnharris85 和 @Yuankun 所说的关于需要将 IP 地址设置为“任意”而不是本地主机的内容,我找到了这篇文章:http://blog.scottlogic.com/2016/09/05 /hosting-netcore-on-linux-with-docker.html
dotnet core 应用程序默认使用本地主机网络,并且在测试机器上本地运行时,效果很好。但是,在 Docker 容器内运行 dotnet 应用程序意味着本地主机网络仅限于容器内。
为了解决这个问题,我最初改变了
options.Listen(IPAddress.Loopback, 8080);
到
options.Listen(IPAddress.Any, 8080);
但是,我在本地进行了测试,无法让应用程序做出响应。我认为这意味着这不是一个有效的解决方案。 如果我使用容器化应用程序对其进行了测试,这可能是一个有效的解决方案。
然后我看到了上述文章,并决定尝试以下方法:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://*:8080")
.Build();
这解决了我的问题,现在我的应用程序可以通过 Kubernetes 端点访问。
感谢所有提供建议的人。
@JMadelaine 非常感谢您的分享!几天后这救了我。我已经放弃了。