我正在尝试在Google Cloud上的kubernetes中运行一个非常简单的UDP服务,但我无法访问我正在暴露给互联网的端口。 这是部署和服务文件:
Deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: udp-server-deployment
spec:
replicas: 2
template:
metadata:
labels:
name: udp-server
spec:
containers:
- name: udp-server
image: jpoon/udp-server
imagePullPolicy: Always
ports:
- containerPort: 10001
protocol: UDP
Service.yaml:
apiVersion: v1
kind: Service
metadata:
name: udp-server-service
labels:
app: udp-server
spec:
type: LoadBalancer
ports:
- port: 10001
protocol: UDP
selector:
name: udp-server
这会在Google Cloud中创建负载均衡器,并显示正确的端口。像这样:
但是当我尝试访问该端口时,它是无法访问的。我在GCE中尝试了一些变体来暴露udp端口,但似乎没有任何工作。
➜ udp-example telnet 35.192.59.72 10001
Trying 35.192.59.72...
telnet: connect to address 35.192.59.72: Connection refused
telnet: Unable to connect to remote host
答案 0 :(得分:0)
我试图复制这个问题,我认为这是由于kubernetes配置失败但你是如何尝试测试以及可能缺少防火墙规则引起的。
首先考虑使用host:port
打开与目标telnet
的连接将始终失败,因为您使用的协议是UDP而不是TCP,因此即使服务器也不会创建连接正在运行。并记住创建相应的防火墙规则以确保允许流量。
我去检查go server和go client的源图像,我带了他们的go
源代码,他们正在使用localhost,但他们没有运行客户端在另一个实例上并以负载均衡器为目标。
因此,为了理解是否kubernetes失败,我试图使用nginx图像和TCP完全相同的yaml文件,一切正常。
在同一个GitHub页面中,有一个包含该行的服务器的Dockerfile示例:
# Expose your port
EXPOSE 61243
因此我将ssh放入容器(注意ash
而不是bash
)以了解实际发生的情况以及它正在侦听的服务器端口以及Docker公开的端口
kubectl exec -it udp-server-deployment-8306694-zq412 -- /bin/ash
但请记住:
EXPOSE指令实际上并不发布端口。它在构建映像的人和运行容器的人之间起到一种文档的作用,关于哪些端口要发布。
一旦我进入容器,我就运行了以下输出的客户端,同时定位本地主机和负载均衡器IP:
/go/src/udp # go run client.go
SERVER_ADDRESS=
ServerAddr=:10001
Received udp-server-deployment-8306694-zq412 from 127.0.0.1:10001
提到服务器正常工作。
从Cloud Shell连接客户端无法正常工作,因为防火墙规则不适用于此(我的错误)。
要测试它是否正常工作旋转实例,安装go,运行客户端并检查它是否正常工作。
curl -O https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz
tar xvf go1.7.4.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
vi client.go
/usr/local/go/bin/go run client.go
这是client.go的内容:
package main
import (
"fmt"
"net"
"strconv"
"time"
)
func checkError(err error) {
if err != nil {
fmt.Println("Error: ", err)
}
}
func main() {
Server := "[LOAD BALANCER IP]"
fmt.Println("SERVER_ADDRESS=" + Server)
serverAddr, err := net.ResolveUDPAddr("udp", Server+":10001")
fmt.Println("ServerAddr=" + serverAddr.String())
checkError(err)
conn, err := net.DialUDP("udp", nil, serverAddr)
checkError(err)
defer conn.Close()
buf := make([]byte, 1024)
i := 0
for {
msg := strconv.Itoa(i)
fmt.Fprintf(conn, msg)
i++
n, addr, err := conn.ReadFromUDP(buf)
fmt.Println("Received ", string(buf[0:n]), " from ", addr)
if err != nil {
fmt.Println("Error: ", err)
}
time.Sleep(time.Second * 1)
}
}
请注意,您必须将[LOAD BALANCER IP]
场所替换为您的值。