在CSDN学Golang云原生(Docker容器)

一,Doker 命令行操作

在Go语言中,可以通过调用Docker命令行工具来进行容器管理和操作。下面是一些基本的Docker命令行操作示例:

  1. 启动一个新容器
cmd := exec.Command("docker", "run", "-d", "nginx")
if err := cmd.Run(); err != nil {panic(err)
}

这里使用了docker run命令来启动一个新的Nginx容器,并将其后台运行。

  1. 停止一个正在运行的容器
cmd := exec.Command("docker", "stop", "my-nginx-container")
if err := cmd.Run(); err != nil {panic(err)
}

这里使用了docker stop命令来停止名为“my-nginx-container”的容器。

  1. 删除一个已经停止的容器
cmd := exec.Command("docker", "rm", "my-nginx-container")
if err := cmd.Run(); err != nil {panic(err)
}

这里使用了docker rm命令来删除名为“my-nginx-container”的已停止容器。

  1. 构建一个新镜像
cmd := exec.Command("docker", "build", "-t", "my-custom-image:latest", ".")
if err := cmd.Run(); err != nil {panic(err)
}

这里使用了docker build命令从当前目录构建了一个名为“my-custom-image”的新镜像,并指定其标签为“latest”。

  1. 推送镜像到远程仓库
cmd := exec.Command("docker", "push", "my-registry.com/my-custom-image:latest")
if err := cmd.Run(); err != nil {panic(err)
}

这里使用了docker push命令将名为“my-custom-image”的镜像推送到名为“my-registry.com”的远程仓库中,并指定其标签为“latest”。

二,自定义容器启动命令或入口程序

在Go语言中,可以通过Docker API来自定义容器启动命令或入口程序。具体步骤如下:

  1. 安装Docker SDK for Go

要使用Docker API,首先需要安装docker/docker/client包。可以通过以下命令进行安装:

go get -u github.com/docker/docker@v1.13.1
  1. 编写代码

接下来,可以编写代码来自定义容器启动命令或入口程序。以下是一个示例代码:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/client"
)func main() {// 创建一个新的客户端ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}// 设置容器配置config := &types.ContainerConfig{Image: "nginx",Cmd:   []string{"nginx", "-g", "daemon off;"},ExposedPorts: map[nat.Port]struct{}{nat.Port("80/tcp"): {},},}// 创建并启动容器resp, err := cli.ContainerCreate(ctx, config, nil, nil, "")if err != nil {panic(err)}if err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {panic(err)}fmt.Println(resp.ID)
}

在上面的示例中,我们使用了client.NewClientWithOpts(client.FromEnv)方法创建了一个新的Docker客户端,并设置了容器配置。在这里,我们将容器的镜像设置为Nginx,并指定了自定义的启动命令["nginx", "-g", "daemon off;"]。我们还将80端口映射到了宿主机上。

最后,我们使用cli.ContainerCreate()方法创建并启动了一个新的容器,并打印了其ID。

  1. 运行代码

运行以上代码后,可以看到输出结果中包含有新创建的容器ID。

需要注意的是,在使用Docker API时需要具有足够的权限。如果没有正确的权限,可能会遇到一些问题。同时,在编写代码时应该注意安全性和可靠性等方面的问题。

三,容器health check

在 Go 语言中,我们可以使用 github.com/docker/docker/client 包来创建和管理 Docker 容器,并设置容器的健康检查。下面是一个示例代码,展示如何使用容器健康检查:

package mainimport ("context""fmt""time""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/api/types/strslice""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}containerConfig := &container.Config{Image:        "nginx",AttachStdout: true,AttachStderr: true,Tty:          true,Healthcheck: &container.HealthConfig{Test:        strslice.StrSlice{"/usr/bin/curl", "-f", "http://localhost"},Interval:    time.Duration(10) * time.Second,Timeout:     time.Duration(5) * time.Second,StartPeriod: time.Duration(0) * time.Second,Retries:     3,},}hostConfig := &container.HostConfig{}resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")if err != nil {panic(err)}fmt.Println("Container ID:", resp.ID)err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})if err != nil {panic(err)}statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)select {case err := <-errCh:if err != nil {panic(err)}case status := <-statusCh:fmt.Println("Container exited with status:", status.StatusCode)}
}

