Docker SDK for Python:编程控制 Docker 容器与镜像

好的,各位观众老爷们,欢迎来到“用Python调戏Docker”讲座现场!今天咱们就来聊聊如何用Python这把瑞士军刀,优雅地操纵Docker容器和镜像。

一、Docker SDK:连接Python与Docker的桥梁

首先,我们要介绍今天的男主角——Docker SDK for Python。这玩意儿就像是Python和Docker之间的翻译官,它把Docker的API翻译成Python能听懂的语言,让咱们可以用Python代码来创建、启动、停止、删除容器,以及管理镜像等等。

简单来说,有了它,你就可以把Docker当成一个Python对象来玩弄于股掌之间,而不再需要敲一堆晦涩难懂的命令行了。

二、安装Docker SDK:磨刀不误砍柴工

在开始表演之前,咱们先得把工具准备好。打开你的终端,输入以下命令:

pip install docker

这个命令会从PyPI(Python Package Index)下载并安装docker这个库。如果你的网络环境不太好,可以考虑使用国内的镜像源,比如:

pip install docker -i https://pypi.tuna.tsinghua.edu.cn/simple

安装完毕后,就可以在Python代码中导入docker模块了。

三、连接Docker守护进程:建立通信

要控制Docker,咱们首先得和Docker守护进程建立连接。就像打电话一样,你得先拨号才能听到对方的声音。

import docker

# 连接本地Docker守护进程
client = docker.from_env()

# 如果Docker守护进程不在本地,可以使用URL连接
# client = docker.DockerClient(base_url='tcp://192.168.1.100:2375')

print(client.version())  # 打印Docker版本信息,测试连接是否成功

这段代码首先导入了docker模块,然后使用docker.from_env()函数来连接本地的Docker守护进程。如果你的Docker守护进程不在本地,而是运行在远程服务器上,可以使用docker.DockerClient()函数,并传入Docker守护进程的URL。

最后,我们打印了Docker的版本信息,如果能正常显示版本号,就说明连接成功了。

四、镜像操作:拉取、搜索、构建

镜像就像是容器的模板,咱们得先有镜像才能创建容器。

1. 拉取镜像:从Docker Hub下载

# 拉取一个名为"nginx"的镜像
try:
    image = client.images.pull('nginx')
    print(f"成功拉取镜像:{image.tags}")
except docker.errors.APIError as e:
    print(f"拉取镜像失败:{e}")

这段代码使用client.images.pull()函数来拉取一个名为"nginx"的镜像。如果镜像拉取成功,会打印镜像的标签;如果拉取失败,会打印错误信息。

2. 搜索镜像:寻找目标

# 搜索包含关键词"ubuntu"的镜像
results = client.images.search('ubuntu')
for result in results:
    print(f"镜像名称:{result['name']}, 描述:{result['description']}")

这段代码使用client.images.search()函数来搜索包含关键词"ubuntu"的镜像。搜索结果会以列表的形式返回,每个元素都是一个字典,包含镜像的名称、描述等信息。

3. 构建镜像:DIY你的镜像

如果你觉得Docker Hub上的镜像不能满足你的需求,可以自己构建镜像。

首先,你需要创建一个Dockerfile,这是一个文本文件,包含了构建镜像的指令。例如:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

这个Dockerfile指定了基于ubuntu:latest镜像构建,安装nginx,暴露80端口,并启动nginx。

然后,使用以下Python代码来构建镜像:

import os

# Dockerfile所在的目录
dockerfile_path = './'

# 构建镜像,并打上标签
try:
    image, build_logs = client.images.build(path=dockerfile_path, tag='my-nginx')

    # 打印构建日志
    for log in build_logs:
        if 'stream' in log:
            print(log['stream'].strip())

    print(f"成功构建镜像:{image.tags}")
except docker.errors.BuildError as e:
    print(f"构建镜像失败:{e}")
    for log in e.build_log:
        if 'stream' in log:
            print(log['stream'].strip())

这段代码使用client.images.build()函数来构建镜像。path参数指定Dockerfile所在的目录,tag参数指定镜像的标签。构建过程中会输出构建日志,如果构建失败,会打印错误信息。

五、容器操作:创建、启动、停止、删除

有了镜像,就可以创建容器了。

1. 创建容器:从镜像实例化

