国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Golang】golang使用三方SDK操作容器指南

這篇具有很好參考價(jià)值的文章主要介紹了【Golang】golang使用三方SDK操作容器指南。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【Golang】golang使用三方SDK操作容器指南

大家好 我是寸鐵??
總結(jié)了一篇 golang使用三方SDK操作容器?
喜歡的小伙伴可以點(diǎn)點(diǎn)關(guān)注 ??
這應(yīng)該是目前全網(wǎng)最全golang使用三方SDK操作容器的指南了??


CreateConfig

主要是創(chuàng)建容器的配置信息,常用的字段

使用包如下:

"github.com/docker/docker/api/types"

配置創(chuàng)建Docker 容器的結(jié)構(gòu)體,具體字段的含義和用途如下:

1.Hostname: 容器的主機(jī)名。

2.Domainname: 容器的域名。

3.User: 執(zhí)行容器內(nèi)命令的用戶,也支持指定用戶和用戶組。

4.AttachStdin: 是否連接標(biāo)準(zhǔn)輸入,使得用戶可以與容器進(jìn)行交互。

5.AttachStdout: 是否連接標(biāo)準(zhǔn)輸出。

6.AttachStderr: 是否連接標(biāo)準(zhǔn)錯(cuò)誤輸出。

7.ExposedPorts: 用于指定容器暴露的端口,是一個(gè) nat.PortSet 類型的字段。

8.Tty: 是否將標(biāo)準(zhǔn)流連接到 tty(終端),包括標(biāo)準(zhǔn)輸入(如果它沒有關(guān)閉的話)。

9.OpenStdin: 是否打開標(biāo)準(zhǔn)輸入。

10.StdinOnce: 如果為 true,在第一個(gè)連接的客戶端斷開連接后關(guān)閉標(biāo)準(zhǔn)輸入。

11.Env: 設(shè)置在容器中使用的環(huán)境變量的列表。

12.Cmd: 在啟動容器時(shí)運(yùn)行的命令。

13.Healthcheck: 描述容器健康狀況檢查的配置。

14.ArgsEscaped: 如果為 true,表示命令已經(jīng)被轉(zhuǎn)義,即將其視為命令行(特定于 Windows)。

15.Image: 由操作者傳遞的鏡像的名稱。

16.Volumes: 用于指定容器使用的卷(掛載)的列表。

17.WorkingDir: 容器中命令執(zhí)行的當(dāng)前目錄(PWD)。

18.Entrypoint: 在啟動容器時(shí)運(yùn)行的入口點(diǎn)。

19.NetworkDisabled: 是否禁用網(wǎng)絡(luò)。

20.MacAddress: 容器的 MAC 地址。注意,此字段在 API 版本 v1.44 后已被廢棄,建議使用 EndpointSettings.MacAddress 替代。

21.OnBuild:在 Dockerfile 中定義的 ONBUILD 元數(shù)據(jù)。這個(gè)字段用于保存在構(gòu)建鏡像時(shí)定義的 ONBUILD 指令,它們將在基礎(chǔ)鏡像的構(gòu)建過程中執(zhí)行。

22.Labels:容器的標(biāo)簽列表。這個(gè)字段是一個(gè)映射,用于存儲容器的元數(shù)據(jù)信息,如作者、版本、描述等。標(biāo)簽可以用于組織和識別容器,也可以用于進(jìn)行元數(shù)據(jù)查詢。

23.StopSignal:停止容器時(shí)發(fā)送的信號。這個(gè)字段指定了停止容器時(shí)使用的信號,例如 SIGTERM 或 SIGKILL。

24.StopTimeout:停止容器的超時(shí)時(shí)間(以秒為單位)。這個(gè)字段指定了在發(fā)送停止信號后等待容器停止的時(shí)間。如果容器在超時(shí)時(shí)間內(nèi)未停止,則強(qiáng)制終止。

25.Shell:用于 shell 形式的 RUN、CMD、ENTRYPOINT 的 shell。這個(gè)字段指定了容器內(nèi)部使用的 shell 解釋器,用于執(zhí)行 Dockerfile 中的命令。omitempty 表示如果字段為空,則在 JSON 輸出中省略該字段。


基本操作demo

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
)

func main() {
	// 初始化 Docker 客戶端
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		panic(err)
	}

	//創(chuàng)建容器的配置信息
	createConfig := &container.Config{
		Image: "your_image_name",
		// 可以根據(jù)需要配置其他容器參數(shù)
	}

	//停止容器的配置信息
	stopConfig := container.StopOptions{}

	//刪除容器的配置信息
	removeOptions := types.ContainerRemoveOptions{
		RemoveVolumes: true, // 刪除容器關(guān)聯(lián)的卷
		Force:         true, // 強(qiáng)制刪除容器
	}

	// 列出所有容器的列表
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
	if err != nil {
		panic(err)
	}

	//操作每個(gè)容器的信息和容器的各種操作
	for _, dockerContainer := range containers {
		fmt.Printf("容器 ID:%s\n", dockerContainer.ID)
		fmt.Printf("容器 名稱:%s\n", dockerContainer.Names)

		// 在這里可以添加邏輯來判斷特定條件下的容器,并對其進(jìn)行操作
		// 例如,暫停、刪除等操作

		//容器的創(chuàng)建
		//使用容器的名字創(chuàng)建容器,配置文件配置鏡像等等信息。
		//創(chuàng)建容器的時(shí)候返回創(chuàng)建的容器ID
		createID, err := cli.ContainerCreate(context.Background(), createConfig, nil, nil, nil, "my-container-18")
		if err != nil {
			panic(err)
		}
		fmt.Println("創(chuàng)建的容器ID為: ", createID)

		//容器的刪除
		err = cli.ContainerRemove(context.Background(), dockerContainer.ID, removeOptions)
		if err != nil {
			panic(err)
		}

		//容器的暫停
		err = cli.ContainerPause(context.Background(), dockerContainer.ID)
		if err != nil {
			panic(err)
		}

		//容器的恢復(fù)
		err = cli.ContainerUnpause(context.Background(), dockerContainer.ID)
		if err != nil {
			panic(err)
		}

		//容器的停止
		err = cli.ContainerStop(context.Background(), dockerContainer.ID, stopConfig)
		if err != nil {
			panic(err)
		}

		//容器的重啟
		err = cli.ContainerRestart(context.Background(), dockerContainer.ID, stopConfig)
		if err != nil {
			panic(err)
		}
	}
}