上面的示例中,我们使用 container.HealthConfig 结构体来定义容器的健康检查配置。通过设置 Test 字段,我们可以指定一个命令或脚本来测试容器的健康状态。在这个例子中,我们使用 /usr/bin/curl -f http://localhost 命令来测试容器是否能够访问本地主机。

除了 Test 字段之外,还有其他几个字段可以用于调整健康检查的行为:

  • Interval: 容器健康检查的间隔时间。
  • Timeout: 每次健康检查的超时时间。
  • StartPeriod: 在容器启动后多少秒开始进行第一次健康检查。
  • Retries: 当连续失败几次后认为容器不可用。

设置完容器的健康检查配置后,我们可以使用 cli.ContainerCreate 函数创建容器,并在其中包含配置信息。然后使用 cli.ContainerStart 函数启动容器,并使用 cli.ContainerWait 函数等待容器退出并返回状态信息。

需要注意的是,在运行具有长期运行服务(例如 Web 服务器)的 Docker 容器时,请务必确保正确设置健康检查和自动重启策略以确保高可用性。

四,容器重启策略

在 Go 语言中,可以使用 Docker API 来为容器设置重启策略。以下是一个示例代码:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}containerConfig := &types.ContainerConfig{Image: "nginx",Cmd:   []string{"nginx", "-g", "daemon off;"},}hostConfig := &types.HostConfig{// 设置重启策略RestartPolicy: types.RestartPolicy{Name: "on-failure",MaximumRetryCount: 3,},}resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")if err != nil {panic(err)}if err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {panic(err)}fmt.Println(resp.ID)
}

在上面的示例中,我们通过 types.RestartPolicy 结构体设置了重启策略。具体来说,我们定义了一个 Name 字段,在其中指定了容器停止时应该采取的操作。这里我们选择的是“on-failure”,即只有在容器退出时才会自动重启。另外,我们还设置了最大重试次数。

需要注意的是,在使用 Docker API 时需要具有足够的权限。如果没有正确的权限,可能会遇到一些问题。同时,在编写代码时应该注意安全性和可靠性等方面的问题。

五,容器资源配额

在 Go 语言中,我们可以使用 Docker API 来设置容器的资源配额。以下是一个示例代码:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}containerConfig := &container.Config{Image: "nginx",}hostConfig := &container.HostConfig{// 设置 CPU 配额CpuQuota:   int64(100000),// 设置内存限制Memory:     int64(536870912),}resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")if err != nil {panic(err)}if err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {panic(err)}inspectResp, _ ,err := cli.ContainerInspectWithRaw(ctx, resp.ID)if err != nil {panic(err)}fmt.Println("cpu quota:", inspectResp.HostConfig.Resources.CPUQuota)fmt.Println("memory limit:", inspectResp.HostConfig.Resources.Memory)}

在上面的示例中,我们通过 HostConfig 结构体来定义了容器的资源配额。其中,CpuQuota 字段表示 CPU 配额,单位为微秒(1/1000 毫秒),而 Memory 字段则表示内存限制,单位为字节。

在实际应用中,我们可以根据需要设置不同的资源配额以满足业务需求。值得注意的是,在使用资源配额功能时要确保目标容器支持该功能,并且正确配置监控参数才能够发挥最大效益。

六,容器命名空间隔离

在 Go 语言中,我们可以使用 github.com/docker/docker/client 包来创建和管理 Docker 容器。下面是一个示例代码,展示如何通过命名空间隔离来创建一个新的容器:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}// 创建命名空间隔离的网络networkCreateResp, err := cli.NetworkCreate(ctx, "my-network", types.NetworkCreate{})if err != nil {panic(err)}// 定义容器配置containerConfig := &container.Config{Image:        "nginx",AttachStdout: true,AttachStderr: true,Tty:          true,}// 定义主机配置hostConfig := &container.HostConfig{NetworkMode: container.NetworkMode(networkCreateResp.ID),}resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")if err != nil {panic(err)}err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})if err != nil {panic(err)}fmt.Println("Container ID:", resp.ID)
}

