Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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
cdsl
東京工科大学コンピュータサイエンス学部クラウド・分散システム研究室
https://www.tak-cslab.org/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away