Python docker库基本使用

目录

python docker库创建、编译、提交镜像

python docker库实时获取容器运行状态

python docker库查看某个容器是否存在

container.exec_run()参数详解

docker库client.images.build()参数详解

client.images.build返回内容详解

python-docker库自动化部署


python docker库创建、编译、提交镜像

要在Python中使用Docker库来创建、编译和提交镜像,你可以按照以下步骤进行操作:

  1. 安装Docker库 首先,你需要安装Docker库。你可以使用pip命令来安装它:

pip install docker

创建Docker客户端 接下来,你需要创建一个Docker客户端来与Docker引擎进行通信。你可以使用以下代码来创建一个Docker客户端:

import docker
​
client = docker.from_env()
  1. 创建镜像 接下来,你可以使用Docker客户端来创建一个镜像。你可以使用以下代码来创建一个镜像:

client.images.build(path="path_to_dockerfile", tag="image_tag")

在这里,path_to_dockerfile是Dockerfile的路径,image_tag是你想要给镜像的标签。

  1. 编译镜像 一旦你创建了镜像,你可以使用以下代码来编译它:

client.images.build(path="path_to_dockerfile", tag="image_tag", buildargs={"key": "value"})

在这里,buildargs参数允许你传递构建参数给Dockerfile。

  1. 提交镜像 最后,你可以使用以下代码来提交镜像到Docker仓库:

client.images.push(repository="repository_name", tag="image_tag")

在这里,repository_name是你的Docker仓库的名称,image_tag是你想要提交的镜像的标签。

通过按照这些步骤,你可以使用Python Docker库来创建、编译和提交镜像。


python docker库实时获取容器运行状态

要实时获取Docker容器的运行状态,可以使用Python的docker库中的Container类的方法和属性来实现。以下是一个示例代码,演示如何实时获取容器的运行状态:

import docker
import time
client = docker.from_env()  # 获取指定容器实例
container = client.containers.get('container_id')   # 实时获取容器状态
while True:    
    container.reload()  # 重新加载容器信息    
    print(f"Container {container.name} is {container.status}") 
    time.sleep(5)  # 每隔5秒获取一次状态

在上面的示例中,首先创建了一个Docker客户端实例client,然后使用client.containers.get('container_id')方法获取指定ID的容器实例。然后使用while循环实时获取容器的状态,通过container.reload()方法重新加载容器信息,并打印容器的状态。在每次获取状态之后,使用time.sleep(5)让程序休眠5秒,以实现每隔5秒获取一次状态的效果。通过这种方式,可以实时监控Docker容器的运行状态,并根据需要进行相应的操作。


python docker库查看某个容器是否存在

你可以使用 Docker Python 客户端库来检查特定容器是否存在。以下是一个简单的示例代码,演示了如何使用 Docker Python 客户端库来检查特定容器是否存在:

import docker
​
client = docker.from_env()
​
# 定义要查找的容器名称
container_name = 'my-container'
​
# 通过容器名称查找容器
containers = client.containers.list(all=True, filters={'name': container_name})
​
# 检查是否存在指定名称的容器
if containers:
    print(f"容器 '{container_name}' 存在")
else:
    print(f"容器 '{container_name}' 不存在")

在上面的示例中,我们首先使用 client.containers.list() 方法来列出所有的容器,并通过设置 filters 参数来筛选出特定名称的容器。然后,我们检查筛选后的容器列表是否为空,从而确定特定容器是否存在。

请注意,上面的示例仅演示了如何使用 Docker Python 客户端库来检查特定容器是否存在,实际情况下可能需要根据具体的需求进行适当的调整。


container.exec_run()参数详解

