docker golang 主进程与 python 子进程通信的最佳实践

Best practice on docker golang main process communicate with python subprocess

我知道使用docker的最佳实践是在每个容器中只有一个主进程并且只有一个CMD行运行ning.

我的情况是我有一个 Golang 微服务,功能是在 python 子流程中实现的。目前主进程只接受 API 调用然后调用 exec 中的 python 子进程并读取 STDOUTSTDERR.

我想优化架构,例如 运行 python 仅在 docker 内的本地主机上作为服务(Flask)。然后我的主要 Golang 进程可以使用 restful http 调用与 python 进程进行通信。

但这会让 2 个服务 运行ning 在同一个 docker 中并且它不是主进程和子进程。这实际上会很糟糕吗,知道吗?

感谢所有帮助。

通常当你有多个服务时,最好的做法是不要将它们部署在一个容器中,建议你将它们部署在多个容器中。

您可以使用docker-compose来帮助您:

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

对于您的场景,请举一个最简单的例子作为下一个。

文件夹结构:

.
├── docker-compose.yaml
├── flask
│   ├── app.py
│   └── Dockerfile
└── go
    ├── app.go
    └── Dockerfile

docker-compose.yaml:

version: '3'
services:
  flask_service:
    build: flask

  go_service:
    build: go
    ports:
    - "9500:9500"
    depends_on:
    - flask_service

go/app.go:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
        url := "http://flask_service:9600"
        ret, err := http.Get(url)
        if err != nil {
                panic(err)
        }
        defer ret.Body.Close()

        body, err := ioutil.ReadAll(ret.Body)
        if err != nil {
                panic(err)
        }
        fmt.Fprintf(w, string(body))
}

func main() {
        http.HandleFunc("/", handler)
        http.ListenAndServe(":9500", nil)
}

go/Dockerfile:

FROM golang:latest as build

WORKDIR /go/app
COPY ./app.go .
RUN go mod init app; go mod tidy; go build

CMD ["/go/app/app"]

flask/app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hey, we have Flask in a Docker container!'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=9600)

flask/Dockerfile:

FROM python:alpine3.7

WORKDIR /app

RUN pip install flask

COPY . /app

ENTRYPOINT [ "python" ]
CMD [ "app.py" ]

执行:

$ docker-compose up
Creating network "20211203_default" with the default driver
Creating 20211203_flask_service_1 ... done
Creating 20211203_go_service_1    ... done
Attaching to 20211203_flask_service_1, 20211203_go_service_1

验证:

$ curl http://10.192.244.21:9500
Hey, we have Flask in a Docker container!

您可以看到我们访问 9500 端口,它将请求路由到 golang container,然后 golang container 将使用 api 调用 flask service container,最后得到 flask.

产生的内容 Hey, we have Flask in a Docker container!