查找容器信息

cmd

對應(yīng)于cmd的命令如下:

docker ps 

類似于cmd的方式,這里可以使用golang程序拿到如下字段信息,查出當(dāng)前運(yùn)行的所有容器的信息。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

/*
需求:
嘗試在golang中拉取鏡像、創(chuàng)建容器、刪除容器、停止容器、暫停容器、恢復(fù)容器、重啟容器。
運(yùn)行容器、怎么使用docker run去運(yùn)行一個(gè)容器、怎么使用docer build命令
看看其他在docker-cli中執(zhí)行的命令是否使用go程序也能夠正常執(zhí)行。
*/

func main() {
	// 初始化 Docker 客戶端
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		panic(err)
	}
	// 先得到列出所有容器的列表
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
	if err != nil {
		panic(err)
	}

	// 對應(yīng)為docker ps -a 命令
	// 再從列表中拿到信息
	for _, container := range containers {
		fmt.Printf("CONTAINER ID: %s\n", container.ID)
		fmt.Printf("IMAGE: %s \n", container.Image)
		fmt.Printf("COMMAND: %s \n", container.Command)
		fmt.Printf("CREATED: %s \n", container.Created)
		fmt.Printf("Status: %s \n", container.Status)
		fmt.Printf("PORTS: %s \n", container.Ports)
		fmt.Printf("NAMES:%s\n", container.Names)
	}
}

運(yùn)行結(jié)果

遍歷容器,拿到容器的各種字段信息,與docker ps 命令的信息一致。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

創(chuàng)建容器

cmd

運(yùn)行容器,一般是指定容器內(nèi)的端口和容器的名字(不能與之前的名字重復(fù))

--expose:編輯容器內(nèi)的端口

--name:編輯容器的名字

最后的my-golang-app 為鏡像源

docker run --expose 3888/tcp --name mycontainer-15 my-golang-app 

結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"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"
	"github.com/docker/go-connections/nat"
	"io"
	"log"
	"os"
)

func main() {
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		log.Fatal(err)
	}

    //配置容器的各種信息,如鏡像源、容器內(nèi)的端口
	containerConfig := &container.Config{
		Image: "my-golang-app",
		ExposedPorts: nat.PortSet{
			"3889/tcp": {},
		},
	}

	hostConfig := &container.HostConfig{}

	networkingConfig := &network.NetworkingConfig{}

	//創(chuàng)建容器
	resp, err := cli.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, nil, "mycontainer-20")
	if err != nil {
		log.Fatal(err)
	}

	//啟動容器
	if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
		log.Fatal(err)
	}
    //容器在后臺運(yùn)行
    //fmt.Println("容器ID為: " , resp.ID)
	
    // 獲取容器的日志
	out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true})
	if err != nil {
		log.Fatal(err)
	}
	defer out.Close()

	// 打印容器的日志到控制臺
	go func() {
		_, err := io.Copy(os.Stdout, out)
		if err != nil && err != io.EOF {
			log.Fatal(err)
		}
	}()

	// 等待容器運(yùn)行完成
	statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
	for {
		select {
		case err := <-errCh:
			if err != nil {
				log.Fatal(err)
			}
		case <-statusCh:
			return
		default:
			// 如果沒有接收到任何數(shù)據(jù),則繼續(xù)等待
		}
	}
}


運(yùn)行結(jié)果

查看創(chuàng)建的容器的基本信息,如容器的端口和名字等等。

對照一下,兩種方式創(chuàng)建的結(jié)果都是一樣的。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

程序中使用日志的方式打印出使用dockerfile的go程序運(yùn)行的結(jié)果,但是打印一個(gè)數(shù)字后被阻塞了。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

如果不使用上面程序的日志輸出,運(yùn)行時(shí)是以后臺的方式運(yùn)行的,也就不會直接把程序運(yùn)行的結(jié)果輸出來??梢韵葎?chuàng)建,再使用Attach方法進(jìn)入容器,就可以輸出程序的內(nèi)容了。具體見下面進(jìn)入容器部分。

刪除容器

cmd

docker rm -f 容器ID

查看結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"fmt"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要刪除的容器 ID
	containerID := "d815a35c7822"

	// 定義刪除容器時(shí)的選項(xiàng)
	options := types.ContainerRemoveOptions{
		Force:         true,  // 強(qiáng)制刪除容器
		RemoveVolumes: true,  // 刪除關(guān)聯(lián)的數(shù)據(jù)卷
		RemoveLinks:   false, // 不刪除關(guān)聯(lián)的鏈接
	}

	// 調(diào)用 ContainerRemove 方法刪除容器
	err = cli.ContainerRemove(context.Background(), containerID, options)
	if err != nil {
		fmt.Printf("Failed to remove container: %v\n", err)
	} else {
		fmt.Println("Container removed successfully")
	}
}

運(yùn)行結(jié)果

程序運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

刪除容器13之前

go 引入外部sdk,go,Docker,golang,后端,docker,容器

容器13成功刪除了

go 引入外部sdk,go,Docker,golang,后端,docker,容器


停止容器

cmd

docker stop 容器ID

停止容器前,狀態(tài)為Up

go 引入外部sdk,go,Docker,golang,后端,docker,容器

停止容器后,狀態(tài)為Exited

go 引入外部sdk,go,Docker,golang,后端,docker,容器


實(shí)例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types/container"

	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要停止的容器 ID
	containerID := "b50423e8aade"

	stopOptions := container.StopOptions{}

	// 調(diào)用 ContainerStop 方法停止容器
	err = cli.ContainerStop(context.Background(), containerID, stopOptions)
	if err != nil {
		fmt.Printf("Failed to stop container: %v\n", err)
	} else {
		fmt.Println("Container stopped successfully")
	}
}

運(yùn)行結(jié)果

程序執(zhí)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

檢查是否停止成功如下:

停止前

go 引入外部sdk,go,Docker,golang,后端,docker,容器

