go通过docker sdk来对容器资源做限制

发布时间 2023-07-20 14:06:08作者: 厚礼蝎

创建容器时

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/mount"
	"github.com/docker/docker/client"
	"github.com/docker/go-connections/nat"
)

func main() {
	// 设置远程Docker守护进程的地址
	remoteDockerURL := "tcp://10.0.0.12:2376" // 将remote-docker-host替换为远程Docker守护进程的IP地址或域名

	// 创建Docker客户端,并指定远程Docker守护进程地址
	cli, err := client.NewClientWithOpts(
		client.WithHost(remoteDockerURL),
		// client.WithVersion("1.41"),
		client.WithAPIVersionNegotiation(),
	)
	if err != nil {
		fmt.Println("创建docker客户端失败:", err)
		os.Exit(1)
	}
	// 关闭Docker客户端连接
	defer cli.Close()
	// 配置要启动的容器
	containerConfig := &container.Config{
		Image: "nginx:latest", // 指定要使用的镜像
		// 其他容器配置项,例如:Cmd、Env等
	}
	// 设置资源限制,例如:内存限制和CPU限制
	limitCPU := int64(1)                    // 设置CPU限制为1核
	limitMemory := int64(256 * 1024 * 1024) // 设置内存限制为256MB
	// 配置容器自动重启
	hostConfig := &container.HostConfig{
		RestartPolicy: container.RestartPolicy{
			Name: "always", // 设置重启策略为"always",容器将总是自动重启
			// 可选的重启策略:
			// - "no":无重启策略
			// - "always":容器总是自动重启
			// - "on-failure":容器在非零退出状态时重启(默认最多重启3次)
			// - "unless-stopped":除非手动停止,否则容器总是自动重启
		},
		PortBindings: nat.PortMap{
			"80/tcp": []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: "8080"}}, // 将容器的80端口映射到宿主机的8080端口
		},
		Mounts: []mount.Mount{
			{
				Type:     mount.TypeBind,
				Source:   "/data/html",            // 宿主机上要挂载的文件夹路径
				Target:   "/usr/share/nginx/html", // 容器内挂载的路径
				ReadOnly: false,                   // 是否只读
			},
		},
		Resources: container.Resources{
			CpusetCpus: "",                // 设置CPU核心绑定
			Memory:     limitMemory,       // 设置内存限制 单位是字节(Byte)。
			MemorySwap: limitMemory,       // 设置内存+swap限制 单位是字节(Byte)。
			CPUPeriod:  100000,            // 设置CPU周期 单位是微秒(μs)
			CPUQuota:   limitCPU * 100000, // 设置CPU配额 单位是微秒(μs)
		},
	}
	// 设置容器名称
	containerName := "nginx"
	// 创建并启动容器
	resp, err := cli.ContainerCreate(context.Background(), containerConfig, hostConfig, nil, nil, containerName)
	if err != nil {
		fmt.Println("容器创建失败:", err)
		return
	}

	// 启动容器
	if err := cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{}); err != nil {
		fmt.Println("容器创建失败:", err)
		return
	}

	fmt.Println("容器创建成功,容器ID:", resp.ID)
}

更新现有容器

package main

