Is there a straight way to get html response from a unix socket in Go (like curl does)?

huangapple go评论75阅读模式
英文:

Is there a straight way to get html response from a unix socket in Go (like curl does)?

问题

我需要创建一个运行在 Docker Swarm 中作为服务的 Docker(1.13)容器,用于调度作业(类似于在整个 Swarm 中执行 'docker exec' 的 crontab)。
我是一个系统管理员,不是一个程序员,所以我开始使用 bash、curl 和 jq 来完成这个任务。
它可以工作,但肯定还有改进的空间。

为了让你了解我正在处理的混乱情况,这里有一些我传递给 Docker socket 的调用片段,用于查找服务运行的位置:

获取本地 Docker 节点 ID:

curl -s --unix-socket /var/run/docker.sock http:/v1.26/info | jq -r '.Name + " " + .Swarm.NodeID'

列出 Swarm 节点 ID:

curl -s --unix-socket /var/run/docker.sock http:/v1.26/nodes | jq -r '.[] | .Description.Hostname + " " + .ID'

列出 Swarm 服务:

curl -s --unix-socket /var/run/docker.sock http:/v1.26/nodes | jq -r '.[] | .Description.Hostname + " " + .ID'

列出正在运行的任务:

curl -s --unix-socket /var/run/docker.sock http:/v1.26/tasks | jq -r '.[] | select( .Status.State | contains("running")) | .NodeID + " " + .ServiceID + " " + .ID + " " + .Status.State'

我想用 golang 更好地完成这个任务。

我知道在与 TCP socket 通信时如何使用 http.Get:

res, err := http.Get(url)
body, err := ioutil.ReadAll(res.Body)
err = json.Unmarshal(body, &p)
// p 现在包含了我请求的内容

但是我该如何处理 Unix 文件 socket(/var/run/docker.sock)呢?我猜我需要使用 net.DialUnix,但是到目前为止我还无法使其工作。

欢迎提出任何想法或建议。

英文:

I need to create a docker (1.13) container that will be running as a service in a docker swarm to schedule jobs (like a swarm-wide crontab that performs 'docker exec' where needed).
I'm a rather sysadmin guy and not really a coder, so I started doing it with with bash, curl and jq.
It works, but there is definitely room for improvement.

To give you an idea of the mumbo-jumpo I'm dealing with, here are a few snippets of the calls I pass to the docker socket to find out where the services are running:

# Get local docker node ID:
curl -s --unix-socket /var/run/docker.sock http:/v1.26/info | jq -r '.Name + " " + .Swarm.NodeID'

# List swarm node ID's:
curl -s --unix-socket /var/run/docker.sock http:/v1.26/nodes | jq -r '.[] | .Description.Hostname + " " + .ID'

# List swarm services:
curl -s --unix-socket /var/run/docker.sock http:/v1.26/nodes | jq -r '.[] | .Description.Hostname + " " + .ID'

# List running tasks:
curl -s --unix-socket /var/run/docker.sock http:/v1.26/tasks | jq -r '.[] | select( .Status.State | contains("running")) | .NodeID + " " + .ServiceID + " " + .ID + " " + .Status.State'

I'd like to do it nicer with golang.

I understand how http.Get works when talking to a tcp socket:

res, err := http.Get(url)
body, err := ioutil.ReadAll(res.Body)
err = json.Unmarshal(body, &p)
// p is then populated with the content of my request

But how can I deal with a unix filesocket (/var/run/docker.sock)? I assume I have to use net.DialUnix but could not get it to work so far.

Any idea or suggestion are welcome.

答案1

得分: 1

请尝试以下代码:

package main

import (
    "fmt"
    "net"
    "log"
    "bufio"
)

func main() {
    conn, err := net.Dial("unix", "/var/run/docker.sock")

    if err != nil {
        panic(err)
    }
    fmt.Fprintf(conn, "GET /images/json HTTP/1.0\r\n\r\n")
    status, err := bufio.NewReader(conn).ReadString('\t')
    if err != nil {
        log.Println(err)
    }

    fmt.Print("服务器返回的消息: " + status)
}

另一种方法是使用 Docker SDK,它适用于 Python、Go 和其他一些语言。

英文:

Try this:

package main

import (
    "fmt"
    "net"
    "log"
    "bufio"

)

func main() {
    conn, err := net.Dial("unix", "/var/run/docker.sock")

    if err != nil {
        panic(err)
    }
    fmt.Fprintf(conn, "GET /images/json HTTP/1.0\r\n\r\n")
    status, err := bufio.NewReader(conn).ReadString('\t')
    if err != nil {
        log.Println(err)
    }

    fmt.Print("Message from server: "+status)
}

Another approach:

Use docker SDK, available for python, go and some other languages.

huangapple
  • 本文由 发表于 2017年3月7日 06:42:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/42636989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定