container.exec_run() 方法是 Docker Python 客户端库中用于在容器内部执行命令的方法。该方法的参数如下:

  • cmd:要在容器内部执行的命令,可以是字符串或者列表。如果是字符串,则会被解析为 shell 命令执行;如果是列表,则会被直接执行。

  • stdout:是否将命令的标准输出重定向到主机的标准输出。默认为 False,表示不重定向。

  • stderr:是否将命令的标准错误输出重定向到主机的标准错误输出。默认为 False,表示不重定向。

  • stdin:是否将主机的标准输入重定向到命令的标准输入。默认为 False,表示不重定向。

  • tty:是否为命令分配一个伪终端。默认为 False

  • privileged:是否以特权模式运行容器。默认为 False

  • user:在容器内部执行命令的用户。默认为 root

  • environment:要设置的环境变量,可以是字典或者列表。如果是字典,则表示要设置的环境变量名和值;如果是列表,则表示要设置的环境变量字符串,比如 ['VAR1=value1', 'VAR2=value2']

  • workdir:命令执行的工作目录。默认为容器的根目录。

  • detach:是否将命令的执行分离到后台。默认为 False,表示不分离。

  • socket:是否返回一个 socket 对象,用于读取命令的输出。默认为 False

  • demux:是否将命令的标准输出和标准错误输出分离。默认为 False,表示不分离。

  • stream:是否将命令的输出流式传输。默认为 False

  • stdin_open:是否保持标准输入的打开状态。默认为 False

  • privileged:是否以特权模式运行容器。默认为 False

  • auto_remove:是否在容器退出时自动删除容器。默认为 False

  • name:容器的名称。

  • entrypoint:命令的入口点。可以是字符串或者列表。如果是字符串,则会被解析为 shell 命令执行;如果是列表,则会被直接执行。

  • network:容器所在的网络名称或者 ID。

  • pid_mode:容器的 PID 模式。可以是 host 或者 container:<name|id>。默认为 None

  • ipc_mode:容器的 IPC 模式。可以是 host 或者 container:<name|id>。默认为 None

  • uts_mode:容器的 UTS 模式。可以是 host 或者 container:<name|id>。默认为 None

  • cap_add:要添加的 Linux 容器功能。可以是字符串或者列表。

  • cap_drop:要删除的 Linux 容器功能。可以是字符串或者列表。

  • mounts:要挂载的卷。可以是列表。

  • labels:容器的标签。可以是字典。

  • stop_signal:停止容器时发送的信号。默认为 SIGTERM

  • stop_timeout:停止容器的超时时间。默认为 10 秒。

  • runtime:容器使用的运行时。默认为 None

  • stdin_once:是否只允许标准输入被使用一次。默认为 False

  • extra_hosts:要添加到容器的 /etc/hosts 文件的主机名和 IP 地址。可以是字典。

  • auto_remove:是否在容器退出时自动删除容器。默认为 False

需要注意的是,不同版本的 Docker Python 客户端库可能支持的参数略有不同。如果使用的是旧版本的客户端库,可能会缺少某些参数。因此,在使用 container.exec_run() 方法时,需要根据具体的客户端库版本和需求选择适当的参数。


docker库client.images.build()参数详解

在Docker库中,client.images.build() 方法用于构建 Docker 镜像。该方法接受多个参数,下面是这些参数的详细解释:

  1. path (str): Dockerfile 的路径。这是必需的参数,指定了 Dockerfile 的位置。

  2. tag (str): 镜像的标签。这是必需的参数,用于给镜像打上标签。

  3. quiet (bool): 如果设置为 True,则不会输出构建过程的详细信息。默认为 False。

  4. fileobj (file-like object): Dockerfile 的内容。如果你不想使用 path 参数指定 Dockerfile 的路径,你可以传入 Dockerfile 的内容。

  5. custom_context (bool): 如果设置为 True,则表示使用自定义的构建上下文。默认为 False。

  6. encoding (str): Dockerfile 文件的编码方式。默认为 UTF-8。

  7. buildargs (dict): 用于传递构建参数给 Dockerfile。这是一个字典类型的参数,其中键值对表示构建参数的名称和值。

  8. container_limits (dict): 用于设置容器的资源限制,比如内存限制、CPU限制等。

  9. network_mode (str): 用于指定构建时使用的网络模式。

  10. shmsize (int): 用于设置共享内存大小。

  11. labels (dict): 用于设置镜像的标签。

  12. cache_from (list): 用于指定构建时使用的缓存镜像列表。

  13. target (str): 用于指定构建时的目标阶段,仅在多阶段构建时有效。

这些参数可以帮助你在使用 Docker 库时更灵活地进行镜像构建,并根据需要进行定制化配置。


client.images.build返回内容详解

client.images.build() 方法返回一个生成器对象和一个构建日志的字典。让我们来详细解释一下这两个返回值:1. 生成器对象:这个生成器对象用于迭代构建过程中的输出信息。你可以使用 for 循环来逐行获取构建日志,例如:

image, build_logs = client.images.build(path="/path_to_project", tag="your_image_tag")
for line in build_logs:
    print(line)     

这样就可以逐行打印构建过程中的输出信息。2. 构建日志字典:这个字典包含了构建过程中的详细信息,包括构建的步骤、输出内容等。通常包括以下字段:

  • stream: 构建过程中的输出信息

  • status: 构建过程中的状态信息

  • errorDetail: 如果有错误发生,包含错误的详细信息通过这些返回内容,你可以获取构建过程中的详细信息,并根据需要进行处理和展示。

python-docker库自动化部署

# coding=utf-8

import traceback

import docker
from loguru import logger


