第五天:与容器交互
本文转载自adventofdocker.com。
嗨!恭喜你来到第五天!今天我们将继续第四天的 Go 应用开发,并让它更有趣一些。我们将首先运行一个简单的 HTTP 服务器,然后看看如何与它交互!
简单回顾一下,昨天我们创建了一个 Dockerfile,内容如下:
FROM golang
COPY . .
RUN go build -o main main.go
CMD ["./main"]
我们的 main.go 文件内容如下:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
如果你昨天没有创建该目录,请创建一个新目录并将文件添加到该目录中!
当然,打印“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
}
这里我们基本上只创建了一条路由(/),当有人访问根路径时,它会打印“Hello World!”。HTTP 服务器将监听 8080 端口。如果你想尝试更多功能,可以添加更多路由,更改端口或消息。
您仍然可以使用昨天的 Dockerfile,并像昨天一样构建镜像。
$ docker build -t hello-world-go .
然后像昨天那样运行它。
$ docker run hello-world-go
如果您现在打开浏览器并访问该网站,http://localhost:8080您应该会在浏览器中看到“Hello, World!”,对吗?
嗯,其实不是……
这是因为 Docker 容器默认与主机隔离。这意味着如果您在容器中监听某个端口,主机将无法访问该端口。您需要显式地告诉 Docker 您想要暴露某个端口。为此,请终止正在运行的容器(在终端中按 CTRL+C),然后修改您的运行命令:
$ docker run -p 8080:8080 hello-world-go
这将把容器的 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"]
与正在运行的容器交互
我想向您展示三个与容器交互的实用命令:docker ps,,docker stats和docker 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
这里可以看到,我们有一个容器正在运行,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
您可以看到,我们的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
funny_galoisdocker ps是我们的容器名称,您可以使用上面的命令获取容器名称。这些-it标志用于将您的终端连接到容器,以便您可以使用它。该bash命令将在容器中打开一个 shell。如果您运行此命令,您会发现自己已进入容器,从这里您可以浏览、安装软件包、进行各种操作等等。例如,您可能只想使用以下命令查看当前目录中的内容ls:
docker exec -ti funny_galois bash
root@27a27b6343a7:/go# ls
Dockerfile bin main main.go src
我建议你试一试,在容器里探索一番。添加文件,安装一些软件包。尽情体验吧!然后停止容器,再重复一遍,文件还在吗?为什么呢?
这是明天的预告,我们将回顾一下什么是层,为什么容器是短暂的,以及这对我们的工作流程意味着什么 :)
在此之前,祝你编程愉快!🚀
乔纳斯
文章来源:https://dev.to/code42cate/day-5-interacting-with-containers-5g31