# 创建一个基于nginx镜像的容器
try:
    container = client.containers.create('nginx', ports={80: 8080}, detach=True)
    print(f"成功创建容器:{container.id}")
except docker.errors.APIError as e:
    print(f"创建容器失败:{e}")

这段代码使用client.containers.create()函数来创建一个基于nginx镜像的容器。ports参数指定端口映射,将容器的80端口映射到主机的8080端口。detach=True表示在后台运行容器。

2. 启动容器:让容器跑起来

# 启动容器
try:
    container.start()
    print(f"成功启动容器:{container.id}")
except docker.errors.APIError as e:
    print(f"启动容器失败:{e}")

这段代码使用container.start()函数来启动容器。

3. 停止容器:让容器休息一下

# 停止容器
try:
    container.stop()
    print(f"成功停止容器:{container.id}")
except docker.errors.APIError as e:
    print(f"停止容器失败:{e}")

这段代码使用container.stop()函数来停止容器。

4. 删除容器:清理垃圾

# 删除容器
try:
    container.remove()
    print(f"成功删除容器:{container.id}")
except docker.errors.APIError as e:
    print(f"删除容器失败:{e}")

这段代码使用container.remove()函数来删除容器。

5. 列出容器:看看有哪些容器在运行

# 列出所有容器
containers = client.containers.list(all=True)
for container in containers:
    print(f"容器ID:{container.id}, 状态:{container.status}, 名称:{container.name}")

这段代码使用client.containers.list()函数来列出所有容器。all=True表示列出所有容器,包括正在运行的和已经停止的。

6. 查看容器日志:了解容器的运行情况

# 查看容器日志
try:
    logs = container.logs()
    print(logs.decode('utf-8'))
except docker.errors.APIError as e:
    print(f"查看容器日志失败:{e}")

这段代码使用container.logs()函数来查看容器的日志。

7. 在容器中执行命令:远程控制

# 在容器中执行命令
try:
    exec_result = container.exec_run('ls -l')
    print(f"执行结果:{exec_result.output.decode('utf-8')}")
except docker.errors.APIError as e:
    print(f"执行命令失败:{e}")

这段代码使用container.exec_run()函数在容器中执行命令。

六、更高级的操作:网络、卷、Compose

除了基本的镜像和容器操作,Docker SDK还支持更高级的操作,比如网络、卷、Compose等等。

1. 网络操作:创建、连接、断开

# 创建一个网络
try:
    network = client.networks.create('my-network', driver='bridge')
    print(f"成功创建网络:{network.id}")
except docker.errors.APIError as e:
    print(f"创建网络失败:{e}")

# 连接容器到网络
try:
    network.connect(container)
    print(f"成功连接容器到网络:{network.id}")
except docker.errors.APIError as e:
    print(f"连接容器到网络失败:{e}")

# 断开容器与网络的连接
try:
    network.disconnect(container)
    print(f"成功断开容器与网络的连接:{network.id}")
except docker.errors.APIError as e:
    print(f"断开容器与网络的连接失败:{e}")

#删除网络
try:
    network.remove()
    print(f"成功删除网络:{network.id}")
except docker.errors.APIError as e:
    print(f"删除网络失败:{e}")

2. 卷操作:数据持久化

# 创建一个卷
try:
    volume = client.volumes.create('my-volume')
    print(f"成功创建卷:{volume.name}")
except docker.errors.APIError as e:
    print(f"创建卷失败:{e}")

# 删除卷
try:
    volume.remove()
    print(f"成功删除卷:{volume.name}")
except docker.errors.APIError as e:
    print(f"删除卷失败:{e}")

在创建容器的时候可以指定卷挂载:

# 创建一个基于nginx镜像的容器,并挂载卷
try:
    container = client.containers.create('nginx', ports={80: 8080}, detach=True, volumes={'my-volume': {'bind': '/data', 'mode': 'rw'}})
    print(f"成功创建容器:{container.id}")
except docker.errors.APIError as e:
    print(f"创建容器失败:{e}")

3. Compose操作:编排你的应用

Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。你可以使用Compose文件来配置你的应用服务,然后使用docker-compose up命令来启动所有服务。

虽然Docker SDK本身不直接支持Compose的全部功能,但你可以使用docker-compose命令行工具,并通过Python的subprocess模块来调用它。

