1. tomoyk

    Posted

    tomoyk
Changes in title
+Kubernetes上のコンテナ間でUDPブロードキャストを諦めた
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,169 @@
+# 結論
+
+素直に諦めて別のやり方に切り替えました.なので,難しいと思います.
+
+# やろうとしたこと
+
+KubernetesにデプロイしたDockerコンテナ同士でUDPブロードキャストパケットをやり取りして研究の検証をしようとしていました.
+
+# 上手くいかないところ
+
+コンテナからホストOSへはUDPブロードキャストパケットは到達していました.コンテナからコンテナが到達できない状況でした.
+
+# 調べたこと
+
+以下の記事にKubernetesの設計的に難しいとの記述がありました.
+
+[UDP broadcast fails between pods · Issue #1063 · kubernetes-sigs/kind](https://github.com/kubernetes-sigs/kind/issues/1063)
+
+> 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.
+
+# ソースコード/マニフェスト
+
+以下を使って試していました.
+
+```go: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()
+}
+```
+
+```dockerfile
+FROM golang:rc
+EXPOSE 7531
+ADD agent.go /work/
+WORKDIR /work/
+CMD go run agent.go
+```
+
+```yaml
+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