在Docker 中构建 golang程序

97 阅读4分钟
我打算开始记录自己的学习日志,主要是自己懒没有对应的博客,但感觉可以先在掘金存储文章先

在Docker 中构建 golang程序

首先假设自己有一个golang程序
    package main

    import "fmt"

    func main() {
        fmt.Println("Hello, World!")
    }

然后新建一个dockfile

# 使用官方 golang 镜像作为基础镜像
FROM golang:1.20

# 在容器内设置工作目录
WORKDIR /go/src/app

# 将主机的代码复制到工作目录内 <Copy> <src>本地 <desc> 容器内
COPY . .

# 下载依赖管理工具
RUN go get -d -v golang.org/x/net/html

# 编译 Go 程序
RUN go build -o main .

# 启动 Go 程序
CMD ["./main"]

然后用makefile来操作一下具体命令

IMAGE_NAME = testname  
export tag=v1.0  
root:  
export Root=test  
build:  
@echo "building about golang project"  
@docker build -t $(IMAGE_NAME) .  
#  
buildAndRun: build  
@echo "running!"  
@docker run -it $(IMAGE_NAME)  
run:  
@echo "running!"  
@docker run -it $(IMAGE_NAME)

效果图:

image.png

查看这个镜像

        docker inspect testname

     docker inspect testname                                                                    1[
        {
            "Id": "sha256:0783aa7825a69b529fc934542f2c8ac1b6fbf222caff26f1e36fe460a11a7509",
            "RepoTags": [
                "testname:latest"
            ],
            "RepoDigests": [],
            "Parent": "sha256:4b0365df4e57d827cc82bf2f006f2e4306aa0ad7b524329f2816d61b9b15d75d",
            "Comment": "",
            "Created": "2023-06-04T13:11:26.205062834Z",
            "Container": "e5612a0434f2c1276203da5ff88e0d6d354a9abad952374949382746ec92c162",
            "ContainerConfig": {
                "Hostname": "e5612a0434f2",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "8081/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "GOLANG_VERSION=1.19.8",
                    "GOPATH=/go",
                    "GOPROXY=https://goproxy.io"
                ],
                "Cmd": [
                    "/bin/sh",
                    "-c",
                    "#(nop) ",
                    "CMD [\"/docker-gs-ping\"]"
                ],
                "Image": "sha256:4b0365df4e57d827cc82bf2f006f2e4306aa0ad7b524329f2816d61b9b15d75d",
                "Volumes": null,
                "WorkingDir": "/app",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {}
            },
            "DockerVersion": "20.10.14",
            "Author": "",
            "Config": {
                "Hostname": "",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "8081/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "GOLANG_VERSION=1.19.8",
                    "GOPATH=/go",
                    "GOPROXY=https://goproxy.io"
                ],
                "Cmd": [
                    "/docker-gs-ping"
                ],
                "Image": "sha256:4b0365df4e57d827cc82bf2f006f2e4306aa0ad7b524329f2816d61b9b15d75d",
                "Volumes": null,
                "WorkingDir": "/app",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": null
            },
            "Architecture": "arm64",
            "Variant": "v8",
            "Os": "linux",
            "Size": 846096276,
            "VirtualSize": 846096276,
       ....

扩展和深入(有错误请指出)

本身的特点: 安全性/隔离性/便携性/可配置

NameSpace

linux NameSpcace 是一种linux Kernel 提供的资源隔离方案

  • 系统可以给进程分配不同的 namespace
  • 并且可以保证Namespace 资源,线程的全都单独隔离。
linux task
    struct task_struct{
    /*namespcket*/ 
    struct nsproxy *nsproxy
    }

NameSpace数据结构

 struct nsproxy { 
 atomic_t count; 
 struct uts_namespace *uts_ns; 
 struct ipc_namespace *ipc_ns; 
 struct mnt_namespace *mnt_ns; 
 struct pid_namespace *pid_ns_for_children; 
 struct net *net_ns; 
 }

大概隔离效果:

image.png

Pid namespace

不同用户的进程通过Pid namespace的隔离开始,并且不同的隔离空间有不同的pid

Net namespace

每一个net namespace 都有独立的 network devices Ip,address Ip,以及Ip routing tables,/proc/net('netstat','ss','ip',will read proc/net file directly)

ipc namespace

用来管理linux之间的信号量,消息队列,共享内存。 每个IPC资源都有一个32位独立的ID

实践

docker run -it --rm ubuntu bash   //mac os don't have lsns command
lsns -t pid
lsns -t net

可以通过以上命令获取到pid然后去查看 proc里面对应的参数


root@0609445e7234:/# ls -la /proc/1/ns/
 
lrwxrwxrwx 1 root root 0 Jun  6 02:47 **cgroup** -> **'cgroup:[4026532384]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **ipc** -> **'ipc:[4026532305]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **mnt** -> **'mnt:[4026532303]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:45 **net** -> **'net:[4026532308]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:46 **pid** -> **'pid:[4026532306]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **pid_for_children** -> **'pid:[4026532306]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **time** -> **'time:[4026531834]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **time_for_children** -> **'time:[4026531834]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **user** -> **'user:[4026531837]'**

lrwxrwxrwx 1 root root 0 Jun  6 02:47 **uts** -> **'uts:[4026532304]'**

Cgroups (control groups)

  • linux下的一个子系统对一个或者一组进行的一个资源监管的机制(cpu使用的时间,内存,磁盘I/0的限制。
  • Cgourps 在不同的资源系统以Hierarchy的方式管理Hierarchy

就在这个位置

cgroupsposition.png

##以上就是关于我的知识记录,有问题请提出。