停止后

go 引入外部sdk,go,Docker,golang,后端,docker,容器

程序執(zhí)行結(jié)果與cmd停止命令一致。

重啟容器

cmd

docker restart 9ef8ae3b59d9

容器已停止:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

重啟容器:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

重啟容器后,容器的狀態(tài)如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types/container"

	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要重啟的容器 ID
	containerID := "746a98dfb20c"

	topOptions := container.StopOptions{}

	// 調(diào)用 ContainerRestart 方法重啟容器
	err = cli.ContainerRestart(context.Background(), containerID, topOptions)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Container %s has been restarted.\n", containerID)
}

運(yùn)行結(jié)果

重啟前:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

重啟后:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

重啟完成,和cmd的執(zhí)行結(jié)果一致。

暫停容器

cmd

docker pause 容器ID

暫停容器前

go 引入外部sdk,go,Docker,golang,后端,docker,容器

暫停容器后

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要暫停的容器 ID
	containerID := "e4d6650df3af"

	// 暫停容器
	err = cli.ContainerPause(context.Background(), containerID)
	if err != nil {
		fmt.Printf("Failed to pause container: %v\n", err)
	} else {
		fmt.Println("Container paused successfully")
	}
}

運(yùn)行結(jié)果

暫停容器前:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

暫停容器:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

恢復(fù)暫停

cmd

docker unpause 容器ID

恢復(fù)暫停前:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

恢復(fù)暫停成功:

go 引入外部sdk,go,Docker,golang,后端,docker,容器


實(shí)例

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要暫停的容器 ID
	containerID := "e4d6650df3af"

	// 暫停容器
	err = cli.ContainerPause(context.Background(), containerID)
	if err != nil {
		fmt.Printf("Failed to pause container: %v\n", err)
	} else {
		fmt.Println("Container paused successfully")
	}
}

運(yùn)行結(jié)果

恢復(fù)前:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

恢復(fù)暫停:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

說明確實(shí)是恢復(fù)暫停成功了!

進(jìn)入容器

Attach

cmd
docker attach 容器ID

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

退出容器,發(fā)現(xiàn)容器也停止掉了。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

注意: 這種進(jìn)入容器的方式使用exit退出會把整個(gè)容器都停止掉。但是使用go的程序停止卻不會使得容器停止。

實(shí)例

要進(jìn)入容器,可以使用 Docker 客戶端的 ContainerAttach 方法。這個(gè)方法允許您連接到容器的標(biāo)準(zhǔn)輸入、輸出和錯(cuò)誤流,并與容器進(jìn)行交互。

package main

import (
	"context"
	"fmt"
	"io"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要進(jìn)入的容器 ID
	containerID := "e4d6650df3af"

	// 定義進(jìn)入容器時(shí)的選項(xiàng)
	options := types.ContainerAttachOptions{
		Stream: true,
		Stdin:  true,
		Stdout: true,
		Stderr: true,
	}

	// 調(diào)用 ContainerAttach 方法進(jìn)入容器
	resp, err := cli.ContainerAttach(context.Background(), containerID, options)
	if err != nil {
		panic(err)
	}
	defer resp.Close()

	// 將容器的標(biāo)準(zhǔn)輸入輸出連接到當(dāng)前進(jìn)程的標(biāo)準(zhǔn)輸入輸出
	go io.Copy(os.Stdout, resp.Reader)
	go io.Copy(resp.Conn, os.Stdin)

	// 等待用戶輸入以繼續(xù)運(yùn)行
	fmt.Println("Press enter to exit...")
	fmt.Scanln()
}

運(yùn)行結(jié)果

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

退出程序:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

退出程序但是不會停止掉程序:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

ExecAttach

cmd
docker exec -it mycontainer-18 bash

這樣的進(jìn)入容器是以命令行的方式進(jìn)入容器的,所以不會輸出程序的運(yùn)行結(jié)果,但是使用exit退出程序不會關(guān)閉程序。

退出程序:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

使用exit退出程序,發(fā)現(xiàn)確實(shí)是沒有關(guān)閉程序。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例
package main

import (
	"context"
	"fmt"
	"io"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要進(jìn)入的容器 ID
	containerID := "e4d6650df3af"

	// 定義要執(zhí)行的命令
	cmd := []string{"sh"} // 這里可以根據(jù)需要修改為其他交互式 shell,如 bash

	// 準(zhǔn)備執(zhí)行命令的選項(xiàng)
	createResp, err := cli.ContainerExecCreate(context.Background(), containerID, types.ExecConfig{
		Cmd:          cmd,
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Tty:          true,
	})
	if err != nil {
		panic(err)
	}

	// 連接到正在運(yùn)行的命令以進(jìn)行交互
	resp, err := cli.ContainerExecAttach(context.Background(), createResp.ID, types.ExecStartCheck{
		Tty: true,
	})
	if err != nil {
		panic(err)
	}
	defer resp.Close()

	// 將容器的標(biāo)準(zhǔn)輸入輸出連接到當(dāng)前進(jìn)程的標(biāo)準(zhǔn)輸入輸出
	go func() {
		if _, err := io.Copy(os.Stdout, resp.Reader); err != nil {
			panic(err)
		}
	}()

	go func() {
		if _, err := io.Copy(resp.Conn, os.Stdin); err != nil {
			panic(err)
		}
	}()

	// 等待用戶輸入以繼續(xù)運(yùn)行
	fmt.Println("Press enter to exit...")
	fmt.Scanln()
}

運(yùn)行結(jié)果

以命令行的方式進(jìn)入容器進(jìn)行交互,和直接使用cmd的方式是一樣的。

go 引入外部sdk,go,Docker,golang,后端,docker,容器

小結(jié)

以上兩種方式都可以進(jìn)入容器,需要結(jié)合具體使用場景進(jìn)行權(quán)衡。

  • 其中一個(gè)是可以看到程序的執(zhí)行結(jié)果,但是退出會直接關(guān)閉掉容器。
  • 另一個(gè)是以命令行的方式進(jìn)入容器進(jìn)行交互,退出不會直接關(guān)閉容器。

拉取鏡像

cmd

對應(yīng)到cmd命令如下:

