Hướng dẫn run docker with python - chạy docker với python

Docker là gì?

Docker là nền tảng cung cấp cho các công cụ, service để các lập trình viên và người quản trị hệ thống có thể phát triển, thực thi, chạy các ứng dụng với containers. Việc sử dụng các Linux containers để triển khai ứng dụng được gọi là containerization. Việc sử dụng container giúp dễ dàng hơn trong việc triển khai ứng dụng.

Để hiểu hơn về

import docker
client = docker.from_env()
3, bạn có thể tham khảo Series Tìm hiểu về Docker. Trong bài này, mình sẽ chia sẻ về cách sử dụng Python đẻ tương tác với
import docker
client = docker.from_env()
3.

Công cụ sử dụng

Các công cụ mình sử dụng trong bài chia sẻ này gồm:

  • Docker version 18.06.1-ce, build e68fc7a
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:56 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:21 2018
  OS/Arch:          linux/amd64
  Experimental:     false

  • Python 3.5
  • Docker SDK for Python lastest stable version: Là thư viện Python cho Docker Engine API. Nó sẽ giúp bạn dùng được mọi thứ mà
    import docker
    client = docker.from_env()
    
    5 command có thể, từ bên trong ứng dụng Python, từ việc chạy
    import docker
    client = docker.from_env()
    
    6, quản lý
    import docker
    client = docker.from_env()
    
    6, quản lý
    import docker
    client = docker.from_env()
    
    8, v..v

Các công cụ đề u có documentation dễ hiểu, giúp bạn dễ dàng cài đặt và sử dụng.

Sử dụng Python tương tác với Docker.

Tạo đối tượng client

Để tương tác với

import docker
client = docker.from_env()
9, bạn cần khởi tạo 1 instance cho client.
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
0 hỗ trợ thông qua việc bạn gọi hàm
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
1. Nó sẽ trả về cho bạn 1
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
2 được cấu hình giống với client mà bạn chạy khi dùng
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
3.

import docker
client = docker.from_env()

Ngoài ra bạn có thể tự cấu hình đường dẫn URL đến Docker server, ví dụ như:

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
  • param base_url: sẽ chỉnh dụng URL ddeessn Docker server, bạn có thể sử dụng
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    
    4 hoặc
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    
    5

Khi đã có client, lúc này ứng dụng đã sẵn sàng để tương tác với Docker rồi.

Quản lý Docker containers

1. Chạy container

Để chạy container bạn cần sử dụng method

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
6 có sẵn ở bên trong
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
7. Mặc định khi gọi tới method
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
8, nó sẽ đợi cho tới khi container hoàn tất việc chạy và trả về logs, tương tự như command
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
9.

Khi bạn định nghĩa thêm tham số

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
0 cho method
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
1, thì client sẽ chạy container và ngay lập tức trả về cho bạn 1
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
2 object, hiểu đơn giản là client sẽ chạy container ngầm, tương tự
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
3.

Ví dụ:

  • Chạy container:
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
  • Chạy container ngầm, nhận lại 1 Container object:
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )

Ở ví dụ trên , trong method

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
1 mình có sử dụng thêm vài tham số với mục đích là connect container nữa tạo vào 1
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
5 có tên là Docker-network, mount 1 thư mục từ bên ngoài máy host vào trong container này và cho quyền đọc ghi ở trên đó. Ngoài ra,
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
6 cũng support đầy đủ các option khác, tương tự như khi bạn sử dụng Docker command, bạn có thể tham khảo ở đây.

2. Hiển thị danh sách container.

Giống với lệch

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
7, để list danh sách các containers, Docker SDK cung cấp hàm
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
8 với các tham số:

  • all hiển thị tất cả container. hiển thị tất cả container.
  • limit: giới hạn số container được trả về.: giới hạn số container được trả về.
  • since: hiển thị các container được tạo kể từ ID hoặc name đến nay, bao gồm cả các container không hoạt động.: hiển thị các container được tạo kể từ ID hoặc name đến nay, bao gồm cả các container không hoạt động.
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.list()
# Chỉ hiển thị những containers đang hoạt động.
# [, ]

client.containers.list(all=True)
# Toàn bộ các containers bao gốm cả container không hoạt động.
#[, , , , , ] 

3. Tương tác với container.

Với

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.run('alpine', 'echo hello world')

# b'hello world\n'
9 được trả về khi chạy container, ta có thể dễ dàng tương tác với container đó.

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
print(container.status)
# running

container.kill(9) # Kill container đang chạy đó bằng việc gửi đến nó 1 signal SIGKILL.

container.restart() # Khởi động lại container.