上面的示例中,我们通过 networkCreateResp 变量创建了一个名为 my-network 的网络,并将其绑定到新建的容器中。在定义主机配置时,我们将容器与该网络进行了绑定。通过这种方式,容器就可以在一个独立的命名空间内运行,与主机和其他容器隔离开来。

值得注意的是,在创建命名空间隔离的网络时,需要确保该网络的名称在宿主机上是唯一的。否则会出现名称冲突导致创建失败的情况。同时,我们也要确保目标容器所需的所有网络资源都被正确配置才能够正常使用。

七,Volume数据存储持久化与数据共享

在 Go 语言中,我们可以使用 github.com/docker/docker/client 包来创建和管理 Docker 容器,并通过挂载数据卷的方式实现数据存储持久化和共享。下面是一个示例代码,展示如何使用数据卷来创建一个新的容器:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}hostConfig := &container.HostConfig{Binds: []string{"/path/on/host:/path/on/container"},}containerConfig := &container.Config{Image:        "nginx",AttachStdout: true,AttachStderr: true,Tty:          true,}resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, nil, "")if err != nil {panic(err)}err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})if err != nil {panic(err)}fmt.Println("Container ID:", resp.ID)
}

上面的示例中,我们通过将 /path/on/host 目录与 /path/on/container 目录进行绑定,从而实现了主机和容器之间的数据共享。这样,在容器内部修改 /path/on/container 目录下的文件时,就会直接影响到主机上对应目录下的文件。

如果想要实现数据存储持久化,可以将数据卷挂载到一个宿主机目录上,并通过 -v 参数指定挂载方式。例如:

hostConfig := &container.HostConfig{Binds: []string{"/path/on/host:/path/on/container"},
}

其中 /path/on/host 表示宿主机上的目录,/path/on/container 表示容器内部的目录。

在实际使用中,我们还可以通过 docker volume create 命令创建一个数据卷,并通过 -v 参数指定其名称和挂载方式。例如:

hostConfig := &container.HostConfig{Binds: []string{"my-volume:/path/on/container"},
}_, err = cli.VolumeCreate(ctx, types.VolumeCreateBody{Name: "my-volume"})
if err != nil {panic(err)
}

这样,在容器启动时就会自动挂载名为 my-volume 的数据卷,从而实现数据存储持久化和共享。

八,bridge,host,overlay网络驱动

在 Go 语言中,我们可以使用 github.com/docker/docker/client 包来创建和管理 Docker 容器,并通过不同类型的网络驱动来实现容器之间的通信。下面是一个示例代码,展示如何使用 bridge、host 和 overlay 网络驱动来创建不同类型的网络:

package mainimport ("context""fmt""github.com/docker/docker/api/types""github.com/docker/docker/api/types/container""github.com/docker/docker/api/types/network""github.com/docker/docker/client"
)func main() {ctx := context.Background()cli, err := client.NewClientWithOpts(client.FromEnv)if err != nil {panic(err)}// 创建 bridge 网络netConfig := &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{"my-bridge": &network.EndpointSettings{},},}resp, err := cli.NetworkCreate(ctx, "my-bridge", types.NetworkCreate{Driver: "bridge", CheckDuplicate: true})if err != nil {panic(err)}fmt.Println("Bridge network ID:", resp.ID)containerConfig := &container.Config{Image:        "nginx",AttachStdout: true,AttachStderr: true,Tty:          true,}hostConfig := &container.HostConfig{}networkingConfig := &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{"my-bridge": &network.EndpointSettings{},},}// 创建容器并加入 bridge 网络resp, err = cli.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, "")if err != nil {panic(err)}err = cli.NetworkConnect(ctx, "my-bridge", resp.ID, &network.EndpointSettings{})if err != nil {panic(err)}fmt.Println("Container ID:", resp.ID)// 创建 host 网络resp, err = cli.NetworkCreate(ctx, "my-host", types.NetworkCreate{Driver: "host", CheckDuplicate: true})if err != nil {panic(err)}fmt.Println("Host network ID:", resp.ID)// 创建 overlay 网络resp, err = cli.NetworkCreate(ctx, "my-overlay", types.NetworkCreate{Driver:         "overlay",CheckDuplicate: true,IPAM:           &network.IPAM{},})if err != nil {panic(err)}fmt.Println("Overlay network ID:", resp.ID)
}

