发布于 2026-01-06 1 阅读
0

第五天:与容器交互

第五天:与容器交互

本文转载自adventofdocker.com。

嗨!恭喜你来到第五天!今天我们将继续第四天的 Go 应用开发,并让它更有趣一些。我们将首先运行一个简单的 HTTP 服务器,然后看看如何与它交互!

简单回顾一下,昨天我们创建了一个 Dockerfile,内容如下:

FROM golang

COPY . .

RUN go build -o main main.go

CMD ["./main"]
Enter fullscreen mode Exit fullscreen mode

我们的 main.go 文件内容如下:

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
Enter fullscreen mode Exit fullscreen mode

如果你昨天没有创建该目录,请创建一个新目录并将文件添加到该目录中!

当然,打印“hello world”有点无聊,所以让我们添加一个简单的HTTP服务器,让我们的应用程序更有趣一些。

为此,我们将修改 main.go 文件,使其如下所示:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello World!") // this will be printed as a response when you request /
    })
    fmt.Println("Listening on port 8080")
    http.ListenAndServe(":8080", nil) // this will start the HTTP server (blocking operation) and listen on port 8080
}
Enter fullscreen mode Exit fullscreen mode

这里我们基本上只创建了一条路由(/),当有人访问根路径时,它会打印“Hello World!”。HTTP 服务器将监听 8080 端口。如果你想尝试更多功能,可以添加更多路由,更改端口或消息。

您仍然可以使用昨天的 Dockerfile,并像昨天一样构建镜像。

$ docker build -t hello-world-go .
Enter fullscreen mode Exit fullscreen mode

然后像昨天那样运行它。

$ docker run hello-world-go
Enter fullscreen mode Exit fullscreen mode

如果您现在打开浏览器并访问该网站,http://localhost:8080您应该会在浏览器中看到“Hello, World!”,对吗?

嗯,其实不是……

连接被拒绝

这是因为 Docker 容器默认与主机隔离。这意味着如果您在容器中监听某个端口,主机将无法访问该端口。您需要显式地告诉 Docker 您想要暴露某个端口。为此,请终止正在运行的容器(在终端中按 CTRL+C),然后修改您的运行命令:

$ docker run -p 8080:8080 hello-world-go
Enter fullscreen mode Exit fullscreen mode

这将把容器的 8080 端口暴露给主机上的 8080 端口。现在,如果您访问该端口,http://localhost:8080应该会在浏览器中看到“Hello, World!”的字样。

你好世界

太棒了!我觉得现在正是调整端口的好时机。修改一下配置main.go文件里的端口,看看效果如何。

补充说明:如果你查看其他人编写的 Dockerfile,通常会看到一条 ` EXPOSEexpose` 指令。这条指令实际上并不会将端口暴露给主机,它本质上只是文档,用于连接 Dockerfile 的编写者和使用者。你可以在这里了解更多信息。

FROM golang

COPY . .

RUN go build -o main main.go

EXPOSE 8080

CMD ["./main"]
Enter fullscreen mode Exit fullscreen mode

与正在运行的容器交互

我想向您展示三个与容器交互的实用命令:docker ps,,docker statsdocker exec

在开发过程中,同时运行多个容器是很常见的。例如,一个用于 API,一个用于前端,一个用于数据库。如果您想知道当前正在运行哪些容器,该怎么办呢?
这就是 ` containers` 命令docker ps的作用。docker ps它会列出当前正在运行的容器:

$ docker ps
CONTAINER ID   IMAGE         COMMAND    CREATED         STATUS         PORTS                    NAMES
27a27b6343a7   http-server   "./main"   6 minutes ago   Up 6 minutes   0.0.0.0:8080->8080/tcp   funny_galois
Enter fullscreen mode Exit fullscreen mode

这里可以看到,我们有一个容器正在运行,funny_galois它运行着http-server镜像并监听 8080 端口。非常实用,对吧?
如果输出为空,可能是因为您的容器已经停止了。您可以使用命令列出所有曾经运行过的容器docker ps -a

有时您想了解容器的资源使用情况。这时,docker stats它就能派上用场了。docker stats它会向您展示容器的资源使用情况:

$ docker stats
CONTAINER ID   NAME           CPU %     MEM USAGE / LIMIT     MEM %     NET I/O         BLOCK I/O   PIDS
27a27b6343a7   funny_galois   0.00%     4.914MiB / 7.661GiB   0.06%     4.59kB / 846B   0B / 0B     6
Enter fullscreen mode Exit fullscreen mode

您可以看到,我们的funny_galois容器 CPU 使用率为 0.00%,内存使用率为 4.914MiB(占 7.661GiB 内存限制的 0.06%)。它进行了 4.59kB 的网络 I/O 和 0B 的块 I/O,并且有 6 个进程 ID (PID) 正在运行。这对调试非常有用!

最后,我想向大家展示如何与正在运行的容器进行交互。如果你想在容器里探索一番呢?打开一个 shell?安装一些软件包?通常不建议这样做(因为容器应该是短暂且无状态的),但这在调试时可能很有用。为此,我们可以使用命令docker exec

$ docker exec -it funny_galois bash
Enter fullscreen mode Exit fullscreen mode

funny_galoisdocker ps是我们的容器名称,您可以使用上面的命令获取容器名称。这些-it标志用于将您的终端连接到容器,以便您可以使用它。该bash命令将在容器中打开一个 shell。如果您运行此命令,您会发现自己已进入容器,从这里您可以浏览、安装软件包、进行各种操作等等。例如,您可能只想使用以下命令查看当前目录中的内容ls

docker exec -ti funny_galois bash
root@27a27b6343a7:/go# ls
Dockerfile  bin  main  main.go  src
Enter fullscreen mode Exit fullscreen mode

我建议你试一试,在容器里探索一番。添加文件,安装一些软件包。尽情体验吧!然后停止容器,再重复一遍,文件还在吗?为什么呢?

这是明天的预告,我们将回顾一下什么是层,为什么容器是短暂的,以及这对我们的工作流程意味着什么 :)

在此之前,祝你编程愉快!🚀

乔纳斯

文章来源:https://dev.to/code42cate/day-5-interacting-with-containers-5g31