#docker #go #multiprocessing #containers
#docker #Вперед #многопроцессорная обработка #контейнеры
Вопрос:
Я пытаюсь написать программу, которая с главного «сервера» вызывает 2 «агента», каждый из которых создает контейнеры. Каждый контейнер должен запускаться периодически и каждые 10 секунд выводить время. create
Команда берется из Std.in как <command> <PATH>
.
Например, я передаю 4 контейнера для создания, поэтому agent1
создаю 2 и agent2
создаю 2.
Моя проблема в том, что когда я запускаю эту программу, я вижу только второй контейнер из agent1, когда я набираю docker ps
I get only mycontainer2
.
И только после того, как я остановлю / удалю mycontainer2
, только тогда создается agent2 mycontainer4
. ( mycontainer1
и mycontainer3
вообще не был создан).
Вероятно, способ, которым я их создал, был неправильным. Есть ли какой-нибудь способ, которым я могу создать их все и позволить им работать отдельно?
Главный «сервер»:
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"bufio"
"os"
"bytes"
"os/exec"
"strings"
"strconv"
)
type conf struct {
Name string `yaml:"Name"`
Amount int `yaml:"Amount"`
Image string `yaml:"Image"`
}
func (c *conf) getConf() *conf {
yamlFile, err := ioutil.ReadFile("conf.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}
return c
}
func isError(err error) bool {
if err != nil {
fmt.Println(err.Error())
}
return (err != nil)
}
func showEnvStatus() {
cmd := exec.Command("echo", "Hello from ShowEnv")
// cmd.Stdin = strings.NewReader("some input")
var out bytes.Buffer
cmd.Stdout = amp;out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The out put is: %qn", out.String())
return
}
func createAgents(c conf){
var workload = c.Amount/2
var rightBroderAgent1 = strconv.Itoa(workload)
var leftBorderAgent2 = strconv.Itoa(c.Amount- workload 1)
//invoke agent1. Args are the range of the containers numbers for names. (0 : workload)
cmd1 := exec.Command("./agent","1", rightBroderAgent1, c.Name, c.Image)
var out bytes.Buffer
cmd1.Stdout = amp;out
err1 := cmd1.Run()
if err1 != nil {
fmt.Println(err1)
}
fmt.Println("%qn",out.String())
//invoke agent2. Args are the range of the containers numbers for names.(workload 1 : Amount)
cmd2 := exec.Command("./agent",leftBorderAgent2, strconv.Itoa(c.Amount),c.Name, c.Image)
err2 := cmd2.Run()
if err2 != nil {
log.Fatal(err2)
}
return
}
func parseCommand(text string) ([]string){
res := strings.Split(text, " ")
return res
}
func main() {
i := 0
for i < 1{
var args []string
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('n')
args = parseCommand(text)
switch args[0] {
case "create":
var c conf
c.getConf()
createAgents(c)
default:
fmt.Println("Unknown command, try again")
}
}
}
############################# Файл агента ##################
func main(){
// Args[] structure : {FILE, left border, right border, container's name, image}
left,_ := strconv.Atoi(os.Args[1])
right,_ := strconv.Atoi(os.Args[2])
for i := left; i <= right; i {
fmt.Println(left, right)
var name string = os.Args[3] strconv.Itoa(i 1)
cmd1 := exec.Command("docker", "run", "--name", name, "-it", "-d", os.Args[4])
cmd2 := exec.Command("docker", "cp", "showtime" ,name ":/showtime")
cmd3 := exec.Command("docker", "exec" ,name , "./showtime")
// cmds := []*exec.Cmd{cmd1,cmd2,cmd3}
err1 := cmd1.Run()
if err1 != nil {
fmt.Println(err1)
os.Exit(2)
}
err2 := cmd2.Run()
if err2 != nil {
fmt.Println(err2)
os.Exit(2)
}
err3 := cmd3.Run()
if err3 != nil {
fmt.Println(err3)
os.Exit(2)
}
}
}
Комментарии:
1. Вы проверяли API Docker pkg.go.dev/github.com/docker/docker/api ?
2. Вы также, вероятно, захотите создать изображение, содержащее ваш двоичный файл;
docker cp
программа, которую вы на самом деле хотите запустить, немного необычна. Затем вы можете использовать Docker API для создания и запуска контейнера без необходимости использования инструментов отладки, таких какdocker exec
.