LoginSignup
0

More than 1 year has passed since last update.

posted at

Kubernetes上のコンテナ間でUDPブロードキャストを諦めた

結論

素直に諦めて別のやり方に切り替えました.なので,難しいと思います.

やろうとしたこと

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0