class DockerAutomation:

    def __init__(self, docker_name_or_id):
        self.client = docker.from_env()  # 创建了一个docker客户端对象
        self.docker_name = docker_name_or_id  # docker名称或ID
        self.repository =   # 镜像名称
        self.tag =   # 镜像标签
        self.command = "/bin/bash"  # 创建镜像时需要执行的命令
        # 创建镜像时需要执行的命令
        # self.command = 
        self.localhost_dir =   # 本地数据卷路径
        self.container_dir =   # 挂载到容器的数据卷路径
        self.git_path =   # git仓库链接
        self.git_clone_path = 
        self.container = None  # 容器对象

    def create_run_container(self):
        """
        创建并且启动容器
        :return:
        """
        try:
            self.container = self.client.containers.run(image=f"{self.repository}:{self.tag}",
                                                        command=self.command,
                                                        volumes=[f"{self.localhost_dir}:{self.container_dir}"],
                                                        name=self.docker_name,
                                                        detach=True,
                                                        stdin_open=True,
                                                        )
            if self.get_status() == "running":
                logger.info(f"创建启动容器{self.docker_name}成功")
              

        except Exception as e:
            self.client.close()
            logger.error(f"创建启动容器{self.docker_name}失败" + traceback.format_exc())

    # def build_mirror(self):
    #     """
    #     创建提交镜像,还未测试过,请勿轻易使用
    #     :return:
    #     """
    #     # 拉取代码到本地
    #     git_clone_command = f"git clone {self.git_path} {self.git_clone_path}"
    #     subprocess.run(git_clone_command, shell=True)
    #     # 构建镜像
    #     self.client.images.build(path=f"Dockerfile", tag=self.tag, quiet=True)
    #     # 提交镜像
    #     self.client.images.push(repository=self.repository, tag=self.tag)

    def run_program(self, path, filename):
        """
        在容器中运行某个代码
        :path: 代码文件所在路径
        :filename: 文件名, 不用文件后缀
        :return:
        """
        try:
            if not self.container:
                self.container = self.client.containers.get(self.docker_name)
            # 在容器中执行命令,比如拉取代码
            # self.container.exec_run(f'git clone {self.git_path}')

            # 运行python代码
            command = f"/bin/bash -c 'cd {path} && PYTHONPATH=. python3 {filename}.py'"
            self.container.exec_run(cmd=command, stdout=False, stderr=False)
        except Exception as e:
            self.client.close()
            logger.error("拉运行python文件失败" + traceback.format_exc())

    def run_command(self, command):
        """
        用于在容器中执行脚本
        :param command:
        :return:
        """
        try:
            if not self.container:
                self.container = self.client.containers.get(self.docker_name)
            self.container.exec_run(cmd=command, stdout=False, stderr=False)
        except Exception as e:
            self.client.close()
            logger.error("执行该命令失败" + traceback.format_exc())

    def close_docker(self):
        """
        关闭容器
        :return:
        """
        try:
            if not self.container:
                self.container = self.client.containers.get(self.docker_name)
            self.container.stop()  # 停止容器 ==> docker stop id
            if self.get_status() == "exited":
                logger.info(f"关闭容器{self.docker_name}成功")
            else:
                logger.error(f"关闭容器{self.docker_name}失败")
        except Exception as e:
            self.client.close()
            logger.error(f"关闭容器{self.docker_name}失败: " + traceback.format_exc())

    def close_remove_docker(self):
        """
        关闭并且删除容器
        :return:
        """
        try:
            if not self.container:
                self.container = self.client.containers.get(self.docker_name)
            self.container.stop()  # 停止容器 ==> docker stop id
            self.container.remove()  # 删除容器 ==> docker rm id
            if not self.existed():
                logger.info(f"关闭并且删除容器{self.docker_name}成功")
            else:
                logger.error(f"关闭并且删除容器{self.docker_name}失败")
        except Exception as e:
            logger.error(f"关闭并且删除容器{self.docker_name}失败: " + traceback.format_exc())
            self.client.close()

    def start_docker(self):
        """
        开启容器
        :return:
        """
        try:
            if not self.container:
                self.container = self.client.containers.get(self.docker_name)
            self.container.start()
            if self.get_status() == "running":
                logger.info(f"开启容器{self.docker_name}成功")
            else:
                logger.error(f"开启容器{self.docker_name}失败")
        except:
            self.client.close()
            logger.error(f"开启容器{self.docker_name}失败")

    def get_status(self):
        """
        获取容器状态
        :return:
        """
        try:
            status = None
            if self.existed():
                if not self.container:
                    self.container = self.client.containers.get(self.docker_name)
                self.container.reload()  # 刷新容器状态
                status = self.container.status
            return status
        except Exception as e:
            self.client.close()
            logger.error(f"获取容器{self.docker_name}状态失败: " + traceback.format_exc())

    def existed(self):
        """
        判断容器是否已存在
        :return: 存在则返回其ID,不存在返回False
        """
        exist = self.client.containers.list(all=True, filters={"name": self.docker_name})
        if exist:
            return exist
        else:
            return False


if __name__ == '__main__':
    operate = DockerAutomation("test")
    operate.create_run_container()
    # operate.start_docker()
    operate.close_remove_docker()

    # operate.run_command("/bin/bash -c 'ls")
    # operate.command("nohup python3 /home/tujia/skynet/te.py &")
    print(DockerAutomation("test").get_status())

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值