docker pull 鏡像名

如下:

docker pull nginx:latest

拉取結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要拉取的鏡像的名稱和標(biāo)簽
	imageName := "redis"
	imageTag := "latest"
	imageRef := imageName + ":" + imageTag

	// 拉取鏡像
	out, err := cli.ImagePull(context.Background(), imageRef, types.ImagePullOptions{})
	if err != nil {
		panic(err)
	}
	defer out.Close()

	// 解析拉取鏡像的輸出
	var pullResponse struct {
		Status string `json:"status"`
	}
	if err := json.NewDecoder(out).Decode(&pullResponse); err != nil {
		panic(err)
	}

	fmt.Printf("Pulling image %s: %s\n", imageRef, pullResponse.Status)
}

運(yùn)行結(jié)果

拉取鏡像成功,和cmd拉取鏡像的方式一致。

go 引入外部sdk,go,Docker,golang,后端,docker,容器


拉取鏡像

cmd

對應(yīng)到cmd命令如下:

docker pull 鏡像名

如下:

docker pull nginx:latest

拉取結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

實(shí)例

package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewEnvClient()
	if err != nil {
		panic(err)
	}

	// 定義要拉取的鏡像的名稱和標(biāo)簽
	imageName := "redis"
	imageTag := "latest"
	imageRef := imageName + ":" + imageTag

	// 拉取鏡像
	out, err := cli.ImagePull(context.Background(), imageRef, types.ImagePullOptions{})
	if err != nil {
		panic(err)
	}
	defer out.Close()

	// 解析拉取鏡像的輸出
	var pullResponse struct {
		Status string `json:"status"`
	}
	if err := json.NewDecoder(out).Decode(&pullResponse); err != nil {
		panic(err)
	}

	fmt.Printf("Pulling image %s: %s\n", imageRef, pullResponse.Status)
}

運(yùn)行結(jié)果

拉取鏡像成功,和cmd拉取鏡像的方式一致。

go 引入外部sdk,go,Docker,golang,后端,docker,容器


更新容器

應(yīng)用場景

  1. 動態(tài)調(diào)整資源限制: 您可能希望根據(jù)應(yīng)用程序的負(fù)載情況動態(tài)調(diào)整容器的資源限制,例如內(nèi)存限制、CPU 配額等。通過更新容器配置,您可以在不停止容器的情況下調(diào)整這些限制,從而使容器能夠適應(yīng)不同的負(fù)載。
  2. 修改網(wǎng)絡(luò)配置: 在某些情況下,您可能需要修改容器的網(wǎng)絡(luò)配置,例如更改容器的端口映射、連接到不同的網(wǎng)絡(luò)或修改容器的主機(jī)名等。通過更新容器配置,您可以實(shí)現(xiàn)這些網(wǎng)絡(luò)配置的變更,而無需重新創(chuàng)建容器。
  3. 更新掛載卷: 如果您使用了掛載卷來與容器共享數(shù)據(jù)或配置文件,可能會需要在運(yùn)行時(shí)更新掛載卷的配置。通過更新容器配置,您可以修改容器掛載的卷,例如更改卷的路徑或添加新的掛載卷。
  4. 應(yīng)用配置更改: 在某些情況下,您可能需要更新容器中運(yùn)行的應(yīng)用程序的配置。通過更新容器配置,您可以傳遞新的環(huán)境變量、更新容器的命令或參數(shù)等,從而修改容器中應(yīng)用程序的配置。

總的來說,ContainerUpdate 方法可以用于在容器運(yùn)行時(shí)對其進(jìn)行動態(tài)配置更改,而不需要停止和重新啟動容器。這種能力使得容器的管理更加靈活,并能夠在不中斷服務(wù)的情況下進(jìn)行必要的調(diào)整和更新。

cmd

docker update命令用于更新一個(gè)正在運(yùn)行的容器的配置。它允許你修改容器的資源限制、重啟策略和其他配置選項(xiàng)。以下是docker update命令的基本用法:

docker update 容器id/名字

實(shí)例

cli.ContainerUpdate 更新容器的資源限制、重啟策略和其他配置選項(xiàng),并不是更新容器的鏡像、端口之類的配置。其他暫無直接更新的API

采用:先刪除原有容器,再根據(jù)配置信息進(jìn)行重建的封裝函數(shù)。不過,這么做需要會影響容器內(nèi)正在運(yùn)行的服務(wù),需要考慮一下。

更新的結(jié)構(gòu)體如下:

updateConfig := container.UpdateConfig{
		Resources: container.Resources{
			Memory:   512000000,  // 設(shè)置內(nèi)存限制為 512MB
			NanoCPUs: 1000000000, // 設(shè)置 CPU 配額(以納秒為單位)
		},
	}

端口和掛載卷配置示例:

// 容器端口映射,鍵為容器端口,值為宿主機(jī)端口
	portMapping := map[string]string{
		"80/tcp": "8080",
	}

	// 容器掛載卷
	volumeMounts := []mount.Mount{
		{
			Type:   mount.TypeBind,
			Source: "/host/path", // 宿主機(jī)路徑
			Target: "/container/path", // 容器路徑
		},
	}

demo

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/client"
)

func main() {
	// 創(chuàng)建 Docker 客戶端
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		log.Fatal(err)
	}

	// 容器ID,需要根據(jù)實(shí)際情況修改
	containerID := "your_container_id_here"

	// 配置更新
	updateConfig := container.UpdateConfig{
		Resources: container.Resources{
			Memory:   512000000,  // 設(shè)置內(nèi)存限制為 512MB
			NanoCPUs: 1000000000, // 設(shè)置 CPU 配額(以納秒為單位)
		},
	}

	// 執(zhí)行容器更新
	err = updateContainer(cli, containerID, updateConfig)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("容器配置已更新")
}

// updateContainer 函數(shù)用于更新容器的配置信息
func updateContainer(cli *client.Client, containerID string, updateConfig container.UpdateConfig) error {
	ctx := context.Background()

	// 執(zhí)行容器更新
	_, err := cli.ContainerUpdate(ctx, containerID, updateConfig)
	if err != nil {
		return err
	}

	return nil
}

