博文涉及内容一览表:
1 | Docker概览 |
2 | Docker版本安装与介绍(略) |
3 | 镜像 |
4 | 容器 |
5 | 镜像与容器 |
6 | 网络管理 |
7 | 数据卷 |
8 | 仓库 |
9 | Dockerfile |
10 | Docker Compose |
第九章 Docker核心技术 --Dockerfile
1. 简介
Dockerfile其实就是根据特定的语法格式撰写出来的一个普通的文本文件
利用docker build命令依次执行在Dockerfile中定义的一系列命令,最终生成一个新的镜像(定制镜像)
#一般默认名字是 Dockerfile
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# vim Dockerfile
-------------------------------------------
# test Dockerfile
FROM centos
RUN echo '这是一个测试的dockerfile'
-------------------------------------------
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker build -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# pwd
/root/home/docker_demo/dockerfile-dir
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# ll
total 4
-rw-r--r--1 root root 73 Mar 23 17:16 Dockerfile
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker build /root/home/docker_demo/dockerfile-dir
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos
---> 1e1148e4cc2c
Step 2/2 : RUN echo '这是一个测试的dockerfile'
---> Running in 615183849e27
这是一个测试的dockerfile
Removing intermediate container 615183849e27
---> 7c3459c0404e
Successfully built 7c3459c0404e
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 0ecb3daceb64 5 seconds ago 202MB
redis latest 4161e91dcc29 3 days ago 95MB
centos-net v1.0 cf3acaf1acc4 10 days ago 280MB
registry latest f32a97de94e1 2 weeks ago 25.8MB
ubuntu latest 47b19964fb50 6 weeks ago 88.1MB
47.101.212.36:9092/centos-latest latest 1e1148e4cc2c 3 months ago 202MB
centos latest 1e1148e4cc2c 3 months ago 202MB
#发现name和tag是NONE
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker build /root/home/docker_demo/dockerfile-dir/ -t test-image:v1.0
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos
---> 1e1148e4cc2c
Step 2/2 : RUN echo '这是一个测试的dockerfile'
---> Using cache
---> 0ecb3daceb64
Successfully built 0ecb3daceb64
Successfully tagged test-image:v1.0
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test-image v1.0 0ecb3daceb64 4 minutes ago 202MB
redis latest 4161e91dcc29 3 days ago 95MB
centos-net v1.0 cf3acaf1acc4 10 days ago 280MB
registry latest f32a97de94e1 2 weeks ago 25.8MB
ubuntu latest 47b19964fb50 6 weeks ago 88.1MB
47.101.212.36:9092/centos-latest latest 1e1148e4cc2c 3 months ago 202MB
centos latest 1e1148e4cc2c 3 months ago 202MB
# 只是进行了重命名,并没有增加镜像
#如果不使用 默认的 Dockerfile 作为名字, 可以如下操作
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# ll
total 4
-rw-r--r--1 root root 73 Mar 23 17:16 Dockerfile
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# mv Dockerfile dockerfile-test
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker build . -f /root/home/docker_demo/dockerfile-dir/dockerfile-test -t test-image:v2.0
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM centos
---> 1e1148e4cc2c
Step 2/2 : RUN echo '这是一个测试的dockerfile'
---> Using cache
---> 0ecb3daceb64
Successfully built 0ecb3daceb64
Successfully tagged test-image:v2.0
[root@izuf6csxy0jrgs3azvia67z dockerfile-dir]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test-image v1.0 0ecb3daceb64 8 minutes ago 202MB
test-image v2.0 0ecb3daceb64 8 minutes ago 202MB
redis latest 4161e91dcc29 3 days ago 95MB
centos-net v1.0 cf3acaf1acc4 10 days ago 280MB
registry latest f32a97de94e1 2 weeks ago 25.8MB
ubuntu latest 47b19964fb50 6 weeks ago 88.1MB
47.101.212.36:9092/centos-latest latest 1e1148e4cc2c 3 months ago 202MB
centos latest 1e1148e4cc2c 3 months ago 202MB
要关注
---> Using cache
当对 Dockerfile 进行build的时候, 如果是第一次 build 那么会执行每一步;
如果不是第一次build , 之前的步骤都不会再执行, 从修改的那一个步骤开始后面的不论是否修改都全部执行.
但凡进行修改就会 重新生成一个新 镜像
Dockerfile 使用命令 docker build
底层就是
docker commit
作用:
根据dockerfile创建镜像
命令格式:
docker build [OPTIONS] PATH | URL | -
命令参数:
PATH Dockerfile所在路径(文件夹路径),文件名必须是Dockerfile
URL Dockerfile所在URL地址
OPTIONS:
-t, --tag list 为镜像设置名称和tag
-f, --file string 指定Dockerfile的路径(这是可以使用其他名称命名Dockerfile)
Dockerfile 特征
Dockerfile 构建特征 (一)
==查看官方的Dockerfile:https://github.com/docker-library/docs ==
Dockerfile构建特征 (二)
Dockerfile必须具备一个FROM命令来进行构建
每一个Dockerfile命令都会构建一层镜像(本质上是每一层都会启动一个容器,执行完命令后,将容器进行提交commit后,产生新的镜像层)
通过查看下载下来的镜像,发现历史层信息的层ID是missing,其实是因为原本的层id只存在于构建镜像的宿主机上,一旦转移镜像后,历史层消息中将只保留最新一层的ID
Dockerfile 命令概述 官方权威链接
-
FROM: 指定基础镜像
-
RUN: 构建镜像过程中需要执行的命令。可以有多条。docker build
-
在
docker build
的过程中 被执行, 所以在有多条RUN命令且发生修改的时候, 一般新修改的放在后面防止重复执行命令或者造成不必要的损耗.
-
-
CMD:添加启动容器时需要执行的命令。多条只有最后一条生效。可以在启动容器时被覆盖和修改。
-
在
docker run
或者docker create
的时候 被执行 -
有三种方式, 推荐使用第三种方式
-
第一种:
CMD ["executable","param1","param2"]
(exec form) , 本质是类似linux下执行exec
的方式, 以当前的终端进程来直接执行, 且执行结束后会杀死当前终端. 所以一般并不推荐该种方式, 如果前面涉及配置环境变量等, 则没法满足功能. -
第二种:
CMD ["param1", "param2"]
(as default params to ENTRYPOINT) -
第三种:
CMD command param1 param2
(shell form). 本质上linux下启动一个子进程或者子线程来执行, 会继承当前终端的环境.
-
-
ENTRYPOINT:同CMD,但这个一定会被执行,不会被覆盖修改。
-
在
docker run
或者docker create
的时候 被执行 -
有两种方式, 推荐使用 第一种 方式
-
第一种:
ENTRYPOINT["executable","param1","param2"]
(exec form, prefered) -
第二种:
ENTRYPOINT command param1 param2
(shell form) -
推荐第一种的原因是 第二种创建子进程的时候是在后台执行, 没法传递信号到前台, 且执行命令的PID不再是1
-
-
LABEL:为镜像添加对应的数据。
-
命令:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
-
-
MLABELAINTAINER:表明镜像的作者。将被遗弃,被LABEL代替。
-
EXPOSE:设置对外暴露的端口。
-
命令:
EXPOSE <port> [<port>/<protocol>...]
, -
举例:
EXPOSE 80/udp
默认是 TCP ,可以修改 UDP -
可以设置多个暴露的端口, 写多行 EXPOSE 命令即可
-
-
ENV:设置执行命令时的环境变量,并且在构建完成后,仍然生效
-
ARG:设置只在构建过程中使用的环境变量,构建完成后,将消失
-
ADD:将本地文件或目录拷贝到镜像的文件系统中。能解压特定格式文件,能将URL作为要拷贝的文件
-
COPY:将本地文件或目录拷贝到镜像的文件系统中。
-
VOLUME:添加数据卷
-
USER:指定以哪个用户的名义执行RUN, CMD 和ENTRYPOINT等命令
-
WORKDIR:设置工作目录
-
ONBUILD:如果制作的镜像被另一个Dockerfile使用(FROM),将在那里被执行Docekrfile命令
-
STOPSIGNAL:设置容器退出时发出的关闭信号。
-
HEALTHCHECK:设置容器状态检查。
-
SHELL:更改执行shell命令的程序。Linux的默认shell是[“/bin/sh”, “-c”],Windows的是[“cmd”, “/S”, “/C”]。
总结
重点掌握:
-
Docker 容器与镜像之间的关系 (尤其commit命令的作用和效果)
-
Dockerfile 的书写规则和使用规则
第十章 Docker核心技术 之 Docker Compose
docker compose 简介
Docker Compose是一个能一次性定义和管理多个Docker容器的工具。
详细地说:
-
Compose中定义和启动的每一个容器都相当于一个服务(service)
-
Compose中能定义和启动多个服务,且它们之间通常具有协同关系
管理方式:
使用YAML文件来配置我们应用程序的服务。
使用单个命令(docker-compose up),就可以创建并启动配置文件中配置的所有服务。
docker compose 工作原理
-
Docker Compose File + Docker Compose CLI 两部分共同组成了 docker compose
-
相当于 启动 多个 service
Docker Compose 安装
•Docker for Mac与Docker for Windows自带docker-compose
•Linux下需要单独安装:
•第一步:sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-(uname -m) -o /usr/local/bin/docker-compose
•第二步:sudo chmod +x /usr/local/bin/docker-compose
终端中使用docker-compose --version查看安装的版本
这里示例安装版本是1.21.2,很可能您看到这里时,已经出现更新的版本,因此建议换成最新版本。查看最新版本。
Docker Compose CLI
•利用docker-compose --help查看或者查看官方文档
•对比后会发现:Docker Compose CLI的很多命令的功能和Docker Client CLI是相似的。最主要的区别就是前者能一次性运行管理多个容器,后者只能一次管理一个。
Docker Compose 版本
•Docker Compose File 有多个版本,基本是向后兼容的,但也有极个别配置项高版本中没有。
•在docker-compose.yml一开始就需要利用version关键词标明当前file使用的版本
Docker Compose FIle TOP配置参数概览
Docker Compose File 顶级配置项:
•version:指定Docker Compose File版本号
•services:定义多个服务并配置启动参数
•volumes:声明或创建在多个服务中共同使用的数据卷对象
•networks:定义在多个服务中共同使用的网络对象
•configs:声明将在本服务中要使用的一些配置文件
•secrets:声明将在本服务中要使用的一些秘钥、密码文件
•x-***:自定义配置。主要用于复用相同的配置。
Docker Compose 应用
无疑, 这一点内容非常重要, 需要反复实践. 时间关系, 没法详细复现一次
Docker Compose 案例一 小型web服务项目搭建
步骤:
1.搭建一个Flask小型web项目
2.根据项目环境, 利用Dockerfile构建镜像
3.撰写docker-compose.yaml配置文件, 启动项目
下面是 app.py文件:
# encoding=utf-8
import time
import redis
from flask import Flask
app = Flask(__name__)
# 此处的host是docker-compose.yaml文件中redis服务的名称
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
"""利用redis统计网站访问次数"""
retries = 5
# 由于当redis重启的时候, 可能有短暂时间无法访问redis
# 因此循环的作用就是在此期间重试, 默认重试 5 次
while True:
try:
# redis 的 incr 方法, 如果hits值存在则自动+1, 否则新增该键, 值为1
return cache.incr("hits")
except redis.exceptions.ConnectError as e:
if retries == 0:
raise e
retries -= 1
time.sleep(0.5)
@app.route("/")
def main():
count = get_hit_count()
return "欢迎访问, 网站已经累计访问{}次\n".formart(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
Dockerfile 文件
# flask web app v1.0
# 搭建一个基于flask的web项目, 实现简单的web访问量统计
# 第一步: 获取镜像: Python3.5.2
# 补充小技巧: 当无法很好判断镜像版本的时候, 可以去github上docker维护的官方lib(地址:https://github.com/docker-library/docs)上去找 对应的tag, 并且推荐找alpine的, 更加轻量
FROM python:3.5-alpine
# 第二步: 拷贝代码到镜像中: ADD COPY 注: 此项目代码量少故而采此方式, 实际中会使用其他方式拷贝到镜像中
# COPY 更加安全, 所以更推荐
COPY ./flask-web-codes /code
# 第三步: 安装项目的依赖环境: flask redis(这里把它作为另外一个镜像进行单独配置, 这里不再安装)
WORKDIR /code
RUN pip install -r requirements.txt
# 第四步: 项目启动, 通过配置 CMD 来实现: python app.py
CMD ["python", "app.py"]
docker-compose.yaml 文件内容:
version: "3.7"
services:
flask-web:
build: .
ports:
- "5000:5000"
container_name: flask-web
networks:
- web
redis:
image: redis
container_name: redis
networks:
- web
volumes:
- redis-data:/data
networks:
web:
driver: bridge
volumes:
redis-data:
driver: local
Docker Compose 案例二 单机环境ELK系统的搭建 (一)
•ELK工作原理介绍:
Docker Compose 案例二 单机环境ELK系统搭建(二)
步骤:
Docker Compose 案例三 多主机环境ELK系统搭建(一)
•Swarm 介绍
Docker Compose 案例三 多主机环境ELK系统搭建(二)
•集群版Docker Compose工作原理
集群和单个的docker-compose原理做个对比:
1.集群的镜像必须是已经创建好的, 不能在 up 的过程中再创建. 所以这里的 菱形image 只有一个;
2.单个docker-compose 中一个服务只能创建一个容器, 而集群中 一个 Sevice服务 创建了多个 container .
3.集群的 docker-compose 构成 是: Dockerfile + docker stack/service 和单机版不同.
Docker Compose 案例三 多主机环境ELK系统搭建(三)
步骤
-
使用docker swarm配置多个docker node集群节点
-
需要 官网上 查看 swarm 搭建 集群的命令
-
-
配置集群版ELK的docker-compose.yaml文件
-
利用docker stack deploy部署集群版ELK环境
实际工作中用到的一些小demo
1. Dockerfile 内容
FROM python:3.6.5
LABEL maintainer test007
ENV PYTHONUNBUFFERED 1
RUN mkdir /docker_api
WORKDIR /docker_api
ADD . /docker_api
RUN pip install --upgrade pip
RUN pip install -i https://pypi.douban.com/simple -r requirements.txt
RUN chmod u+x docker-entrypoint.sh
ENTRYPOINT ["/bin/bash", "docker-entrypoint.sh"]
2. docker-entrypoint.sh
#!/bin/bash
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000
3. docker-compose.yml
version: '3'
services:
db:
image: mysql:5.6
expose:
- 3306
environment:
MYSQL_DATABASE: db_name
MYSQL_ROOT_PASSWORD: db_pw
MYSQL_USER: root
volumes:
- ./mycustom.cnf:/etc/mysql/conf.d/custom.cnf
- ./containers/mysql/data:/var/lib/mysql
web:
build: .
restart: always
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/docker_api
ports:
- 8020:8000
depends_on:
- db
- redis
links:
- db
- redis
redis:
image: 'redis'
expose:
- 6379
volumes:
- ./redisdata:/docker_api/redisdata
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- 8021:80
links:
- db