Bạn cũng có thể chạy command bên trong container, tương tự như lệnh

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
0.

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'Ubuntu:16.04',
                detach=True,
                command=['/bin/bash'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
output = container.exec_run('ls -la', workdir='/home/dao.thai.son/workspace', tty=True, stream=True)
for line in output[1]:
    print(line.decode('utf-8'), end="\n")
    
# total 56436
# drwxr-xr-x 42 dao.thai.son domain^users     4096 Th21 13 10:48 .
# drwxr-xr-x 55 dao.thai.son domain^users     4096 Th21 15 07:43 ..
# drwxr-xr-x  3 dao.thai.son domain^users     4096 Th06 21 14:31 build
# drwxr-xr-x  4 dao.thai.son domain^users     4096 Th05 23 07:24 c

Mặc định

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
1 sẽ trả về 1 tuple gồm
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
2 kiểu int và
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
3 kiểu str. Mình sẽ giải thích 1 chút về các params trong
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
1 mà mình sử dụng:

  • 'ls -la': chính là command mà bạn muốn chạy bên trong container
  • workdir: Chỉ định work directory mà command sẽ thực hiện tại đó
  • tty: hỗ trợ TTY
  • stream=True: Trả về log dạng stream.

Ngoài ra còn có thể dùng các params:

  • stdout, stderr, stdin: attach với stdout, stderr, stdin
  • socket: Trả về 1 connection socket cho phép tùy biến quá trình đọc ghi.
  • environment: 1 dict hoặc list str là các biến môi trường cần sử dụng.

Quản lý images

Chúng ta có thể quản lý images trên server thông qua các methods trong

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run(
                'mysql:5.7',
                detach=True,
                command=['checkpoint.sh'],
                volumes= 
                    {
                        '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                    },
                stdin_open=True,
                tty=True,
                network='Docker-network',
            )
5:

  • Build image từ Dockerfile bằng method
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    container = client.containers.run(
                    'mysql:5.7',
                    detach=True,
                    command=['checkpoint.sh'],
                    volumes= 
                        {
                            '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                        },
                    stdin_open=True,
                    tty=True,
                    network='Docker-network',
                )
    
    6,
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    container = client.containers.run(
                    'mysql:5.7',
                    detach=True,
                    command=['checkpoint.sh'],
                    volumes= 
                        {
                            '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                        },
                    stdin_open=True,
                    tty=True,
                    network='Docker-network',
                )
    
    7 đến thư mục chứa Dockerfile bắt buộc phải có, hoặc
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    container = client.containers.run(
                    'mysql:5.7',
                    detach=True,
                    command=['checkpoint.sh'],
                    volumes= 
                        {
                            '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                        },
                    stdin_open=True,
                    tty=True,
                    network='Docker-network',
                )
    
    8 là đối tượng file sử dụng như Dockerfile,
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    container = client.containers.run(
                    'mysql:5.7',
                    detach=True,
                    command=['checkpoint.sh'],
                    volumes= 
                        {
                            '/home/dao.thai.son/workspace': {'bind': '/home/dao.thai.son/workspace', 'mode': 'rw'}
                        },
                    stdin_open=True,
                    tty=True,
                    network='Docker-network',
                )
    
    9 để chỉ định tag cho image được tạo ra.
image = client.images.build('path_to_dir_contain_Dockerfile', tag='0.1')
  • Pull image từ Docker Hub, qua method
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    client.containers.list()
    # Chỉ hiển thị những containers đang hoạt động.
    # [, ]
    
    client.containers.list(all=True)
    # Toàn bộ các containers bao gốm cả container không hoạt động.
    #[, , , , , ] 
    
    0, nếu bạn không chỉ định tag cho image này, toàn bộ image sẽ được được pull về. Nếu repository không public, bạn có thể đăng nhập thông qua config chỉ định trong param
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    client.containers.list()
    # Chỉ hiển thị những containers đang hoạt động.
    # [, ]
    
    client.containers.list(all=True)
    # Toàn bộ các containers bao gốm cả container không hoạt động.
    #[, , , , , ] 
    
    1.
# Pull image có tag `latest` trên busybox repo
image = client.images.pull('busybox:latest')
# Pull tất cả các tags trên busybox repo
images = client.images.pull('busybox')
  • Tương tự việc pull, ta cũng có thể push image lên repository ví dụ như Docker Hub bằng việc sử dụng method
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    client.containers.list()
    # Chỉ hiển thị những containers đang hoạt động.
    # [, ]
    
    client.containers.list(all=True)
    # Toàn bộ các containers bao gốm cả container không hoạt động.
    #[, , , , , ] 
    
    2, nếu
    import docker
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    client.containers.list()
    # Chỉ hiển thị những containers đang hoạt động.
    # [, ]
    
    client.containers.list(all=True)
    # Toàn bộ các containers bao gốm cả container không hoạt động.
    #[, , , , , ] 
    
    3 thì logs sẽ trả về từng blocking generator
import docker
client = docker.from_env()
0
  • Để xem các images hiện có trong server:
import docker
client = docker.from_env()
1

Theo dõi các sự kiện ở Docker

Để theo dõi các sự kiện xảy ra trên Docker server theo thời gian thực, tương tự khi bạn sử dụng command

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.list()
# Chỉ hiển thị những containers đang hoạt động.
# [, ]

client.containers.list(all=True)
# Toàn bộ các containers bao gốm cả container không hoạt động.
#[, , , , , ] 
4, bạn có thể gọi tới
import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.list()
# Chỉ hiển thị những containers đang hoạt động.
# [, ]

client.containers.list(all=True)
# Toàn bộ các containers bao gốm cả container không hoạt động.
#[, , , , , ] 
5 để lấy các sự kiện:

import docker
client = docker.from_env()
2

Tạm kết

Sau bài chia sẻ này, hy vọng các bạn đã nắm cơ bản được cách sử dụng

import docker
client = docker.DockerClient(base_url='unix://var/run/docker.sock')
client.containers.list()
# Chỉ hiển thị những containers đang hoạt động.
# [, ]

client.containers.list(all=True)
# Toàn bộ các containers bao gốm cả container không hoạt động.
#[, , , , , ] 
6 để tương tác với Docker. Mình sẽ làm tiếp các bài chia sẻ về cách tương tác với Docker Network, Docker Swarm trong thời gian tới, hy vọng các bạn tiếp tục đón nhận.