運(yùn)行結(jié)果

更新容器的內(nèi)存資源限制(單位bytes)

運(yùn)行結(jié)果如下:

go 引入外部sdk,go,Docker,golang,后端,docker,容器

補(bǔ)充

還了解到一個(gè)方法:cli.ConfigUpdate() ,不過這個(gè)更新不是更新容器信息的,可更新的配置信息也非常少,基本與容器無關(guān)。

后面了解到,其實(shí)它主要用于更新 Docker Swarm 配置的信息。

在 Docker 中,Swarm 是 Docker 官方提供的用于容器編排集群管理的工具。Swarm 允許您將多個(gè) Docker 主機(jī)組合成一個(gè)虛擬的、單一的 Docker 主機(jī)。Swarm 中有許多配置項(xiàng)可以控制集群的行為,例如服務(wù)配置、網(wǎng)絡(luò)配置、秘密配置等。

方法體如下:

// ConfigUpdate attempts to update a config
func (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {
	if err := cli.NewVersionError(ctx, "1.30", "config update"); err != nil {
		return err
	}
	query := url.Values{}
	query.Set("version", version.String())
	resp, err := cli.post(ctx, "/configs/"+id+"/update", query, config, nil)
	ensureReaderClosed(resp)
	return err
}

待配置結(jié)構(gòu)體swarm.ConfigSpec信息如下:

// ConfigSpec represents a config specification from a config in swarm
type ConfigSpec struct {
	Annotations
	Data []byte `json:",omitempty"`

	// Templating controls whether and how to evaluate the config payload as
	// a template. If it is not set, no templating is used.
	Templating *Driver `json:",omitempty"`
}

Annotations字段信息如下:

// Annotations represents how to describe an object.
type Annotations struct {
	Name   string            `json:",omitempty"`
	Labels map[string]string `json:"Labels"`
}

容器函數(shù)庫

將上面的各個(gè)函數(shù)集成到一個(gè)文件,形成一個(gè)函數(shù)庫,便于用戶使用和調(diào)用。

package main

import (
	"context"
	"encoding/json"
	"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"
	"github.com/docker/go-connections/nat"
	"github.com/opencontainers/image-spec/specs-go/v1"
	"io"
	"log"
	"os"
)

func main() {
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		log.Fatal(err)
	}
	//查找容器信息
	getInfoOptions := types.ContainerListOptions{}
	getContainerInfo(cli, getInfoOptions)

	//配置創(chuàng)建容器的屬性
	containerConfig := &container.Config{
		Image: "my-golang-app",
		ExposedPorts: nat.PortSet{
			"3889/tcp": {},
		},
	}

	//配置容器主機(jī)的屬性
	//主要用于配置容器的運(yùn)行環(huán)境和資源限制等主機(jī)級別的設(shè)置
	//配置的是容器的主機(jī)配置,而不是宿主機(jī)(即物理計(jì)算機(jī)或虛擬機(jī))的主機(jī)配置。
	hostConfig := &container.HostConfig{}

	//主要用于配置容器的網(wǎng)絡(luò)連接和端口映射等網(wǎng)絡(luò)設(shè)置
	networkingConfig := &network.NetworkingConfig{}

	//主要用于指定容器的運(yùn)行平臺信息,以便 Docker 在部署時(shí)選擇合適的環(huán)境。
	platformConfig := &v1.Platform{}

	//創(chuàng)建的容器名字,唯一標(biāo)識
	containerName := "mycontainer-30"

	//調(diào)用createContainer創(chuàng)建容器并啟動
	containerId, err := createContainer(cli, containerConfig, hostConfig, networkingConfig, platformConfig, containerName)
	fmt.Printf("容器%s已創(chuàng)建好 ", containerId)

	// 刪除容器是通過Id進(jìn)行刪除的,需要根據(jù)名字查找到容器Id
	// 根據(jù)容器的名字查找出要刪除容器的Id
	containerID, err := getContainerIDByName(cli, containerName)
	if err != nil {
		log.Fatal(err)
	}

	// 定義刪除容器時(shí)的選項(xiàng)
	removeOptions := types.ContainerRemoveOptions{
		Force:         true,  // 強(qiáng)制刪除容器
		RemoveVolumes: true,  // 刪除關(guān)聯(lián)的數(shù)據(jù)卷
		RemoveLinks:   false, // 不刪除關(guān)聯(lián)的鏈接
	}
	// 調(diào)用removeContainer刪除容器
	removeContainer(cli, containerID, removeOptions)

	//根據(jù)容器的新配置重新創(chuàng)建容器
	reUpdateContainer(cli, removeOptions, containerConfig, hostConfig, networkingConfig, platformConfig, containerName)

	// 停止容器
	stopOptions := container.StopOptions{}
	stopContainer(cli, containerID, stopOptions)
	// 重啟容器
	restartContainer(cli, containerID, stopOptions)

	// 暫停容器
	pauseContainer(cli, containerID)
	// 恢復(fù)暫停
	unpauseContainer(cli, containerID)

	// 定義進(jìn)入容器時(shí)的選項(xiàng)
	attachOptions := types.ContainerAttachOptions{
		Stream: true,
		Stdin:  true,
		Stdout: true,
		Stderr: true,
	}
	attachContainer(cli, containerID, attachOptions)

	// 定義以命令行進(jìn)入容器的選項(xiàng)
	execAttachConfig := types.ExecConfig{
		Cmd:          []string{"sh"},
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Tty:          true,
	}
	execAttachCheck := types.ExecStartCheck{
		Tty: true,
	}
	execAttachContainer(cli, containerID, execAttachConfig, execAttachCheck)

	// 定義拉取鏡像的選項(xiàng)
	// 定義要拉取的鏡像的名稱和標(biāo)簽
	imageName := "redis"
	imageTag := "latest"
	imageRef := imageName + ":" + imageTag
	imagePulloptions := types.ImagePullOptions{}
	pullImage(cli, imageRef, imagePulloptions)

	//獲取容器內(nèi)所有鏡像的信息
	getImageOptions := types.ImageListOptions{}
	err = getAllImagesInfo(cli, getImageOptions)
	if err != nil {
		log.Fatal(err)
	}

	// 定義更新容器的選項(xiàng)
	// 更新容器配置信息
	// 配置更新
	updateConfig := container.UpdateConfig{
		Resources: container.Resources{
			// Minimum memory limit allowed is 6MB
			// 單位為byte(字節(jié)數(shù))
			Memory:     60000000,
			MemorySwap: 60000000, //設(shè)置Memory小于交換內(nèi)存MemorySwap 需要同時(shí)配置MemorySwap
			NanoCPUs:   1,        // 設(shè)置 CPU 配額(以納秒為單位)范圍: 0.01 - 8.00
		},
	}
	err = updateContainer(cli, containerID, updateConfig)
	if err != nil {
		log.Fatal(err)
	}

}

