Python的docker-py模块
Posted 礁之
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python的docker-py模块相关的知识,希望对你有一定的参考价值。
文章目录
一、docker的配置
[root@centos-1 ~]# vim /etc/systemd/system/docker.service #修改docker的系统启动文件
——————————————————————————
在'12'行添加'-H tcp://0.0.0.0:2375',表示启动时占用端口,从而能够远程连接
添加'-H unix'这段表示允许本地,不加重启后会使用docker命令会报错
还有一个是tls可以使用ssl证书进行连接,但是需要指定证书位置
——————————————————————————
1 [Unit]
2 Description=Docker Application Container Engine
3 Documentation=https://docs.docker.com
4 After=network-online.target firewalld.service
5 Wants=network-online.target
6
7 [Service]
8 Type=notify
9 # the default is not to use systemd for cgroups because the delegate issues still
10 # exists and systemd currently does not support the cgroup feature set required
11 # for containers run by docker
12 ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
13 ExecReload=/bin/kill -s HUP $MAINPID
14 # Having non-zero Limit*s causes performance problems due to accounting overhead
15 # in the kernel. We recommend using cgroups to do container-local accounting.
16 LimitNOFILE=infinity
17 LimitNPROC=infinity
18 LimitCORE=infinity
19 # Uncomment TasksMax if your systemd version supports it.
20 # Only systemd 226 and above support this version.
21 #TasksMax=infinity
22 TimeoutStartSec=0
23 # set delegate yes so that systemd does not reset the cgroups of docker containers
24 Delegate=yes
25 # kill only the docker process, not all processes in the cgroup
26 KillMode=process
27 # restart the docker process if it exits prematurely
28 Restart=on-failure
29 StartLimitBurst=3
30 StartLimitInterval=60s
31
32 [Install]
33 WantedBy=multi-user.target
#保存退出
[root@centos-1 ~]# systemctl daemon-reload
[root@centos-1 ~]# systemctl restart docker
[root@centos-1 ~]# netstat -ntpl | grep 2375
tcp6 0 0 :::2375 :::* LISTEN 1313/dockerd
###注意:
(1)如果开启防火墙则需要配置允许端口通过
(2)阿里云的ECS上部署的Docker,还需在安全组规则添加入方向、tcp、2375端口的开通
二、Python的docker模块
- 官网地址:Docker SDK 官网
- docker-py 是一个第三方库,所以在使用之前需要自行安装。推荐使用 PIP 进行安装,命令如下:
- 先下载docker-py
pip install docker-py
- 安装好之后,进入交互模式查看版本
PS D:\\工作\\work> python
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import docker
>>> docker.version_info
(1, 10, 6)
>>> docker.version
'1.10.6'
- 由于主要操作时针对docker服务器的,所以编写的代码基本上都算是客户端,在docker-py中最重要的操作基本上都在
docker.client
模块中,此模块提供了对docker引擎的相关操作
(1)建立连接
-
docker服务器对外提供的时web接口,即
接收http消息并且返回http响应
,但这里并不直接向docker服务发送http消息,而是使用客户端的高层接口函数来解决这个问题 -
使用接口函数相会更加直观、方便,并且和docker命令行客户端的用法类似
-
在对docker服务器进行操作之前,需要先建立连接,可以使用
docker.from.env()
接口函数来建立连接,大多数情况下不需要传入参数就可以正常建立连接,例如:client = docker.from_env()
-
还有一种连接的方式是构造一个client对象,该对象的初始化函数可以接收下面的参数:
client = docker.Client(base_url='tcp://10.10.30.69:2375',version='1.21',timeout=5) #远程连接
base_url:
连接哪个 Docker 服务器,默认值是本机的 Docker 服务器。version:
使用的协议版本。timeout:
连接超时时间,单位为秒。如果在指定的时间内没有连接成功,则表示连接失败,返回值是 None。tls:
是否使用 TLS 作为传输层,默认值是 False,如果要使用的话,还需要指定ssl文件。
-
下面来看一个python如何与docker建立连接:
#在centos环境下 [root@centos-1 ~]# python3 -m venv tutorial-env #创建虚拟环境目录 [root@centos-1 ~]# source tutorial-env/bin/activate #进入虚拟环境 (tutorial-env) [root@centos-1 ~]# pip install docker-py #下载docker,前面出现tutorial-env,表示进入虚拟环境 (tutorial-env) [root@centos-1 ~]# python3 Python 3.9.9 (main, May 13 2022, 15:23:56) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import docker >>> docker.version '1.10.6' >>> client = docker.Client() >>> if client is None: ... print('connection error') ... else: ... print('connection ok') ... connection ok #连接成功 >>> client.base_url 'http+docker://localunixsocket' >>> client.timeout 60 >>> ver_info = client.version() >>> ver_info 'Platform': 'Name': '', 'Components': ['Name': 'Engine', 'Version': '18.06.1-ce', 'Details': 'ApiVersion': '1.38', 'Arch': 'amd64', 'BuildTime': '2018-08-21T17:28:38.000000000+00:00', 'Experimental': 'false', 'GitCommit': 'e68fc7a', 'GoVersion': 'go1.10.3', 'KernelVersion': '3.10.0-693.el7.x86_64', 'MinAPIVersion': '1.12', 'Os': 'linux'], 'Version': '18.06.1-ce', 'ApiVersion': '1.38', 'MinAPIVersion': '1.12', 'GitCommit': 'e68fc7a', 'GoVersion': 'go1.10.3', 'Os': 'linux', 'Arch': 'amd64', 'KernelVersion': '3.10.0-693.el7.x86_64', 'BuildTime': '2018-08-21T17:28:38.000000000+00:00' >>> ver_info['Version'] '18.06.1-ce' >>> ver_info['ApiVersion'] '1.38' >>> ver_info['KernelVersion'] '3.10.0-693.el7.x86_64' >>> ver_info['BuildTime'] '2018-08-21T17:28:38.000000000+00:00'
(2)对docker镜像的操作
-
docker的镜像就是软件的安装包,对其操作主要有
下载
、删除
、推送
等,对于到docker命令就是pull
、push
和rmi
-
如果想要下载某个镜像,默认的命令是
docker pull imagename
,例如:docker pull alpine:3.9
-
使用python实现的话,可以这样写:
import docker client = docker.from_env() imgs1 = client.images() # 列出所有本地的镜像 client.pull("nginx") # 下载所有的alpine镜像,不要执行这个,这个会全部下载 imgs2 = client.images() # 再次查看所有的本地镜像 for img in imgs2: if img not in imgs1: print(img)
-
上面的代码会把alpine相关镜像全部下载,最好不要执行,我们可以加标签来指定下载的镜像:
import docker client = docker.from_env() imgs1 = client.images() # 列出所有本地的镜像 client.pull("nginx:1.20") # 下载所有的alpine镜像,不要执行这个,这个会全部下载 imgs2 = client.images() # 再次查看所有的本地镜像 for img in imgs2: if img not in imgs1: print(img)
-
还可以看到下载的过程
import docker client = docker.from_env() out_stream = client.pull("nginx:1.20", stream=True) for line in out_stream: print(line) #输出信息: b'"status":"Downloading","progressDetail":"current":24861068,"total":25334886,"progress":"[=================================================\\\\u003e ] 24.86MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Downloading","progressDetail":"current":25123212,"total":25334886,"progress":"[=================================================\\\\u003e ] 25.12MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Verifying Checksum","progressDetail":,"id":"43bc2143131d"\\r\\n' b'"status":"Download complete","progressDetail":,"id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":262144,"total":25334886,"progress":"[\\\\u003e ] 262.1kB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":2097152,"total":25334886,"progress":"[====\\\\u003e ] 2.097MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":3670016,"total":25334886,"progress":"[=======\\\\u003e ] 3.67MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":5505024,"total":25334886,"progress":"[==========\\\\u003e ] 5.505MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":7864320,"total":25334886,"progress":"[===============\\\\u003e ] 7.864MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":10223616,"total":25334886,"progress":"[====================\\\\u003e ] 10.22MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":13369344,"total":25334886,"progress":"[==========================\\\\u003e ] 13.37MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":15728640,"total":25334886,"progress":"[===============================\\\\u003e ] 15.73MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":18087936,"total":25334886,"progress":"[===================================\\\\u003e ] 18.09MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":20447232,"total":25334886,"progress":"[========================================\\\\u003e ] 20.45MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":22806528,"total":25334886,"progress":"[=============================================\\\\u003e ] 22.81MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":24379392,"total":25334886,"progress":"[================================================\\\\u003e ] 24.38MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":25334886,"total":25334886,"progress":"[==================================================\\\\u003e] 25.33MB/25.33MB","id":"43bc2143131d"\\r\\n' b'"status":"Pull complete","progressDetail":,"id":"43bc2143131d"\\r\\n' b'"status":"Extracting","progressDetail":"current":601,"total":601,"progress":"[==================================================\\\\u003e] 601B/601B","id":"45e2f4bfb543"\\r\\n' b'"status":"Extracting","progressDetail":"current":601,"total":601,"progress":"[==================================================\\\\u003e] 601B/601B","id":"45e2f4bfb543"\\r\\n' b'"status":"Pull complete","progressDetail":,"id":"45e2f4bfb543"\\r\\n' b'"status":"Extracting","progressDetail":"current":894,"total":894,"progress":"[==================================================\\\\u003e] 894B/894B","id":"18bc137763b4"\\r\\n' b'"status":"Extracting","progressDetail":"current":894,"total":894,"progress":"[==================================================\\\\u003e] 894B/894B","id":"18bc137763b4"\\r\\n' b'"status":"Pull complete","progressDetail":,"id":"18bc137763b4"\\r\\n' b'"status":"Extracting","progressDetail":"current":664,"total":664,"progress":"[==================================================\\\\u003e] 664B/664B","id":"504f3151a203"\\r\\n' b'"status":"Extracting","progressDetail":"current":664,"total":664,"progress":"[==================================================\\\\u003e] 664B/664B","id":"504f3151a203"\\r\\n' b'"status":"Pull complete","progressDetail":,"id":"504f3151a203"\\r\\n' b'"status":"Extracting","progressDetail":"current":1393,"total":1393,"progress":"[==================================================\\\\u003e] 1.393kB/1.393kB","id":"520efdb29b04"\\r\\n' b'"status":"Extracting","progressDetail":"current":1393,"total":1393,"progress":"[==================================================\\\\u003e] 1.393kB/1.393kB","id":"520efdb29b04"\\r\\n' b'"status":"Pull complete","progressDetail":,"id":"520efdb29b04"\\r\\n' b'"status":"Digest: sha256:ec8e997ca71be5046070b2db6043fb7100e1681b91bb2fcb49d551b7fc9b2ba4"\\r\\n' b'"status":"Status: Downloaded newer image for nginx:1.20"\\r\\n'
-
上面说了查看镜像和下载镜像,现在来看删除镜像:
import docker # 这个必须有,引入Docker包 client = docker.from_env() # 和Docker服务器建立连接 imgs = client.images() # 得到Docker镜像列表 for img in imgs: # 遍历所有的镜像 # 一个镜像可能有几个tag,只要有一个符合要求即可 for tag in img['RepoTags']: if tag == "nginx:1.20": # tag是我们要找的 client.remove_image(img['Id']) # 删除挑选出来的镜像 #执行脚本,之后可以使用docker images进行查看
-
有时,可能镜像已经创建容器,并且在运行中,那么上面的代码就会报错,可以使用强制删除的方式:
import docker # 必须要引入的Docker包 client = docker.from_env() # 和Docker服务器建立连接 imgs = client.images() # 得到所有的本地镜像 for img in imgs: for tag in img['RepoTags']: if tag == "nginx:1.20": # 有我们要找的标签 client.remove_image(img['Id'], force=True) # 添加force=True进行强制删除
-
如果想要删除全部镜像:
import docker client = docker.from_env() # 和Docker服务器建立连接 imgs = client.images() # 得到所有的本地镜像 for img in imgs: # 依次遍历镜像文件 client.remove_image(img['Id']) # 直接删除镜像文件,不在向上面那样做if判断
-
还可以进行推送镜像,例如:
import docker client = docker.from_env() # 指定用户名、密码和服务器 login_ret = client.login(username="docker", # 用户名 password="123.com", # 密码 registry="repo.docker.com") # 服务器信息 print("login_ret:", login_ret) # 将指定的镜像推送到服务器上 push_rsp = client.push("test:test", stream=False) print("push_rsp:", push_rsp)
(3)使用Dockerfile文件创建镜像
-
如果想要使用Dockerfile创建镜像,可以这样使用:
——vim Dockerfile FROM nginx:v1.0 CMD ["/bin/sh"] #保存退出 ——vim test.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- import docker client = docker.from_env() # 注意,一定要以二进制方式打开 fd = open("./Dockerfile", "rb") result = client.build(fileobj=fd, rm=True, tag='pydocker/demo') fd.close() for line in result: print(line) #保存退出 ——python3 test.py #输出结果: b'"stream":"Step 1/2 : FROM nginx:v1.0"\\r\\n' b'"stream":"\\\\n"\\r\\n' b'"stream":" ---\\\\u003e 5dd2557ae711\\\\n"\\r\\n' b'"stream":"Step 2/2 : CMD [\\\\"/bin/sh\\\\"]"\\r\\n' b'"stream":"\\\\n"\\r\\n' b'"stream":" ---\\\\u003e Running in 6daaf3f6dd12\\\\n"\\r\\n' b'"stream":"Removing intermediate container 6daaf3f6dd12\\\\n"\\r\\n' b'"stream":" ---\\\\u003e af2b53a2923a\\\\n"\\r\\n' b'"stream":"Successfully built af2b53a2923a\\\\n"\\r\\n' b'"stream":"Successfully tagged pydocker/demo:latest\\\\n"\\r\\n' ——docker images #查看镜像是否创建成功
(4)对容器的操作
-
看了关于镜像的相关操作后,现在来看创建容器的相关操作:
#查看所有容器 import docker client = docker.from_env() container_list = client.containers() # 得到所有的容器 for container_inst in container_list: print(container_inst['Id'Python的docker-py模块
使用Docker Python SDK登录注册表(docker-py)