上面的示例中,我们使用 cli.NetworkCreate 函数创建了三种不同类型的网络:bridge、host 和 overlay。对于每种网络类型,我们都需要指定相应的驱动和配置信息。

在创建容器时,我们可以通过 networkingConfig 参数将容器加入特定的网络中。例如,在创建 bridge 网络时,我们可以将容器加入名为 my-bridge 的网络:

networkingConfig := &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{"my-bridge": &network.EndpointSettings{},},
}resp, err = cli.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, "")
if err != nil {panic(err)
}err = cli.NetworkConnect(ctx, "my-bridge", resp.ID, &network.EndpointSettings{})
if err != nil {panic(err)
}

类似地,我们可以使用 cli.NetworkConnect 函数将容器加入其他类型的网络中。

需要注意的是,在创建 overlay 网络时,我们需要指定一个 IPAM 配置来管理容器的 IP 地址分配。如果不指定 IPAM 配置,容器就无法在 overlay 网络中通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…

设计模式-策略模式

文章目录 策略模式 策略模式 策略模式是一种行为型设计模式&#xff0c;它允许在运行时动态改变对象的行为。在策略模式中&#xff0c;算法被封装在独立的策略类中&#xff0c;使得它们可以互换使用。下面是一个简单的例子&#xff1a; 假设我们有一个计算税收的系统&#xf…

2022年全国职业院校技能大赛高职组软件测试赛项赛题评分标准

任务 考查点 评分标准 评分细则 分值 任务一 环境搭建及系统部署 &#xff08;5分&#xff09; 环境搭建及系统部署包括搭建与配置测试环境&#xff0c;安装与部署应用系统等&#xff0c;对过程和结果进行截图&#xff0c;完成环境搭建及系统部署报告 1.测试环境搭建与…

小程序附件下载并预览功能

一、实现的功能&#xff1a; 1、word、excel、图片等实现下载并预览 2、打开文件后显示文件名称 二、代码&#xff1a; // 判断文件类型whatFileType(url) {let sr url.lastIndexOf("."); // 最后一次出现的位置let fileType url.substr(sr 1); // 截取url的…

超越传统测试:如何构建可靠的持续集成测试管道

超越传统测试&#xff1a;如何构建可靠的持续集成测试管道 引言 持续集成测试是现代软件开发中至关重要的一环&#xff0c;它可以帮助团队及时发现和解决代码问题&#xff0c;提高软件质量。然而&#xff0c;传统的测试方法往往存在效率低、容易出错等问题。本篇博客将介绍如…

Java接口通过token登录实现页面跳转到登录成功后的页面

首先&#xff0c;你需要在接口请求中将token作为参数传递给后端&#xff0c;后端需要对token进行验证并获取登录用户的信息。 在验证通过后&#xff0c;你可以将登录成功后的页面链接返回给前端&#xff0c;前端通过跳转到该链接来实现页面跳转。 以下是一个简单的Java代码演…

手机图片转pdf?两种方法介绍

手机图片转pdf&#xff1f;如今&#xff0c;随着生活的数字化&#xff0c;我们的手机中储存了大量的照片。但是&#xff0c;如果需要将这些照片转换成PDF格式&#xff0c;该怎么办呢&#xff1f;下面&#xff0c;小编就给大家介绍三种方法来实现这一目标。 第一种方法&#xff…

12页线性代数图解教程,github星标9.1k,适合小白

线性代数“困难户”注意&#xff0c;今天我给大家分享一个超适合小白的线性代数学习笔记&#xff0c;只有12页纸&#xff0c;一半都是图解&#xff0c;不用担心看不懂。 这份笔记名为《线性代数的艺术》&#xff0c;是日本学者Kenji Hiranabe基于Gilbert Strang教授的《每个人…

JS常用操作数组的方法整理

JavaScript提供了许多用于操作数组的方法。以下是其中一些常见的方法&#xff1a; 1. push() : 将一个或多个元素添加到数组的末尾&#xff0c;并返回新数组的长度。 2. pop() : 移除并返回数组的最后一个元素。 3. unshift() : 将一个或多个元素添加到数组的开头&#xff0…