/*
作用: 查找出容器的所有信息(容器ID、鏡像名、端口、運(yùn)行狀態(tài)等等)
*/
func getContainerInfo(cli *client.Client, getInfoOptions types.ContainerListOptions) {
	// 先得到列出所有容器的列表
	containers, err := cli.ContainerList(context.Background(), getInfoOptions)
	if err != nil {
		panic(err)
	}

	// 對應(yīng)為docker ps -a 命令
	// 再從列表(map)中拿到信息
	for _, container := range containers {
		fmt.Printf("CONTAINER ID: %s\n", container.ID)
		fmt.Printf("IMAGE: %s \n", container.Image)
		fmt.Printf("COMMAND: %s \n", container.Command)
		fmt.Printf("CREATED: %s \n", container.Created)
		fmt.Printf("Status: %s \n", container.Status)
		fmt.Printf("PORTS: %s \n", container.Ports)
		fmt.Printf("NAMES:%s\n", container.Names)
	}
}

/*
作用: 根據(jù)容器名字和配置的創(chuàng)建選項(xiàng)創(chuàng)建容器
*/
func createContainer(cli *client.Client, containerConfig *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platformConfig *v1.Platform, containerName string) (containerId string, err error) {
	// 創(chuàng)建容器
	resp, err := cli.ContainerCreate(context.Background(), containerConfig, hostConfig, networkingConfig, platformConfig, containerName)
	if err != nil {
		log.Fatal(err)
	}
	// 啟動容器
	if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
		log.Fatal(err)
	}
	//返回創(chuàng)建好的容器ID
	return resp.ID, err
}

/*
作用: 根據(jù)容器ID和配置的刪除選項(xiàng)刪除容器
*/
func removeContainer(cli *client.Client, containerID string, removeOptions types.ContainerRemoveOptions) {
	// 調(diào)用 ContainerRemove 方法刪除容器
	err := cli.ContainerRemove(context.Background(), containerID, removeOptions)
	if err != nil {
		fmt.Printf("Failed to remove container: %v\n", err)
	} else {
		fmt.Println("Container removed successfully")
	}
}

/*
作用: 根據(jù)容器ID和配置的停止選項(xiàng)停止容器
*/
func stopContainer(cli *client.Client, containerID string, stopOptions container.StopOptions) {
	// 調(diào)用 ContainerStop 方法停止容器
	err := cli.ContainerStop(context.Background(), containerID, stopOptions)
	if err != nil {
		fmt.Printf("Failed to stop container: %v\n", err)
	} else {
		fmt.Println("Container stopped successfully")
	}
}

/*
作用: 根據(jù)容器ID和配置的停止選項(xiàng)重啟容器
*/
func restartContainer(cli *client.Client, containerID string, stopOptions container.StopOptions) {
	// 調(diào)用 ContainerRestart 方法重啟容器
	err := cli.ContainerRestart(context.Background(), containerID, stopOptions)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Container %s has been restarted.\n", containerID)
}

/*
作用: 根據(jù)容器ID暫停容器
*/
func pauseContainer(cli *client.Client, containerID string) {
	// 暫停容器
	err := cli.ContainerPause(context.Background(), containerID)
	if err != nil {
		fmt.Printf("Failed to pause container: %v\n", err)
	} else {
		fmt.Println("Container paused successfully")
	}
}

/*
作用: 根據(jù)容器ID恢復(fù)容器暫停
*/
func unpauseContainer(cli *client.Client, containerID string) {
	// 恢復(fù)暫停
	err := cli.ContainerUnpause(context.Background(), containerID)
	if err != nil {
		fmt.Printf("Failed to pause container: %v\n", err)
	} else {
		fmt.Println("Container paused successfully")
	}
}

/*
作用: 根據(jù)容器ID和配置的進(jìn)入選項(xiàng)進(jìn)入容器內(nèi)部
*/
func attachContainer(cli *client.Client, containerID string, attachOptions types.ContainerAttachOptions) {
	// 調(diào)用 ContainerAttach 方法進(jìn)入容器
	resp, err := cli.ContainerAttach(context.Background(), containerID, attachOptions)
	if err != nil {
		panic(err)
	}
	defer resp.Close()

	// 將容器的標(biāo)準(zhǔn)輸入輸出連接到當(dāng)前進(jìn)程的標(biāo)準(zhǔn)輸入輸出
	go io.Copy(os.Stdout, resp.Reader)
	go io.Copy(resp.Conn, os.Stdin)

	// 等待用戶輸入以繼續(xù)運(yùn)行
	fmt.Println("Press enter to exit...")
	fmt.Scanln()
}

/*
作用: 通過容器ID配置的進(jìn)入選項(xiàng)以命令行的方式進(jìn)入容器內(nèi)部
*/
func execAttachContainer(cli *client.Client, containerID string, execAttachConfig types.ExecConfig, execAttachCheck types.ExecStartCheck) {
	// 準(zhǔn)備執(zhí)行命令的選項(xiàng)
	createResp, err := cli.ContainerExecCreate(context.Background(), containerID, execAttachConfig)
	if err != nil {
		panic(err)
	}

	// 連接到正在運(yùn)行的命令以進(jìn)行交互
	resp, err := cli.ContainerExecAttach(context.Background(), createResp.ID, execAttachCheck)
	if err != nil {
		panic(err)
	}
	defer resp.Close()

	// 將容器的標(biāo)準(zhǔn)輸入輸出連接到當(dāng)前進(jìn)程的標(biāo)準(zhǔn)輸入輸出
	go func() {
		if _, err := io.Copy(os.Stdout, resp.Reader); err != nil {
			panic(err)
		}
	}()

	go func() {
		if _, err := io.Copy(resp.Conn, os.Stdin); err != nil {
			panic(err)
		}
	}()

	// 等待用戶輸入以繼續(xù)運(yùn)行
	fmt.Println("Press enter to exit...")
	fmt.Scanln()
}

