結論
素直に諦めて別のやり方に切り替えました.なので,難しいと思います.
やろうとしたこと
KubernetesにデプロイしたDockerコンテナ同士でUDPブロードキャストパケットをやり取りして研究の検証をしようとしていました.
上手くいかないところ
コンテナからホストOSへはUDPブロードキャストパケットは到達していました.コンテナからコンテナが到達できない状況でした.
調べたこと
以下の記事にKubernetesの設計的に難しいとの記述がありました.
UDP broadcast fails between pods · Issue #1063 · kubernetes-sigs/kind
the pods in fact schedule on different nodes. I don't think it's expected in Kubernetes's network model that you can broadcast between pods like this.
ソースコード/マニフェスト
以下を使って試していました.
agent.go
package main
import (
"bytes"
"log"
"math/rand"
"net"
"os"
"strconv"
"time"
)
func reciever() {
pc, err := net.ListenPacket("udp4", ":7531")
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 1024)
old_buf := make([]byte, 1024)
for {
n, addr, err := pc.ReadFrom(buf)
if err != nil {
log.Fatal(err)
break
}
if bytes.Equal(buf, old_buf) {
continue
} else {
log.Printf("recv: %20s\t%s\n", addr, buf[:n])
old_buf = buf[:n]
}
}
defer pc.Close()
}
func sender() {
// Listening
pc, err := net.ListenPacket("udp4", ":7532")
if err != nil {
log.Fatal(err)
}
defer pc.Close()
// Setup for sending
addr, err := net.ResolveUDPAddr("udp4", "192.168.0.255:7531")
if err != nil {
log.Fatal(err)
}
for {
// wait for listening
time.Sleep(time.Second * 2)
// create payload
random_num := strconv.Itoa(rand.Intn(1000))
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown"
}
// send
my_payload := "hoge " + random_num
_, err = pc.WriteTo([]byte(my_payload), addr)
if err != nil {
log.Fatal(err)
}
log.Printf("sent: %20s\t%s\n", hostname, my_payload)
}
}
func main() {
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown"
}
log.Println(hostname, "starting agent")
go sender()
log.Println(hostname, "sending finish")
reciever()
}
FROM golang:rc
EXPOSE 7531
ADD agent.go /work/
WORKDIR /work/
CMD go run agent.go
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-dep
labels:
ser: agent
spec:
replicas: 3
selector:
matchLabels:
app: agent
template:
metadata:
labels:
app: agent
spec:
containers:
- name: my-agent
image: tomoyk/agent:v0.18
ports:
- containerPort: 7531
---
apiVersion: v1
kind: Service
metadata:
name: agent-ser
spec:
type: ClusterIP
externalIPs:
- 192.168.0.6
ports:
- name: "agent-port"
protocol: "UDP"
port: 7531
targetPort: 7531
selector:
ser: agent
対処方法
- UDPブロードキャストをやめる
- hostネットワークにコンテナを直接差す
- Kubernetesに変更を加える
検証環境
- Docker for Windows 2.3.0.3
- K3s v1.18.3+k3s1