import (
	"context"
	"fmt"
	"os"

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

func main() {
	// 设置远程Docker守护进程的地址
	remoteDockerURL := "tcp://10.0.0.12:2376" // 将remote-docker-host替换为远程Docker守护进程的IP地址或域名

	// 创建Docker客户端,并指定远程Docker守护进程地址
	cli, err := client.NewClientWithOpts(
		client.WithHost(remoteDockerURL),
		// client.WithVersion("1.41"),
		client.WithAPIVersionNegotiation(),
		client.WithTLSClientConfig("cert/ca.pem", "cert/cert.pem", "cert/key.pem"),
	)
	if err != nil {
		fmt.Println("创建docker客户端失败:", err)
		os.Exit(1)
	}
	// 关闭Docker客户端连接
	defer cli.Close()
	// 替换containerID为实际的容器ID
	containerID := "nginx"

	// 设置资源限制,例如:内存限制和CPU限制
	limitCPU := int64(1)                     // 设置CPU限制为1核
	limitMemory := int64(2560 * 1024 * 1024) // 设置内存限制为256MB

	// 创建容器的更新配置
	updateConfig := container.UpdateConfig{
		Resources: container.Resources{
			CPUPeriod:        200000,            // 设置CPU周期
			CPUQuota:         limitCPU * 200000, // 设置CPU配额
			Memory:           limitMemory,       // 设置内存限制
			MemorySwap:       limitMemory,       // 设置内存+swap限制
			MemorySwappiness: nil,               // 设置内存swappiness
		},
	}
	// 创建并启动容器
	resp, err := cli.ContainerUpdate(context.Background(), containerID, updateConfig)
	if err != nil {
		fmt.Println("容器创建失败:", err)
		return
	}
	fmt.Println("容器资源限制已成功更新!", resp.Warnings)
}

container.Resources 结构体中的各项属性

  1. CPUShares (int64): CPU共享权重。该值表示容器与其他容器之间CPU共享的权重。具有较高CPUShares值的容器将获得更多的CPU时间。
  2. Memory (int64): 内存限制。该值表示容器可使用的内存限制,单位为字节(Byte)。
  3. NanoCPUs (int64): CPU配额。该值表示CPU资源分配的配额,单位为10-9 CPUs。CPU配额指定在一个CPU周期容器可以使用的CPU时间。
  4. CgroupParent (string): 父cgroup。在UNIX平台上,可以通过设置CgroupParent来指定容器的cgroup父节点。
  5. BlkioWeight (uint16): 块IO权重。该值表示容器与其他容器之间块IO资源共享的权重。
  6. BlkioWeightDevice ([]*blkiodev.WeightDevice): 块IO权重设备配置。
  7. BlkioDeviceReadBps ([]*blkiodev.ThrottleDevice): 块IO设备读取速率限制配置。
  8. BlkioDeviceWriteBps ([]*blkiodev.ThrottleDevice): 块IO设备写入速率限制配置。
  9. BlkioDeviceReadIOps ([]*blkiodev.ThrottleDevice): 块IO设备读取IOps限制配置。
  10. BlkioDeviceWriteIOps ([]*blkiodev.ThrottleDevice): 块IO设备写入IOps限制配置。
  11. CPUPeriod (int64): CPU CFS (Completely Fair Scheduler)周期。该值表示CPU资源分配的周期,单位为微秒(μs)。CPU周期是限制CPU配额的基本时间单位。
  12. CPUQuota (int64): CPU CFS (Completely Fair Scheduler)配额。该值表示CPU资源分配的配额,单位为微秒(μs)。CPU配额指定在一个CPU周期内容器可以使用的CPU时间。
  13. CPURealtimePeriod (int64): 实时CPU周期。该值表示容器实时CPU资源分配的周期,单位为微秒(μs)。实时CPU周期用于实时任务,例如音频或视频处理。
  14. CPURealtimeRuntime (int64): 实时CPU运行时间。该值表示容器实时CPU资源分配的运行时间,单位为微秒(μs)。实时CPU运行时间用于实时任务,例如音频或视频处理。
  15. CpusetCpus (string): 设置容器绑定到特定的CPU核心。可以设置为一个或多个CPU核心的编号,例如:"0"表示绑定到第一个CPU核心,"0,1"表示绑定到第一个和第二个CPU核心。
  16. CpusetMems (string): 设置容器绑定到特定的内存节点。可以设置为一个或多个内存节点的编号,例如:"0"表示绑定到第一个内存节点,"0,1"表示绑定到第一个和第二个内存节点。
  17. Devices ([]DeviceMapping): 列表设备映射。可以通过Devices字段将主机设备映射到容器内部。
  18. DeviceCgroupRules ([]string): 列表规则设备cgroup。可以通过DeviceCgroupRules字段将规则添加到容器的设备cgroup中。
  19. DeviceRequests ([]DeviceRequest): 列表设备请求。可以通过DeviceRequests字段向容器驱动程序发出设备请求。
  20. KernelMemory (int64): 内核内存限制。该值表示容器使用的kernel memory限制,单位为字节(Byte)。此字段已被标记为过时(Deprecated),在某些版本的kernel中可能不再起作用。
  21. KernelMemoryTCP (int64): 内核TCP缓冲区内存限制。该值表示容器使用的内核TCP缓冲区内存限制,单位为字节(Byte)。
  22. MemoryReservation (int64): 内存保留。该值表示容器至少保留的内存大小,单位为字节(Byte)。当系统内存不足时,这个值可以帮助系统决定是否强制暂停或终止容器。
  23. MemorySwap (int64): 内存+swap限制。该值表示容器可使用的内存+swap的总限制,单位为字节(Byte)。设置为-1时表示启用无限交换空间。
  24. MemorySwappiness (*int64): 内存swappiness行为。指定容器的内存swappiness值,可以设置为nil表示使用系统默认值。
  25. OomKillDisable (*bool): 是否禁用OOM Killer。设置为true表示禁用OOM Killer,不允许容器被OOM Killer杀死。
  26. PidsLimit (*int64): 设置容器的PIDs限制。可以设置为0-1表示无限制,设置为nil表示不修改现有的PIDs限制。
  27. Ulimits ([]*units.Ulimit): 列表ulimits限制。可以通过Ulimits字段设置容器中的ulimits限制。
  28. CPUCount (int64): 适用于Windows平台的CPU个数限制。
  29. CPUPercent (int64): 适用于Windows平台的CPU使用百分比限制。
  30. IOMaximumIOps (uint64): 适用于Windows平台的系统驱动器的最大IOps限制。
  31. IOMaximumBandwidth (uint64): 适用于Windows平台的系统驱动器的最大IO带宽限制。

请注意,每个字段在不同的Docker版本和操作系统平台上可能会有所不同。在使用container.Resources时,请根据您使用的Docker版本和操作系统平台进行相应的调整。