/*
作用: 通過配置拉取的鏡像名和拉取選項(xiàng)拉取鏡像
*/
func pullImage(cli *client.Client, imageRef string, imagePulloptions types.ImagePullOptions) {
	// 拉取鏡像
	out, err := cli.ImagePull(context.Background(), imageRef, imagePulloptions)
	if err != nil {
		panic(err)
	}
	defer out.Close()

	// 解析拉取鏡像的輸出
	var pullResponse struct {
		Status string `json:"status"`
	}
	if err := json.NewDecoder(out).Decode(&pullResponse); err != nil {
		panic(err)
	}

	fmt.Printf("Pulling image %s: %s\n", imageRef, pullResponse.Status)
}

/*
作用: 通過容器ID和編寫的更新配置動態(tài)更新容器配置信息(主要是資源限制、重啟選項(xiàng))
*/
func updateContainer(cli *client.Client, containerID string, updateConfig container.UpdateConfig) error {
	// 執(zhí)行容器更新
	_, err := cli.ContainerUpdate(context.Background(), containerID, updateConfig)
	if err != nil {
		return err
	}
	fmt.Println("容器配置已更新")
	return nil
}

/*
作用: 根據(jù)容器名字和容器的新配置創(chuàng)建容器,用于對容器的配置進(jìn)行靜態(tài)的修改。
*/
func reUpdateContainer(cli *client.Client, removeOptions types.ContainerRemoveOptions, containerConfig *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platformConfig *v1.Platform, containerName string) {
	// 一開始調(diào)用函數(shù)時(shí)就要傳入創(chuàng)建、刪除容器的配置
	//傳入要刪除的名字,得到要刪除的容器ID。
	containerID, err := getContainerIDByName(cli, containerName)
	if err != nil {
		log.Fatal(err)
	}
	//刪除容器
	removeContainer(cli, containerID, removeOptions)

	//調(diào)用創(chuàng)建api,創(chuàng)建新的容器
	containerId, err := createContainer(cli, containerConfig, hostConfig, networkingConfig, platformConfig, containerName)
	fmt.Printf("容器%s已重新創(chuàng)建好 ", containerId)
}

/*
作用:通過容器名查找容器ID,常用于需要使用容器ID的容器操作
*/
func getContainerIDByName(cli *client.Client, containerName string) (string, error) {
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
	if err != nil {
		return "", err
	}

	for _, container := range containers {
		for _, name := range container.Names {
			// 注意: 容器名字以 "/" 開頭,例如:你創(chuàng)建的名字為mycontainer-30 實(shí)際在容器中為"/mycontainer-30"
			// 在查找時(shí)前面要拼接上一個(gè) /
			if name == "/"+containerName {
				return container.ID, nil
			}
		}
	}
	return "", fmt.Errorf("未找到容器名稱為 %s 的容器", containerName)
}

/*
作用: 獲取容器的所有鏡像信息(不包含鏡像的名字)
*/
func getAllImagesInfo(cli *client.Client, getImageOptions types.ImageListOptions) error {
	// 調(diào)用 Docker API 獲取所有鏡像的摘要信息
	images, err := cli.ImageList(context.Background(), getImageOptions)
	if err != nil {
		return err
	}

	// 打印每個(gè)鏡像的信息
	for _, image := range images {
		fmt.Printf("鏡像ID: %s\n", image.ID)
		fmt.Printf("標(biāo)簽: %s\n", image.Labels["com.docker.compose.version"])
		fmt.Printf("大小: %d bytes\n", image.Size)
		fmt.Println("--------------")
	}
	return nil
}

往期好文??

保姆級教程

【保姆級教程】Windows11下go-zero的etcd安裝與初步使用

【保姆級教程】Windows11安裝go-zero代碼生成工具goctl、protoc、go-zero

【Go-Zero】手把手帶你在goland中創(chuàng)建api文件并設(shè)置高亮


報(bào)錯(cuò)解決

【Go-Zero】Error: user.api 27:9 syntax error: expected ‘:‘ | ‘IDENT‘ | ‘INT‘, got ‘(‘ 報(bào)錯(cuò)解決方案及api路由注意事項(xiàng)

【Go-Zero】Error: only one service expected goctl一鍵轉(zhuǎn)換生成rpc服務(wù)錯(cuò)誤解決方案

【Go-Zero】【error】 failed to initialize database, got error Error 1045 (28000):報(bào)錯(cuò)解決方案

【Go-Zero】Error 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)報(bào)錯(cuò)解決方案

【Go-Zero】type mismatch for field “Auth.AccessSecret“, expect “string“, actual “number“報(bào)錯(cuò)解決方案

【Go-Zero】Error: user.api 30:2 syntax error: expected ‘)‘ | ‘KEY‘, got ‘IDENT‘報(bào)錯(cuò)解決方案

【Go-Zero】Windows啟動rpc服務(wù)報(bào)錯(cuò)panic:context deadline exceeded解決方案


Go面試向

【Go面試向】defer與time.sleep初探

【Go面試向】defer與return的執(zhí)行順序初探

【Go面試向】Go程序的執(zhí)行順序

【Go面試向】rune和byte類型的認(rèn)識與使用

【Go面試向】實(shí)現(xiàn)map穩(wěn)定的有序遍歷的方式文章來源地址http://www.zghlxwxcb.cn/news/detail-847712.html

