docker-py(Docker SDK for Python)使用指南
本篇博客围绕官方提供的`python`版的`docker EngineAPI(Docker SDK for Python)`,结合具体示例,详细介绍如何使用`python`来自动化操作`docker`。
前言
本篇博客围绕官方提供的python
版的docker Engine API(Docker SDK for Python)
,结合具体示例,详细介绍如何使用python
来自动化操作docker
。
建议本篇文章同《Docker常用指令汇总》一起食用效果更佳!!!
1. docker客户端
要与Docker
服务器进行通信,首先需要实例化一个客户端,要做到这一点,最简单的方法是调用 from_env()
函数 ,当然,如果使用ssh
来操作远程的docker
,也可以通过实例化 DockerClient
类。
常规client
实例化:
# pip install docker
import docker
client = docker.from_env()
使用ssh
远程操作docker
,初始化client
可以这样做:
client = docker.Dockerclient("ssh://username@yourip", use_ssh_client=True)
# 执行之后会让用户输入密码
# base_url(str) -- 指向Docker服务器的URL。例如, unix:///var/run/docker.sock 或 tcp://127.0.0.1:1234
# version(str) -- 要使用的API的版本。设为 auto 自动检测服务器的版本。默认: 1.35
# timeout(int) -- API调用的默认超时时间,单位为秒
# tls(bool or TLSConfig) -- 启用TLS。经过 True 使用默认选项启用它,或将 TLSConfig 对象以使用自定义配置
# user_agent(str) -- 为对服务器的请求设置自定义用户代理
# credstore_env(dict) -- 调用凭据存储进程时覆盖环境变量
# use_ssh_client (bool) -- 如果设置为 True ,通过向ssh客户端发出命令来建立ssh连接。确保在主机上安装并配置了ssh客户端
# max_pool_size (int) -- 要保存在池中的最大连接数
得到的client
是一个DockerClient
对象,常用的属性及方法有:
属性 | 功能 | 备注 |
---|---|---|
containers | 用于管理服务器上的容器 | 无 |
images | 用于管理服务器上的镜像 | 无 |
close() | 关闭当前连接 | 无 |
events() | 从服务器获取实时事件 | docker events |
info() | 显示系统范围的信息 | docker info |
login() | 使用注册表进行身份验证 | docker login |
version() | 从服务器返回版本信息 | docker version |
2. docker镜像
client.images
是一个ImageCollection
对象,用来管理服务器上的镜像,其主要有以下方法:
属性 | 功能 | 备注 |
---|---|---|
list(**kwargs) | 列出服务器上的图像 | docker images |
get(name) | 根据镜像名字来获取镜像 | 无 |
load(data) | 加载镜像 | docker load 需要注意的是,data 参数为镜像的二进制数据,而非路径 |
prune(filters=None) | 删除未使用的图像 | 无 |
pull(repository, tag=None, all_tags=False, **kwargs) | 拉取给定名称的镜像并将其返回 | docker pull |
push(repository, tag=None, **kwargs) | 将镜像推送到注册表 | docker push |
remove(*args, **kwargs) | 删除镜像 | docker rmi |
search(*args, **kwargs) | 在Docker Hub 上搜索镜像 | docker search |
client.list()
client.images.get('myubuntu:python')
# 加载镜像
with open(image_path, 'rb') as f:
img = client.images.load(f)
img_obj = img[0]
print('Image Info: ', img_obj.short_id, img_obj.tags)
# 拉取最新的ubuntu镜像
image = client.images.pull('ubuntu')
# 如果 tag 是 None 或为空,则设置为 latest
# 如果 all_tags 已设置,则 tag 参数被忽略,并且将拉取所有镜像标签
Image
对象是服务器上的映像,其主要有以下方法:
属性 | 功能 | 备注 |
---|---|---|
attrs | 服务器中此对象的原始表示形式 | 无 |
id | 镜像的ID | 无 |
labels | 作为字典的镜像的标签 | 无 |
short_id | 截断为12个字符的图像的ID,加上 sha256: 前缀 | 无 |
tags | 镜像的标签 | 无 |
history() | 显示图像的历史记录 | 无 |
reload() | 再次从服务器加载此对象并更新 attrs 使用新的数据 | 无 |
save(chunk_size=2097152, named=False) | 保存镜像 | docker save |
tag(repository, tag=None, **kwargs) | 将此镜像的标签添加到存储库中 | docker tag |
img = client.images.get('myubuntu:python')
print(img.attrs)
print(img.id)
print(img.labels)
print(img.short_id)
print(img.tags)
3. docker容器
client.containers
是一个ContainerCollection
对象,在服务器上运行和管理容器,其主要有以下方法:
属性 | 功能 | 备注 |
---|---|---|
run(image, command=None, **kwargs) | 运行一个容器,默认情况下,它将等待容器完成并返回其日志 | docker run ,如果 detach 参数是 True ,它将启动容器并立即返回一个 Container 对象,类似于 docker run -d |
create(image, command=None, **kwargs) | 在不启动的情况下创建容器 | docker create |
get(id_or_name) | 按名称或ID获取容器 | docker create |
list(**kwargs) | 列出容器 | docker ps |
prune(filters=None) | 删除停止的容器 | 无 |
下面将详细介绍一下run()
函数,主要有以下参数:
image(str)
---- 要运行的映像command(str or list)
---- 要在容器中运行的命令auto_remove(bool)
---- 当容器的进程退出时,在守护程序端启用容器的自动删除cap_add(list of str)
---- 添加内核功能,例如,["SYS_ADMIN", "MKNOD"]
cap_drop(list of str)
---- 放弃内核功能cpu_count(int)
---- 可用CPU
数(仅限windows
)cpu_percent(int)
---- 可用CPU
的可用百分比(仅限windows
)cpu_period(int)
---- 以微秒为单位的CPU
周期长度cpu_shares(int)
----CPU
占有率(相对权重)cpuset_cpus(str)
---- 允许执行的CPUs
(0-3, 0, 1)
detach(bool)
---- 在后台运行容器并返回一个Container
对象devices(list)
---- 将主机设备作为以下形式的字符串列表公开给容器:<path_on_host>:<path_in_container>:<cgroup_permissions>
device_requests(list)
---- 将主机资源(如GPU
)公开给容器,作为docker.types.DeviceRequest
实例dns(list)
---- 设置自定义的DNS
服务器dns_opt(list)
---- 要添加到容器的resolv.conf
文件dns_search(list)
---- 域名系统搜索域domainname(str or list)
---- 设置自定义DNS
搜索域entrypoint(str or list)
---- 容器的入口点environment(dict or list)
---- 要在容器内设置的环境变量,格式为字典或字符串列表["PYTHONPATH=xxx"]
extra_hosts(dict)
---- 要在容器内解析的其他主机名,作为主机名到IP
地址的映射group_add(list)
---- 容器进程将以其身份运行的其他组名或ID
的列表healthcheck(dict)
---- 指定要执行的测试以检查容器是否正常hostname(str)
---- 容器的可选主机名isolation(str)
---- 使用隔离技术,默认为None
kernel_memory(int or str)
---- 内核内存限制labels(dict or list)
---- 以字典或者列表(空值)的形式,例如{"label1": "value1", "label2": "value2"}
或["label1", "label2"]
links(dict)
---- 链接的映射使用{'container': 'alias'}
格式化,别名是可选的log_config(LogConfig)
---- 日志记录配置mac_address(str)
---- 要分配给容器的MAC
地mem_limit(int or str)
---- 内存限制name(str)
---- 给容器起的名称network(str)
---- 此容器在创建时将连接到的网络的名称network_disabled(bool)
---- 禁用网络network_mode(str)
---- 以下其中一项: 桥接模式bridge
、主机模式host
、none
、container:<name|id>
ports(dict)
---- 要绑定到容器内部的端口,字典形式:{'2222/tcp': 3333}
会将容器内的端口2222
暴露为主机上的端口3333
privileged(bool)
---- 将扩展权限授予此容器read_only(bool)
---- 将容器的根文件系统挂载为只读remove(bool)
---- 当容器运行完毕后,将其移除。默认为False
restart_policy(dict)
---- 容器退出时重新启动,配置为带有关键字的词典:Name
取值只能是on-failure
或always
,MaximumRetryCount
为失败时重新启动容器的次数。例如:{"Name": "on-failure", "MaximumRetryCount": 5}
shm_size(str or int)
----/dev/shm
的大小,比如1G
stdin_open(bool)
---- 保持STDIN
打开,即使没有连接stdout(bool)
---- 当detach=False
时日志从STDOUT
返回 ,默认为True
stderr(bool)
---- 当detach=False
时日志从STDERR
返回 ,默认为False
stream(bool)
---- 如果设置为True
,且detach
为False
,则返回日志生成器而不是字符串,如果detach
为True
将忽略。默认为False
sysctls(dict)
---- 要在容器中设置的内核参数tmpfs(dict)
---- 要挂载的临时文件系统,作为将容器内的路径映射到该路径的选项的字典。例如:{'/mnt/vol2': '', '/mnt/vol1': 'size=3G,uid=1000'}
tty(bool)
---- 分配一个伪TTY
user(str or int)
---- 在容器内运行命令的用户名或UID
version(str)
---- 要使用的API
的版本。设为auto
自动检测服务器的版本。默认为1.35
volume_driver(str)
---- 卷驱动程序/插件的名称volumes(dict or list)
---- 用于配置装载在容器内的卷的字典。键是主机路径或卷名,值是包含键的字典,比如:{'/home/user1/': {'bind': '/mnt/vol2', 'mode': 'rw'},'/var/www': {'bind': '/mnt/vol1', 'mode': 'ro'}}
,其中bind
表示在容器内挂载卷的路径,mode
要么为rw
以读/写方式装载卷,或ro
以只读方式装载它。也可以是列表形式直接映射:['/home/user1/:/mnt/vol2','/var/www:/mnt/vol1']
working_dir(str)
---- 容器的工作目录的路径
上述的参数并没有完全列举完,只对可能用到的进行了介绍,下面看下具体如何使用:
container = client.containers.run(image='ubuntu:latest',
command='/bin/bash',
user='root',
name='docker_test',
volumes=['/home/liyanpeng/docker-test:/home/liyanpeng/docker-test'],
working_dir='/home/liyanpeng',
tty=True,
detach=True,
stdin_open=True,
environment=['PYTHONPATH=xxxxx:$PYTHONPATH'])
# 如果detach=True,那么在容器内的输出信息需要通过container.logs()来查看
# 如果detach=False,可以直接print(container)来查看信息
Container
对象是容器对象的本地表示形式,其主要有以下方法:
属性 | 功能 | 备注 |
---|---|---|
attrs | 容器的属性信息 | 无 |
id | 容器的id | 无 |
image | 容器的容器的图像 | 无 |
labels | 作为词典的容器的标签 | 无 |
name | 容器的名称 | 无 |
short_id | 对象的ID ,截断为12个字符 | 无 |
status | 容器的状态,例如running 或 exited | 无 |
attach(**kwargs) | 附在这个容器上 | 无 |
commit(repository=None, tag=None, **kwargs) | 将容器提交到映像 | docker commit |
diff() | 检查容器的文件系统上的更改 | 无 |
exec_run(cmd) | 在该容器内运行命令 | docker exec |
export(chunk_size=2097152) | 将容器的文件系统的内容导出为TAR 压缩包 | 无 |
logs(**kwargs) | logs(**kwargs) | docker logs |
remove(**kwargs) | 移除这个容器 | docker rm |
rename(name) | 重命名此容器 | docker rename |
restart(**kwargs) | 重新启动此容器 | docker restart |
start(**kwargs) | 启动这个容器 | docker start |
stats(**kwargs) | 此容器的流统计信 | docker stats |
stop(**kwargs) | 停止容器 | docker stop |
top(**kwargs) | 显示容器正在运行的进程 | 无 |
update(**kwargs) | 更新容器的资源配置 | 无 |
wait(**kwargs) | 等容器停止,然后返回其退出代码 | docker wait |
4. 使用示例
# -*- coding:utf-8 -*-
# Author: liyanpeng
# Email: youran.xia@foxmail.com
# Datetime: 2023/2/3 17:16
# Filename: python_docker·py
import docker
from packaging.version import Version
class PythonDocker(object):
image_file = '/home/liyanpeng/ubuntu-20.04.tar.gz'
repository = 'ubuntu'
tag = 'latest'
localhost_dir = '/home/liyanpeng/docker-test'
container_dir = '/home/liyanpeng/docker-test'
container = None
container_name = 'python_docker'
client = docker.from_env()
# client = docker.Dockerclient("ssh://username@yourip", use_ssh_client=True)
@classmethod
def load_image(cls):
with open(cls.image_file, 'rb') as f:
img = cls.client.images.load(f)
img_obj = img[0]
print('Image Info: ', img_obj.short_id, img_obj.tags)
@classmethod
def check_version(cls):
docker_version = cls.client.version()['Components'][0]['Version']
assert Version(docker_version) >= Version('19.03'), 'Docker version requires: docker >= 19.03.'
@classmethod
def run_container(cls):
try:
cls.container = cls.client.containers.run('{}:{}'.format(cls.repository, cls.tag),
command='/bin/bash',
user='root',
name=cls.container_name,
volumes=['{}:{}'.format(cls.localhost_dir, cls.container_dir)],
working_dir='/home',
tty=True,
detach=True,
stdin_open=True,
environment=['PYTHONPATH=xxxxx:$PYTHONPATH'])
except Exception as err:
cls.container = cls.client.containers.get(cls.container_name)
@classmethod
def run_docker(cls):
result = cls.container.exec_run('python3 x.py') # 在容器内执行代码
print(result.exit_code, result.output.decode('utf-8'))
@classmethod
def close_docker(cls):
cls.container.stop() # 停止容器 ==> docker stop id
cls.container.remove() # 删除容器 ==> docker rm id
cls.client.close() # 关闭连接
结束语
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)