【问题标题】:Messing/Mixing/Duplicating application variables in memory inside running containers在正在运行的容器内的内存中弄乱/混合/复制应用程序变量
【发布时间】:2021-12-28 19:45:00
【问题描述】:

我在通过 docker-compose 运行 docker 容器时遇到问题。 在写到这里之前,我尝试了所有可能的解决方案,在谷歌上进行了研究等等。 还是没有运气!希望这里的人们可以帮助我找出与 docker running 容器相关的问题。

预期行为

从同一个图像运行 4 个容器 在 docker 容器中运行的应用程序生成随机数据并创建 json 字符串。 在容器内运行的每个应用程序都应生成/创建唯一值。

实际行为

从同一个图像运行 4 个容器 在 docker 容器中运行的应用程序混合了一个值,几乎 70% 是相同的值。 假设,容器“共享”内存的问题。 在 docker 容器之外运行的相同应用程序可以完美运行并生成唯一值。

用 PHP、Node.js、Golang 测试。问题是一样的。

重现行为的步骤

只需访问此 repo 了解更多详细信息或运行:

git clone https://github.com/duktig-dev/docker-memory-issue-reproduction.git
cd docker-memory-issue-reproduction
docker-compose up -d

在 ./log directlry 内部每个生成 2500 个值后,容器将自动停止运行。

每个应用程序都将日志数据附加到自己的文件中。

您可以通过运行分析创建的值重复:

php checker.php

但在某些方面你可以想象:

在不创建 docker 容器的情况下,运行同一应用程序的 4 个副本:生成唯一的随机值。

在 docker 容器内,运行的应用程序和 70% 的值是相同的。 假设,问题来自容器的内存堆栈。

使用docker-compose部署容器:

所有 4 个容器使用相同的图像

container A Using Image "Myimg"
container B Using Image "Myimg"
container C Using Image "Myimg"
container D Using Image "Myimg"

docker version的输出:

Docker version 20.10.12, build e91ed57

docker info的输出:

Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.7.1-docker)
  scan: Docker Scan (Docker Inc., v0.12.0)

Server:
 Containers: 8
  Running: 6
  Paused: 0
  Stopped: 2
 Images: 41
 Server Version: 20.10.12
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
 runc version: v1.0.2-0-g52b36a2
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: default
  cgroupns
 Kernel Version: 5.13.0-22-generic
 Operating System: Ubuntu 21.10
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 15.54GiB
 Name: david-Macmini
 ID: FNY6:BSVD:L7JK:BFCW:ZCMP:6OMK:HM3I:U22T:WB2W:FCXM:4WC5:XS7B
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

在 Ubuntu 21.10(裸机)中运行 docker

【问题讨论】:

  • 用任何语言编辑问题以包含minimal reproducible example 将非常有帮助。程序使用什么技术来生成随机数?容器通常不应共享内存,就像运行相同可执行文件的不同进程一样(运行同一映像的多个容器可能会共享可执行文件的只读副本,但如果没有容器也是如此)。
  • 感谢您的建议。我已经编辑了“重现行为的步骤”部分,您可以在其中找到更多详细信息。
  • 有趣的是,当我们尝试生成 10,000 个值时,结果为:Total: 10000, Unique: 2500, Duplicate: 7500。我们尝试了很多次。此外,我们尝试在数据创建之间添加更多时间间隔。超过 2-3 秒。

标签: docker docker-compose deployment containers


【解决方案1】:

由于随机生成数据的行为,经过一些好朋友的提示,我有了解决办法。

这里展示了改进的代码部分,我使用“crypto/rand”而不是按时间播种。

package main

func main() {
 // code here to use this functions
}

import (
    "context"
    "fmt"

    "os"
    "sync"
    "time"

    "crypto/rand"
    "encoding/base32"

    "math/big"
)

func getRandomInt64(limit int64) int64 {

    nBig, err := rand.Int(rand.Reader, big.NewInt(limit))
    if err != nil {
        panic(err)
    }
    n := nBig.Int64()
    //fmt.Printf("Here is a random %T in [0,%d) : %d\n", n, limit, n)
    return n
}

func getSmallInt() byte {
    b := []byte{0}
    if _, err := rand.Reader.Read(b); err != nil {
        panic(err)
    }

    return b[0]
}

func getToken(length int) string {
    randomBytes := make([]byte, 32)
    _, err := rand.Read(randomBytes)
    if err != nil {
        panic(err)
    }
    return base32.StdEncoding.EncodeToString(randomBytes)[:length]
}

注意:我只是把随机生成函数放在这里,而不是整个代码

生成了 1,000,000 个随机数据,效果完美!

Starting...
Get file: Golang-Publisher-A.log lines 250000
Get file: Golang-Publisher-B.log lines 250000
Get file: Golang-Publisher-C.log lines 250000
Get file: Golang-Publisher-D.log lines 250000
Total: 1000000
Unique: 1000000
Duplicate: 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-20
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 2016-03-07
    • 2011-01-19
    相关资源
    最近更新 更多