随着容器技术的出现,我们的开发方式也在发生着变化,以前使用C/C++进行开发时,一般都是开发本地应用,后面发展到本地开发,远程编译部署。如今容器的出现,又有一种新的开发方式,就是在容器中进行编译部署。 一、安装远程容器
笔者使用的远程容器包括Docker和Podman,Ubuntu可以使用apt或者snap命令来安装,CentOS可以使用yum命令来安装,这里就不详述了。
二、安装与配置容器仓库 1.安装与配置参见:使用nexus3作为Docker镜像仓库
2.安装证书配置好容器仓库后,为了让开发机(笔者的为Windows,与容器仓库所在主机不为同一机器)能够正常以https的方式访问,需要把安装容器仓库所生成的证书复制到Windows进行安装,即把上前文中的ca.crt文件复制到Windows,然后双击它,在d出的对话框中选择“安装证书”进行安装。
我们这里还是如使用podman容器配置gitlab一文中的GoDemo类似,准备几个文件,main.go,Dockerfile
main.go的内容如下:
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("Hello, 这是一个Docker测试!"))
})
http.ListenAndServe(":8000", nil)
}
Dockerfile内容如下:
# 编译使用的镜像
FROM golang:1.16 as build-env
COPY . /dockerdev
WORKDIR /dockerdev
RUN go mod init demo && go build -o /demo
# 最终使用的镜像
FROM ubuntu:latest
# 暴露的端口
EXPOSE 8000
WORKDIR /
COPY --from=build-env /demo /
CMD ["/demo"]
该Dockerfile使用了多阶段构建的方式,即将编译阶段与构建容器的最终阶段分开,这样可以让我们在最终能生成最小的Docker镜像。
四、运行 1.开启容器远程服务为了让项目在远程容器中运行,需要先打开容器的远程服务,如果是podman来作为容器服务,在服务器上运行如下命令:
sudo podman system service --time=0 tcp:0.0.0.0:2979
如果是docker需要修改docker服务文件,笔者使用的ubuntu系统,路径为:
/lib/systemd/system/docker.service
在ExecStart的命令行中添加
-H tcp://0.0.0.0:2979
如下图所示:
然后重新加载配置并重启服务:
systemctl daemon-reload
systemctl restart docker
注意:如果系统开启了防火墙,需要允许使用到的所有端口。如果是在内网测试,也可以直接关闭防火墙。
2.添加运行配置在Goland中打开前面的Dockerfile文件,第一个from ……命令的前面会有一个绿色箭头,点它运行“新建运行配置”:
在服务器一栏中选择“新建…”
在新建Docker连接对话框中,连接方式中选择TCP套接字,URL填写容器服务器地址及端口:
tcp://192.168.1.8:2979
填写好后,Goland会自动连接,下面会有连接成功与否的提示。
选择配置好的Docker服务器,填写镜像标记,比如mydemo:v1;容器名称,比如mydemo。
由于我们的项目需要使用到8000端口,对外提供服务,所以需要添加绑定端口,将端口暴露出来。
填写好后,运行,可以看到运行的容器,构建的镜像,网络、卷等信息,选中运行的容器,可以在构建日志中看到构建过程:
打开浏览器测试:
成功运行。
能够成功运行的镜像,我们可以将其推送到镜像仓库中。
1.连接镜像仓库在开发机导入容器库访问证书后,就可以连接容器镜像库(注册表)了,打开Goland设置界面,如下图所示,打开“构建、执行、部署”中的Docker注册表,添加一个注册表
名称,自定义地址,填写前面配置的容器仓库地址,笔者的为192.168.1.8:5051用户名,填写Nexus中的用户名密码,填写Nexus中的用户名对应的密码填写好后,Goland会自动连接,如果连接成功,下面会给出“连接成功”提示,如果失败,也会给出提示。 2. 推送镜像
选择刚才构建的镜像,右键选择“推送镜像”
在推送镜像界面选择头面连接的注册表,填写仓库名和标签,确定。
成功后就可以在nexue中查看到刚才推送的镜像。
我们将运行环境放在容器中运行后,如果有问题,如何调试呢?
1.修改Dockerfile还是以前面的项目为示例,我们修改Dockerfile为:
# 编译使用的镜像
FROM golang:1.16 as build-env
RUN export GO111MODULE="on" && export GOPROXY="https://goproxy.cn,direct" && go get github.com/go-delve/delve/cmd/dlv
COPY . /dockerdev
WORKDIR /dockerdev
RUN go build -gcflags="all=-N -l" -o /demo
# 最终使用的镜像
FROM ubuntu:latest
# 暴露的端口
EXPOSE 8000 40000
WORKDIR /
COPY --from=build-env /go/bin/dlv /
COPY --from=build-env /demo /
CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/demo"]
该Dockerfile文件在编译阶段,下载并编译生成dlv调试器,由于国内下载源码比较慢,所以需要修改GOPROXY值设置代理,并打开GO111MODULE。
在执行容器时,是以dlv调试器来打开我们的项目执行文件demo,并监听40000端口。
提示:
如果不想更改原始的Dockerfile文件,可以改名为Dockerfile.debug。如果之前从未使用过.debug的文件,Goland会询问如何关联该类型的文件。
在项目中添加go.mod文件
内容如下:
module demo
go 1.16
也可以在本机使用
go mod init demo
go mod tidy
命令来自动生成go.mod以及go.sum文件。
注意:如果不在项目中先添加go.mod,直接在Dockerfile中编译前使用go mod init demo指令来生成会导致调试时找不到路径,这点很奇怪。
添加Dockerfile运行/调试配置
然后设置运行配置:
--security-opt="apparmor=unconfined" --cap-add=SYS_PTRACE
如下图所示:
配置好后,运行配置,开始构建镜像并运行容器。
如果出现未连接docker的问题:
先断开Docker,再重新连接
然后填写主机地址以及端口号:
配置好后,执行调试:
我们在main.go中的输出语句打断点:
在浏览器中打开http://192.168.1.8:8000/,可以看到断点命中了。
也可以使用Goland新建一个http请求文件,命名为test
内容为:
GET http://192.168.1.8:8000
然后点击前面的绿色箭头,运行,也会命中断点。
前面的用于调试的Dockerfile中,在编译阶段,每次都需要下载dlv调试器,可以自己制作一个带dlv调试的go容器,这样就不用每次都去下载了。
在Go容器中运行:
export GO111MODULE="on" && export GOPROXY="https://goproxy.cn,direct" && go get github.com/go-delve/delve/cmd/dlv
下载dlv调试器,然后使用命令提交
podman commit go-dlv 127.0.0.1:5000/go-dlv:1.16
如果有镜像仓库,使用下面的命令推送到仓库:
podman push 127.0.0.1:5000/go-dlv:1.16
参考链接:
https://blog.jetbrains.com/go/2020/05/04/go-development-with-docker-containers/
https://blog.jetbrains.com/go/2020/05/06/debugging-a-go-application-inside-a-docker-container/
https://www.jetbrains.com/help/idea/podman.html#tutorial-run-podman-in-a-virtual-machine
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)