【Pytorch学习】pytorch中的isinstance() 函数

描述 isinstance() 函数来判断一个对象是否是一个已知的类型&#xff0c;类似 type()。 isinstance() 与 type() 区别&#xff1a; type() 不会认为子类是一种父类类型&#xff0c;不考虑继承关系。 isinstance() 会认为子类是一种父类类型&#xff0c;考虑继承关系。 如果要判…

Lambda表达式常见的Local variable must be final or effectively final原因及解决办法

目录 Local variable must be final or effectively final错误原因 解决办法按照要求定义为final&#xff08;不符合实情&#xff0c;很多时候是查库获取的变量值&#xff09;使用原子类存储变量&#xff0c;保证一致性AtomicReference常用原子类 其它 Local variable must be …

为什么要有虚拟内存?

操作系统是通过内存分段和内存分页的方式管理虚拟内存地址和物理内存地址之间的关系 内存分段 程序是由若干个逻辑分段组成的&#xff0c;代码分段、数据分段、栈段、堆段组成&#xff0c;不同的段有不同的属性&#xff0c;所以就用分段的形式分离开。 分段机制下的虚拟内存…

JVM理论(七)性能监控与调优

概述 性能优化的步骤 性能监控&#xff1a;就是通过以非强行或入侵方式收集或查看应用程序运行状态,包括如下问题 GC频繁CPU过载过高OOM内存泄漏死锁程序响应时间较长性能分析&#xff1a;通常在系统测试环境或者开发环境进行分析 通过查看程序日志以及GC日志,或者运用命令行工…

《零基础入门学习Python》第070讲:GUI的终极选择:Tkinter7

上节课我们介绍了Text组件的Indexs 索引和 Marks 标记&#xff0c;它们主要是用于定位&#xff0c;Marks 可以看做是特殊的 Indexs&#xff0c;但是它们又不是完全相同的&#xff0c;比如在默认情况下&#xff0c;你在Marks指定的位置中插入数据&#xff0c;Marks 的位置会自动…

yaml语法详解

#kv #对空格的严格要求十分高 #注入到我们的配置类中 #普通的keyvalue name: qinjiang#对象 student:name: qingjiangage: 3#行内写法 student1: {name: qinjiang,age: 3}#数组 pets:- cat- dog- pigpet: [cat,dog,pig]yaml可以给实体类赋值 person:name: kuangshenage: 19happ…

Android onTouchEvent方法不触发ACTION_UP的解决方法

Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://触摸、按下setImageResource(R.mipmap.ic_music);break;case MotionEvent.ACTION_UP://抬起setImageResource(R.mipmap.ic_launcher);break;}return sup…

ERROR 1064 - You have an error in your SQL syntax;

ERROR 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near (/, 少个逗号吧&#xff0c;以前开始写SQL&#xff0c;特别是修改SQL的时候容易出现这样错误。 而且自己也知道在附近…

前端异常错误处理(包括但不限于react,vue)

错误异常发生 页面js报错请求报错页面资源加载报错promise异常iframe加载异常页面奔溃&卡顿异常 处理异常的方法 1、react 自带的errorBoundaries 2、 react 自定义Hooks 3、 vue errorHandler 4、try catch 对特定的代码进行捕获 5、window.addEventListerner …

【深度学习】日常笔记15

训练集和测试集并不来⾃同⼀个分布。这就是所谓的分布偏移。 真实⻛险是从真实分布中抽取的所有数据的总体损失的预期&#xff0c;然⽽&#xff0c;这个数据总体通常是⽆法获得的。计算真实风险公式如下&#xff1a; 为概率密度函数 经验⻛险是训练数据的平均损失&#xff0c;⽤…

【MySQL主从复制】

目录 一、MySQL Replication 1.概述 2.优点 二、MySQL复制类型 1.异步复制&#xff08;Asynchronous repication&#xff09; 2.全同步复制&#xff08;Fully synchronous replication&#xff09; 3.半同步复制&#xff08;Semisynchronous replication&#xff09; 三…