- Dockerfile
Dockerfile其实就是根据特定的语法格式撰写出来的一个普通的文本文件
利用docker build
命令依次执行在Dockerfile中定义的一系列命令,最终生成一个新的镜像(定制镜像
)
根据dockerfile构建镜像
:docker build [OPTIONS] PATH | URL | -
命令参数:
PATH:Dockerfile所在路径(文件夹路径),文件名默认是Dockerfile
URL:Dockerfile所在URL地址
OPTIONS:
-t, --tag list:为镜像设置名称和tag
-f, --file string:指定Dockerfile的路径(这是可以使用其他名称命名Dockerfile)
特征:
1. Dockerfile内容相同构建的镜像相同,也即IMAGE ID相同;
2. IMAGE ID是随机生成的(如果删除镜像重新构建生成的ID不会是原来那个);
3. 构建的第一次会写入缓存,如果第二次执行相同的Dockerfile内容构建则走缓存;如果Dockerfile内容中间有变动,则变动内容往下的都会被重新执行
4. 只要Dockerfile内容不一样构建的镜像就是不一样的(IMAGE ID不同)
5. 基于以上特性:Dockerfile文件的修改尽量在末尾追加(每一次修改在底层都是commit操作)
6. Dockerfile必须具备一个FROM命令来进行构建
7. 每一个Dockerfile命令都会构建一层镜像(本质上是每一层都会启动一个容器,执行完命令后,将容器进行提交后,产生新的镜像层)
8. 通过查看下载下来的镜像,发现历史层信息的层ID是missing,其实是因为原本的层id只存在于构建镜像的宿主机上,一旦转移镜像后,历史层消息中将只保留最新一层的ID
- 官方Dockerfile
查看镜像历史构建信息(以从官方拉取的redis为例)
docker history redis
在github官方Dockerfile中找到redis进入,找到latest版,点击进入即可查看Dockerfile内容,与history内容一致
- Dockerfile 常用命令
- FROM: 指定基础镜像,如果基础镜像在本地不存在会执行pull操作
- RUN: 构建镜像过程中需要执行的命令。可以有多条。docker build的时候执行
如果包含多条命令,必须要要使用json的格式,如[“executable”, “param1”, “param2”]
执行一条命令是用的shell 方式执行(子进程运行,先前设置的环境变量可以访问)
执行多条命令是用的exec方式执行(主进程运行,先前设置的环境变量无法访问) - CMD:添加启动容器时需要执行的命令。多条只有最后一条生效。可以在启动容器时被覆盖和修改。(3种写法)
- ENTRYPOINT:同CMD,但这个一定会被执行,不会被覆盖修改。(2种写法)
- LABEL:为镜像添加对应的数据。在docker inspect IMAGE 中 .ContainerConfig.Labels 查看
- MAINTAINER:表明镜像的作者。将被遗弃,被LABEL代替。
- EXPOSE:设置对外暴露的端口。在docker inspect IMAGE 中 .Config.ExposedPorts 查看
- ENV:设置执行命令时的环境变量,并且在构建完成后,仍然生效
- ARG:设置只在构建过程中使用的环境变量,构建完成后,将消失
- ADD:将本地文件或目录拷贝到镜像的文件系统中。能解压特定格式文件(.tar.gz),能将URL作为要拷贝的文件
- COPY:将本地文件或目录拷贝到镜像的文件系统中。
- VOLUME:添加数据卷
- USER:指定以哪个用户的名义执行RUN, CMD 和ENTRYPOINT等命令
- WORKDIR:设置工作目录
- ONBUILD:如果制作的镜像被另一个Dockerfile使用,将在那里被执行Docekrfile命令
- STOPSIGNAL:设置容器退出时发出的关闭信号。(kill -l查看所有信号)
- HEALTHCHECK:设置容器状态检查。
- SHELL:更改执行shell命令的程序。Linux的默认shell是[“/bin/sh”, “-c”],Windows的是[“cmd”, “/S”, “/C”]。
- CMD和ENTRYPOINT的区别
命令行指令会覆盖CMD指令(缺省),而不会覆盖ENTRYPOINT指令(ENTRYPOINT指令优先级比CMD高)
-
Docker Compose:一个能一次性
定义和管理多个Docker容器的工具
Compose中定义和启动的每一个容器都相当于一个服务(service)
Compose中能定义和启动多个服务,且它们之间通常具有协同关系-
管理方式:
使用YAML文件来配置我们应用程序的服务。
使用单个命令(docker-compose up),就可以创建并启动配置文件中配置的所有服务 -
工作原理:
-
安装方法查看
Linux下需要单独安装:
第一步:
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
第二步:sudo chmod +x /usr/local/bin/docker-compose
终端中使用docker-compose --version
查看安装的版本
建议使用 最新版本 -
Docker Compose CLI 官方文档
对比后会发现:Docker Compose CLI的很多命令的功能和Docker Client CLI是相似的。最主要的区别就是前者能一次性运行管理多个容器,后者只能一次管理一个。
Docker Compose File 有多个版本,基本是向后兼容的,但也有极个别配置项高版本中没有
- 在docker-compose.yml一开始就需要利用version关键词标明当前file使用的版本
- Docker Compose File 顶级配置项:
version:指定Docker Compose File版本号
services:定义多个服务并配置启动参数
volumes:声明或创建在多个服务中共同使用的数据卷对象
networks:定义在多个服务中共同使用的网络对象
configs:声明将在本服务中要使用的一些配置文件
secrets:声明将在本服务中要使用的一些秘钥、密码文件
x-***:自定义配置。主要用于复用相同的配置。
更多详细配置
- Docker Compose 案例一:小型Flask web服务项目搭建
步骤:
-
根据项目环境,利用Dockerfile构建镜像
Dockerfile# Flask web app v1.0 # 搭建一个基于Flask的web项目:实现简单的访问量统计 # 第一步:获取一个镜像 Python3.6 使用alpine版本,轻量级的Python,节省存储 FROM python:alpine3.6 # 第二步:拷贝项目代码到镜像中 使用COPY,因为他不会做多余的操作 COPY ./flask-web-code /code # 第三步:安装项目的依赖模块 WORKDIR /code RUN pip install -r requirements.txt # 第四步:配置项目启动 CMD参数 python app.py CMD ["python", "app.py"]
docker build . -t my-flask-web
-
撰写docker-compose.yaml配置文件,启动项目
docker-compose.ymlversion: "3.6" services: flask-web: build: . ports: ["5000:5000"] container_name: flask-web networks: - web redis: image: redis container_name: redis networks: - web volumes: - web-data:/data networks: web: driver: "bridge" volumes: web-data: driver: "local"
说明:
- 缩进要统一(要么2个空格,要么4个空格)
- 内容放在同一行的冒号: 后面要接空格(volumes下面指定的是挂载点,冒号:后面不能有空格)
- 如果不指定volumes,重启服务以后会使用新的数据卷,前面的数据将无法复用,因此要指定volumes保证服务重启以后数据一致性。
启动:docker-compose up -d (首次启动会进行构建镜像比较耗时)
关闭:docker-compose down
-
- Docker Compose 案例二 单机环境ELK系统搭建
-
拉取Elasticsearch / Logstash / Kibana 镜像(国外比较慢)
-
配置参数:sysctl -w vm.max_map_count=262144(加入到/etc/rc.local 开机自动配置)
-
docker-compose.yml 参照 搭建文档
version: '2.2' services: es01: image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0 container_name: es01 environment: - node.name=es01 - discovery.seed_hosts=es02 - cluster.initial_master_nodes=es01,es02 - cluster.name=docker-cluster - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - esdata01:/usr/share/elasticsearch/data ports: - 9200:9200 networks: - esnet es02: image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0 container_name: es02 environment: - node.name=es02 - discovery.seed_hosts=es01 - cluster.initial_master_nodes=es01,es02 - cluster.name=docker-cluster - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - esdata02:/usr/share/elasticsearch/data networks: - esnet logstash: image: docker.elastic.co/logstash/logstash:7.3.0 environment: - "LS_JAVA_OPTS=-Xms256m -Xmx256m" container_name: logstash networks: - esnet depends_on: - es01 - es02 kibana: image: docker.elastic.co/kibana/kibana:7.3.0 container_name: kibana ports: - "5601:5601" depends_on: - es01 - es02 networks: - esnet volumes: esdata01: driver: local esdata02: driver: local networks: esnet:
-
启动Elasticsearch:docker-compose up
检查是否启动成功:docker ps -a(如果启动失败使用docker logs -f
查看是否有报错日志)
-
- Docker Compose 案例三 多主机环境ELK系统搭建
- Swarm 介绍:
- 集群版Docker Compose工作原理
- 搭建步骤
- 使用docker swarm配置多个docker node集群节点、
主节点:docker swarm init
从节点执行上面红框部分语句即可 - 配置集群版ELK的docker-compose.yaml文件
注意:版本3+;加入deploy;删除无效配置;bootstrap.memory_lock=falseversion: '3.6' services: es01: image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0 environment: - node.name=es01 - discovery.seed_hosts=es02 - cluster.initial_master_nodes=es01,es02 - cluster.name=docker-cluster - bootstrap.memory_lock=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" volumes: - esdata01:/usr/share/elasticsearch/data ports: - 9200:9200 networks: - esnet deploy: placement: constraints: - node.role == manager es02: image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0 environment: - node.name=es02 - discovery.seed_hosts=es01 - cluster.initial_master_nodes=es01,es02 - cluster.name=docker-cluster - bootstrap.memory_lock=false - "ES_JAVA_OPTS=-Xms512m -Xmx512m" volumes: - esdata02:/usr/share/elasticsearch/data networks: - esnet deploy: placement: constraints: - node.role == worker logstash: image: docker.elastic.co/logstash/logstash:7.3.0 environment: - "LS_JAVA_OPTS=-Xms256m -Xmx256m" networks: - esnet deploy: replicas: 2 logstash2: image: docker.elastic.co/logstash/logstash:7.3.0 environment: - "LS_JAVA_OPTS=-Xms256m -Xmx256m" networks: - esnet deploy: replicas: 2 kibana: image: docker.elastic.co/kibana/kibana:7.3.0 ports: - "5601:5601" networks: - esnet deploy: placement: constraints: - node.role == manager volumes: esdata01: driver: local esdata02: driver: local networks: esnet: driver: "overlay"
- 利用
docker stack deploy -c docker-compose.yml elk
部署集群版ELK环境
查看所有服务:docker service ls
查看特定服务日志:docker service logs elk_elasticsearch -f
删除先前部署的ELK环境:docker stack rm elk
- Swarm 介绍:
- 杂七杂八
- 容器存储空间计算:
(基础镜像大小+程序大小+每天日志增长量x容器周期)x容器数量+富余空间(+20%)