到了這里,關(guān)于【Golang】golang使用三方SDK操作容器指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Golang 通過開源庫 go-redis 操作 NoSQL 緩存服務(wù)器

    前置條件: 1、導(dǎo)入庫: import ( \\\"github.com/go-redis/redis/v8\\\" ) 2、搭建哨兵模式集群 具體可以百度、谷歌搜索,網(wǎng)上現(xiàn)成配置教程太多了,不行還可以搜教程視頻,跟著視頻博主一步一個(gè)慢動作,慢慢整。 本文只介紹通過 “主從架構(gòu) / 哨兵模式” 訪問的形式,這是因?yàn)椋瑔蝹€(gè)

    2024年01月23日
    瀏覽(26)
  • 【Golang星辰圖】數(shù)據(jù)管理利器:Go編程語言中的數(shù)據(jù)庫和搜索引擎綜合指南

    Go編程語言是一種強(qiáng)大、類型安全且高效的編程語言,它在處理數(shù)據(jù)庫和搜索引擎方面有著廣泛的應(yīng)用。本篇文章將詳細(xì)介紹幾個(gè)Go編程語言中常用的數(shù)據(jù)庫和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。對于每個(gè)工具,我們將介紹其功

    2024年03月26日
    瀏覽(109)
  • 【Golang中的Go Module使用】

    Golang中的Go Module是一個(gè)用于包管理和版本控制的工具。在本文中,我們將深入探討Go Module的相關(guān)知識,包括其定義、使用方法以及一些常見的應(yīng)用場景。 Go Module是Golang中的包管理和版本控制工具,它的發(fā)展歷程、用法、意義以及相關(guān)指令都對于Golang開發(fā)者來說非常重要。在本

    2024年02月16日
    瀏覽(18)
  • 【Golang】Golang進(jìn)階系列教程--為什么 Go 語言 struct 要使用 tags

    【Golang】Golang進(jìn)階系列教程--為什么 Go 語言 struct 要使用 tags

    在 Go 語言中,struct 是一種常見的數(shù)據(jù)類型,它可以用來表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在 struct 中,我們可以定義多個(gè)字段,每個(gè)字段可以有不同的類型和名稱。 除了這些基本信息之外,Go 還提供了 struct tags,它可以用來指定 struct 中每個(gè)字段的元信息。 在本文中,我們將探討為什

    2024年02月15日
    瀏覽(39)
  • 【GoLang】哪些大公司正在使用Go語言

    【GoLang】哪些大公司正在使用Go語言

    前言: 隨著計(jì)算機(jī)科學(xué)和軟件開發(fā)的快速發(fā)展,編程語言的選擇變得愈加關(guān)鍵。 在這個(gè)多元化的編程語境中,Go語言(簡稱Golang)以其簡潔、高效、并發(fā)處理能力等特性逐漸受到業(yè)界關(guān)注。 越來越多的大型科技公司紛紛采用Go語言作為其軟件開發(fā)的首選語言,這種趨勢反映了

    2024年02月04日
    瀏覽(17)
  • 使用 Go (Golang) 使用 OpenCV 繪制對象 GoCV

    使用 Go (Golang) 使用 OpenCV 繪制對象 GoCV

    本文將向你展示如何使用 OpenCV 使用 Go 編程語言 (Golang) 和 GoCV 包繪制直線、正方形、圓形和橢圓形對象。 OpenCV 是一個(gè)主要用于實(shí)時(shí)計(jì)算機(jī)視覺的編程函數(shù)庫。最初由 Intel 開發(fā),然后由 Willow Garage 和 Itseez 提供支持。這個(gè)庫是跨平臺的,可以在開源 Apache 2 許可下免費(fèi)使用。

    2024年02月07日
    瀏覽(23)
  • Golang編寫客戶端SDK,并開源發(fā)布包到GitHub,供其他項(xiàng)目import使用

    Golang編寫客戶端SDK,并開源發(fā)布包到GitHub,供其他項(xiàng)目import使用

    如果希望其他項(xiàng)目能夠使用該SDK,可以將該SDK打包為一個(gè)Go模塊,并將其發(fā)布到Go模塊倉庫中。這將使其他項(xiàng)目能夠通過Go的模塊依賴機(jī)制來使用該SDK。可以輕松地引用和使用你的代碼。 登錄到你的 GitHub 帳戶。 在 GitHub 主頁點(diǎn)擊右上角的加號(+),然后選擇 “New repository”(

    2024年02月09日
    瀏覽(28)
  • 【Docker】golang使用DockerFile正確食用指南

    【Docker】golang使用DockerFile正確食用指南

    大家好 我是寸鐵?? 總結(jié)了一篇golang使用DockerFile正確食用指南? 喜歡的小伙伴可以點(diǎn)點(diǎn)關(guān)注 ?? 今天寸鐵想讓編寫好的 go 程序在 docker 上面跑,要想實(shí)現(xiàn)這樣的效果,就需要用到今天的主角: Docker File ,那怎么使用 DockerFile 呢? 那具體怎么做呢?其實(shí)很簡單,不過網(wǎng)上的博

    2024年03月12日
    瀏覽(29)
  • golang利用go mod巧妙替換使用本地項(xiàng)目的包

    golang利用go mod巧妙替換使用本地項(xiàng)目的包

    ??拉了兩個(gè)項(xiàng)目下來,其中一個(gè)項(xiàng)目依賴另一個(gè)項(xiàng)目,因?yàn)楦膭恿吮灰蕾嚨捻?xiàng)目,想重新導(dǎo)入測試一下。 ??go.mod文件的require中想要被代替的包名在replace中進(jìn)行一個(gè)替換,注意:用來替換的需要用絕對路徑,一開始我用~/Documents/xboot/xboot/tools/reflect沒有效果。 ??這樣原

    2024年02月15日
    瀏覽(28)
  • golang IDE 使用 go-1.7 無法識別 goroot問題

    golang IDE 使用 go-1.7 無法識別 goroot問題

    當(dāng)前使用了 golang IDE 要設(shè)定 go-1.17 版本作為默認(rèn) GOROOT 系統(tǒng)環(huán)境變量已經(jīng)定義好 打開了 ide 會出現(xiàn)下面問題,選擇 1.17 后會出現(xiàn)下面報(bào)錯(cuò) The selected directory is not a valid horne for GO SDK 修改 $GOROOT 下文件增加一個(gè)變量 再次在 IDC 選擇 GOROOT 就可以找到 go 1.17.2 版本 選擇后,需要關(guān)閉

    2024年02月16日
    瀏覽(47)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包