Про что поговорим

Про что не поговорим

  • как вообще делать сборки
  • ускоряем сборки локально
  • ускоряем сборки в CI
  • как работает докер
  • когда он нужен и не нужен
  • как управлять контейнерами: rancher, swarm, portainer, k8s...
  • оптимизация размера образа
  • как объединить контейнеры в сеть
  • управление данными
  • безопасность
class ImageV1:  # docker build -> image:v1
    ...


container1_v1 = ImageV1()  # docker run image:v1
container2_v1 = ImageV1()  # docker run image:v1
...



# some time later
class ImageV2:  # docker build -> image:v2
    ...


container1_v2 = ImageV2()  # docker run image:v2
container2_v2 = ImageV2()  # docker run image:v2
...
python3 -c 'print("Hello, world!")'
FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

CMD ["python3", "-c", "print('Hello, world!')"]

ubuntu

apt

cmd

2fe221ce

4c583ab5

5ecf05ce

FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

CMD ["python3", \
    "-m", \
    "http.server"]

ubuntu

apt

cmd

2fe221ce

4c583ab5

5ecf05ce

ubuntu

apt

cmd

90d13b6a

FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

CMD ["python3", \
    "-c", \
    "print('Hello')"]
FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

COPY run.py /opt/run.py

CMD ["python3", "/opt/run.py"]

HOST

CONTAINER

some_directory

dockerfile

run.py

...

opt

run.py

/

...

...

...

FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

COPY run.py /opt/run.py

CMD ["python3", "/opt/run.py"]

AAA

BBB

ubuntu

apt

copy

cmd

CCC

DDD

FROM ubuntu:16.04

RUN apt update -y && \
    apt install -y python3

COPY run.py /tmp/run.py

CMD ["python3", "/tmp/run.py"]

AAA

BBB

ubuntu

apt

copy

cmd

CCC

DDD

ubuntu

apt

copy

cmd

EEE

FFF

from flask import Flask

app = Flask('example-server')


@app.route('/')
def home():
    return 'ok'
apt install ...
pip install ...
source code

?

?

?

apt install ...
pip install ...
source code
FROM alpine

RUN apk update && \
  apk add --update python3-dev py3-pip && \
  pip3 install --upgrade pip

COPY requirements.txt /tmp/requirements.txt

RUN pip3 install -r /tmp/requirements.txt

WORKDIR /server

COPY ./server /server

CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000"]

HOST

CONTAINER

project

dockerfile

app.py

...

server

/

requirements.txt

server

__init__.py

app.py

__init__.py

tmp

requirements.txt

...

(1) git push

(2) git pull

CI

(3) docker push <image>:<tag>

(4) deploy

<image>:<tag>

(5) docker pull <image>:<tag>

TeamCity Server

build agent

build agent

build agent

build agent

<...>

Шаги сборки:

  1. Вычисляем тэг образа, который будем собирать, например:
    дата + ветка + хэш коммита


     
  2. Собираем: docker build

     
  3. Прогоняем тесты и линтеры

     
  4. Пушим образ в registry, если ничего не упало
RUN apk install ...
COPY req.txt /r.txt
RUN pip install ...
COPY ./code /code

awesome-service:2019-09-25-b7ed60f

FROM alpine
RUN apk install ...
COPY req.txt /r.txt
RUN pip install ...
COPY ./code /code

awesome-service:2019-09-25-b7ed60f

FROM alpine
FROM awesome-base:v1

awesome-base:v1

FROM alpine

RUN apk update && \
  apk add --update python3-dev py3-pip && \
  pip3 install --upgrade pip

COPY poetry.lock /tmp/poetry.lock
COPY pyproject.toml /tmp/pyproject.toml

RUN pip install poetry && poetry install
ARG BASE_TAG

FROM awesome-base:${BASE_TAG}

WORKDIR /server

COPY ./server /server

CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000"]

awesome-base.dockerfile

awesome.dockerfile

certifi==2018.4.16
chardet==3.0.4
Django==1.9
idna==2.6
requests==2.18.4
urllib3==1.22
certifi
chardet
Django
idna
requests
urllib3
md5sum requirements.txt
...

[tool.poetry.dependencies]
python = "^3.7"
fastapi = "^0.38.1"
uvicorn = "^0.9.0"
python-multipart = "^0.0.5"

[tool.poetry.dev-dependencies]
pytest = "^5.1"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
grep 'content-hash' poetry.lock

pyproject.toml

poetry.lock

...
content-hash = "de0b7dd2286198c11fce59..."
...
RUN apk install ...
COPY req.txt /r.txt
RUN pip install ...
FROM alpine

awesome-base:<poetry-content-hash>

Вычисляем тэг базового образа:

grep 'content-hash' poetry.lock

Пулим базовый образ:

docker pull awesome-base:de0b7dd2

Получилось?

Собираем и пушим базовый образ:

docker build ...

docker push awesome-base:de0b7dd2

Собираем основной образ

awesome:<date>-<commit-hash>

на основе базового

POETRY_HASH=$(grep 'content-hash' poetry.lock)
DOCKERFILE_HASH=$(md5sum awesome-base.dockerfile)
TAG="$POETRY_HASH-$DOCKERFILE_HASH"
FROM alpine

RUN apk update && \
  apk add --update python3-dev py3-pip && \
  pip3 install --upgrade pip

WORKDIR /awesome

COPY poetry.lock poetry.lock
COPY pyproject.toml pyproject.toml

RUN pip install poetry && poetry install

awesome-base.dockerfile

Docker

By persi

Docker

  • 226