首先,你需要创建一个docker-compose.yml文件,例如:

version: "3.9"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword

然后,使用以下Python代码来启动Compose项目:

import subprocess

# Compose文件所在的目录
compose_path = './'

# 启动Compose项目
try:
    result = subprocess.run(['docker-compose', '-f', os.path.join(compose_path, 'docker-compose.yml'), 'up', '-d'], capture_output=True, text=True, check=True)
    print(f"启动Compose项目成功:{result.stdout}")
except subprocess.CalledProcessError as e:
    print(f"启动Compose项目失败:{e.stderr}")

这段代码使用subprocess.run()函数来调用docker-compose up命令。capture_output=True表示捕获命令的输出,text=True表示以文本形式返回输出,check=True表示如果命令执行失败,抛出一个异常。

七、实战案例:自动化部署Web应用

咱们来做一个简单的实战案例:自动化部署一个Web应用。

  1. Dockerfile:创建一个Dockerfile,用于构建Web应用的镜像。
FROM python:3.9-slim-buster

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "app.py"]
  1. requirements.txt:列出Web应用依赖的Python库。
Flask
gunicorn
  1. app.py:Web应用的Python代码。
from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, Docker! This is running on: " + os.uname().nodename

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
  1. Python脚本:使用Docker SDK来构建镜像、创建容器并启动Web应用。
import docker
import os

client = docker.from_env()

# 镜像名称
image_name = 'my-web-app'

# 容器名称
container_name = 'my-web-app-container'

# 端口映射
ports = {5000: 8000}

# 构建镜像
try:
    image, build_logs = client.images.build(path='./', tag=image_name)
    for log in build_logs:
        if 'stream' in log:
            print(log['stream'].strip())
    print(f"成功构建镜像:{image.tags}")
except docker.errors.BuildError as e:
    print(f"构建镜像失败:{e}")
    for log in e.build_log:
        if 'stream' in log:
            print(log['stream'].strip())
    exit()

# 创建容器
try:
    container = client.containers.create(image_name, ports=ports, detach=True, name=container_name)
    print(f"成功创建容器:{container.id}")
except docker.errors.APIError as e:
    print(f"创建容器失败:{e}")
    exit()

# 启动容器
try:
    container.start()
    print(f"成功启动容器:{container.id}")
except docker.errors.APIError as e:
    print(f"启动容器失败:{e}")
    exit()

print(f"Web应用已成功部署,请访问 http://localhost:{ports[5000]}")

运行这个Python脚本,它会自动构建镜像、创建容器并启动Web应用。你可以在浏览器中访问http://localhost:8000来查看Web应用。

八、总结:Python与Docker的完美结合

今天咱们一起学习了如何使用Docker SDK for Python来控制Docker容器和镜像。从连接Docker守护进程,到拉取、搜索、构建镜像,再到创建、启动、停止、删除容器,以及网络、卷等高级操作,咱们都做了详细的讲解。

希望通过今天的讲座,大家能够掌握使用Python来自动化管理Docker环境的技能,提高工作效率,解放双手,有更多的时间去摸鱼!

一些常用方法的表格总结

操作 方法 描述
连接 Docker docker.from_env() / docker.DockerClient() 连接到本地或远程 Docker 守护进程
拉取镜像 client.images.pull(image_name) 从 Docker Hub 或其他镜像仓库拉取镜像
搜索镜像 client.images.search(term) 在 Docker Hub 上搜索镜像
构建镜像 client.images.build(path=path, tag=tag) 使用 Dockerfile 构建镜像
创建容器 client.containers.create(image, ...) 基于镜像创建容器
启动容器 container.start() 启动容器
停止容器 container.stop() 停止容器
删除容器 container.remove() 删除容器
列出容器 client.containers.list(all=True) 列出所有容器 (包括运行中和已停止的)
查看日志 container.logs() 查看容器的日志
执行命令 container.exec_run(cmd) 在容器中执行命令
创建网络 client.networks.create(name, ...) 创建 Docker 网络
连接网络 network.connect(container) 将容器连接到网络
断开网络 network.disconnect(container) 将容器从网络断开
创建卷 client.volumes.create(name) 创建 Docker 卷
删除卷 volume.remove() 删除 Docker 卷

感谢大家的观看,下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注