Docker简介
- 官方文档地址:https://www.docker.com/get-started
- 中文参考手册:https://docker_practice.gitee.io/zh-cn/
简介
# 官方定义
- We have a complete container solution for you - no matter who you are and where you are on your containerization journey.
- 翻译:我们为你提供完整的解决方案,无论你是谁无论你在哪里都可以开启你的容器之旅
- 总结:在官方之中给的定义Docker属于一个容器技术
Docker解决问题
-
在开发阶段项目能够正确运行,但是在生产阶段代码不能正确运行
在我们运行一个Django项目的时候,我们可能需要使用到MySQL Redis RabbitMQ Elasticsearch等,假如我们在Windows操作系统进行开发使用的版本为A,当我们将代码在Centos操作系统进行发布的时候可能使用的版本是B,由于版本使用的不一致导致代码运行环境有问题可能会出现各种异常,由于版本问题导致代码运行有问题会额外的给人员带来负担,如果我们使用Docker我们可以直接将运行的项目进行打包,直接使用Docker将代码项目发布即可,我们此时无需考虑使用本版,操作系统等问题,做到一次打包终身使用的效果。
优点:一次打包终身使用,无需考虑版本操作系统等问题,只需要能够正常的运行Docker服务即可
-
项目A内存资源被项目B所耗尽,导致项目A不能正常运行
在生产环境中可能一个服务器同时运行多个项目,在项目A中所需要大量的资源最终将整个服务器资源耗尽,此时项目B由于无法得到正确的运行资源最终该项目无法正确对外运行,如果我们使用Docker运行项目,此时Docker在操作系统层面起到进程隔离效果,对每个容器分配单独的运行资源,这样每个项目就会拥有独立的运行资源互相隔离互不影响
优点二:进程之间的隔离导致各个应用独立运行,互不影响
-
简化部署,提高效率
如果在比较大的项目之中可能需要使用到多台服务器充当生产环境,大量的服务器无论是运维还是环境搭建都是比较麻烦的,如果我们此时使用docker极大的降低了运维难度,减少了环境搭建的时间提高部署效率
优点三:镜像复制保证多个节点环境一致
Docker与虚拟机的区别
-
Docker体积轻巧
在上图中我们可以看出如果在虚拟机中安装操作系统再次运行一些服务,导致原本轻量的虚拟机因为安装操作系统导致虚拟机特保笨重同时对于应用的迁移也时分不方便,而使用Docker可以看到其直接运行在物理机中的操作系统因此Docker十分轻便
-
Docker部署简便
在Docker中只需要安装Docker当Docker安装成功之后在运行Docker应用即可,而使用虚拟机我们需要安装虚拟机软件其次在虚拟机软件中安装操作系统,在最终的操作系统在部署服务,这一系列的流程耗时费力
-
启动迅速节省资源
如果使用虚拟机的操作系统运行服务,例如MySQL需要向虚拟操作系统申请资源,虚拟操作系统需要向虚拟机申请资源,虚拟机再向物理机器申请资源即大致为 虚拟内存--->虚拟机内存--->物理内存导致虚拟机不但耗费资源而且启动缓慢,然而Docker直接向物理即申请资源 即为虚拟内存--->物理内存的节省资源启动迅速
对比点 | 传统虚拟机 | Docker容器 |
---|---|---|
磁盘占用 | 几个GB到几十个GB左右 | 几十MB到几百MB左右 |
CPU内存占用 | 虚拟操作系统非常占用CPU和内存 | Docker引擎占用极低 |
启动速度 | (从开机到运行项目)几分钟 | (从开启容器到运行项目)几秒 |
安装管理 | 需要专门的运维技术 | 安装、管理方便 |
应用部署 | 每次部署都费时费力 | 从第二次部署开始轻松简捷 |
耦合性 | 多个应用服务安装到一起,容易互相影响 | 每个应用服务一个容器,达成隔离 |
系统依赖 | 无 | 需求相同或相似的内核,目前推荐是Linux |
Docker安装配置
安装
# 安装依赖
[root@SR ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置国内 docker 的 yum 源(阿里云)
[root@SR ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 docker-ce
[root@SR ~]# yum install docker-ce docker-ce-cli containerd.io -y
'''
注:docker-ce-cli 作用是 docker 命令行工具包
containerd.io 作用是容器接口相关包
yum info 软件包的名字,可以查看一个包的具体作用。
'''
# 启动Docker
[root@SR ~]# systemctl start docker && systemctl enable docker
# 查看docker版本
[root@SR ~]# docker version
# 查看docker信息
[root@SR ~]# docker info
阿里源
# 由于Docker默认仓库在国外,国外速度网速感人 因此将镜像源修改国内镜像源
[root@SR ~]# mkdir -p /etc/docker
[root@SR ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://lz2nib3q.mirror.aliyuncs.com"]
}
[root@SR ~]# systemctl daemon-reload
[root@SR ~]# systemctl restart docker
[root@SR ~]# docker info
Docker核心概念与架构
核心概念
镜像(image)
- 在我们传统的安装软件的时候需要下载软件的安装包,在Docker中镜像就类似我们的软件安装包,例如我们需要安装MySQL时候需要找到MySQL的安装包,同理我们需要使用Docker运行MySQL服务就需要找到MySQL镜像。
- 特点: 只读
容器(container)
- 当我们下载啦MySQL安装包的时候我们进行安装,进而MySQL的软件包就变成了运行MySQL的程序,在我们找到某软件镜像的时候运行该镜像,该镜像就会成为一个运行某服务的容器 例如我们需要使用Docker跑MySQL服务,当我们将MySQL服务运行就可以变成运行MySQL的容器。
- 特点: 可读可写
仓库(repository)
- 当我们需要使用MySQL镜像的时候,那么这个从哪里找这个镜像呢,在Docker官方给我们提供了仓库地址,在该仓库中存放了所有的Docker镜像,当我们需要获取镜像的时候只需要从仓库地址下载即可
- 远程仓库:Docker官方提供的存放镜像的仓库
- 本地仓库:自己本地磁盘存放的Docker镜像
运行架构图
Docker常用命令
辅助命令
# 1.安装完成辅助命令
docker version -------------------------- 查看docker的信息
docker info -------------------------- 查看更详细的信息
docker --help -------------------------- 帮助命令
Image命令
# 1.查看本机中所有镜像
docker images -------------------------- 列出本地所有镜像
docker image ls -------------------------- 列出本地所有镜像
-a 列出所有镜像(包含中间映像层)
-q 只显示镜像id
# 2.搜索镜像
docker search [options] 镜像名 ------------------- 去dockerhub上查询当前镜像
-s 指定值 列出收藏数不少于指定值的镜像
--no-trunc 显示完整的镜像信息
docker search nginx
# 3.从仓库下载镜像
docker pull 镜像名[:TAG|@DIGEST] ----------------- 下载镜像
TAG:指定版本
@DIGEST:指定摘要
docker pull mysql:5.7
# 4.删除镜像
docker rmi 镜像名/镜像ID -------------------------- 删除镜像
-f 强制删除
docker rmi -f 822
# 删除所有镜像
docker rm -f $(docker images -aq)
Container命令
# 1.运行容器
docker run 镜像名 -------------------------- 镜像名新建并启动容器
--name 别名为容器起一个名字
-d 启动守护式容器(在后台启动容器)
-p 映射端口号:原始端口号 指定端口号启动
# 2.查看运行的容器
docker ps -------------------------- 列出所有正在运行的容器
-a 正在运行的和历史运行过的容器
-q 静默模式,只显示容器编号
# 3.停止|关闭|重启容器
docker start 容器名字或者容器id --------------- 开启容器
docker restart 容器名或者容器id --------------- 重启容器
docker stop 容器名或者容器id ------------------ 正常停止容器运行
docker kill 容器名或者容器id ------------------ 立即停止容器运行
stop:优雅退出如果使用该命令会向容器发送信号,容器内部会进行事务等操作
kill:直接退出容器内部无任何操作
# 4.删除容器
docker rm -f 容器id和容器名 -------------------------- 强制删除
docker rm -f $(docker ps -aq) -------------------------- 删除所有容器
# 7.查看容器的运行日志
docker logs [OPTIONS] 容器id或容器名 ------------------ 查看容器日志
-t 日志显示时间戳
-f 实时展示日志
--tail 数字 显示最后多少条
docker logs -tf --tail 5 c6
# 5.查看容器内进程
docker top 容器id或者容器名 ------------------ 查看容器内的进程
# 6.查看查看容器内部细节
docker inspect 容器id ------------------ 查看容器内部细节
# 8.进入容器内部
docker exec [options] 容器id 容器内命令 ------------------ 进入容器执行命令
-i 以交互模式运行容器,通常与-t一起使用
-t 分配一个伪终端 shell窗口 bash
-d 后台运行
docker exec -it c63 bash
# 9.容器和宿主机之间复制文件
docker cp 文件|目录 容器id:容器路径 ----------------- 将宿主机复制到容器内部
docker cp 容器id:容器内资源路径 宿主机目录路径 ----------------- 将容器内资源拷贝到主机上
# 10.容器打包成新的镜像
docker commit -m "描述信息" -a "作者信息" (容器id或者名称)打包的镜像名称:标签
docker commit -m "nginx:1.0" -a "SR" 1e nginx:1.0
# 11.打包镜像
docker save 镜像名 | ID -o 名称.tar
docker save 15 -o nginx.tar
# 12.载入镜像
docker load -i 名称.tar
docker load -i nginx.tar
# 13.容器开机自启
docker run --restart=always 镜像名称 | ID
docker run -d -p 80:80 --restart=always c2
# 14.数据卷(volum)实现与宿主机共享目录
docker run -v 宿主机的路径|任意别名:/容器内的路径 镜像名
注意:
1.如果是宿主机路径是绝对路径,宿主机目录会覆盖容器内目录内容 如果宿主机器目录不存在会自动创建
2.如果是宿主机器是相对路径则会在docker运行容器时自动在宿主机中创建一个目录,并将容器目录文件复制到宿主机中
3.容器目录不可以为相对路径必须为绝对路径
4.容器内部修改挂载点的权限宿主机器会根据容器内部属主的UID在对应的宿主机更改权限
5.容器删除不会影响宿主机挂载的目录
# 如果是宿主机器是相对路径则会在docker运行容器时自动在宿主机中创建一个目录,并将容器目录文件复制到宿主机中
docker run -d -v test2:/etc/ nginx:latest --name centos2
# 容器目录不可以为相对路径必须为绝对路径
docker run -d -v /root/test3:etc nginx:latest --name centos2
# 容器内部修改挂载点的权限宿主机器会根据容器内部属主的UID在对应的宿主机更改权限
ll -d test4/
# 容器删除不会影响宿主机挂载的目录
docker rm -f centos4
ll
# 指定容器名称
docker run -h (容器名称) 容器镜像 | ID
docker run -d -p 82:80 --name nginx2 -h nginx2 nginx:latest
docker exec -it nginx2 bash
Docker镜像组成原理
镜像组成
在上述中我们可以将镜像看做一个软件包,既然镜像属于软件包那么一个镜像就应该有软件包运行所需要的文件 例如:本省的软件文件,依赖文件,库文件,配置文件,环境变量等。
镜像体积过大
在Docker中容器属于操作系用级别隔离,因此运行一个Docker镜像还需要拥有操作系统,最终可以看出一个镜像组成包含操作系统依赖,软件自身依赖,以及软件自身包等,由于这些各种文件依赖等导致虽然Docker轻量然而镜像体积过大。
联合文件系统
Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统。而Docker就是使用联合文件系统,在上图中可以看到一个完整的Docker镜像其实是由多个文件系统共同组成对外提供一个文件系统,在Docker镜像之中每个文件系统都被加载,而对外提供的系统是由一个个子文件系统组成而该子文件系统都被加载因此整个外部文件系统所需要的所有文件都被加载。
Docker分层架构
在上图中可以看出其实镜像底层都需要操作系统等基础镜像依赖以及一些公共的库,因此我们可以将这些公共的文件进行抽象处理,这样就无需拉取镜像的时候都会拉取一些重复的文件。
如果我们进行镜像分层,可以实现资源的共享,无需加载一些重复的文件系统,这样下载镜像的时候降低了镜像的大小,运行镜像的时候无需重复运行一些重复的文件系统节省资源。
Docker网络模式
常用命令
查看网络信息
[root@localhost ~]# docker network ls
创建网桥
# -d指定网桥网络类型
[root@localhost ~]# docker network create lnmp -d bridge
删除网桥
[root@localhost ~]# docker network rm lnmp
bridge模式
简介
当我们运行某些项目的时候,可能需要运行多个容器,在某些情况下我们需要保证容器之间能够进行网络之间的通信。
当Docker服务被启动的时候,操作系统会自动生成一个网卡 docker0
,该网卡物理上属于一块网卡,逻辑上可以看做一个虚拟交换机,当Docker运行容器的时候容器会绑定到该虚拟交换机上,这样通过该虚拟交换机就行成一个二层网络用来容器互联。
在Docker容器被启动的时候创建主机会创建一对虚拟网卡 veth pair
设备(这一对网卡中其中一个网卡接收的数据,另外一块网卡会接收相同的数据),Docker将 veth pair
网卡其中一块放在Docker容器内部命名为 eth0
,另外一块网卡绑定在虚拟交换机上名称以 veth
开头,并且该虚拟交换机会自动给容器分配 IP
地址,容器内部会将网桥的 IP
地址充当网关。
图解
容器互通
# 运行两个容器
[root@localhost ~]# docker run -d -p 80:80 --network lnmp --restart=always --name nginx0 nginx:latest
[root@localhost ~]# docker run -d -p 81:80 --network lnmp --restart=always --name nginx1 nginx:latest
# 查看网桥的详细信息
[root@localhost ~]# docker inspect lnmp
# 查看容器ip
root@1524edfbce9e:~# ifconfig
# 检测网络连通性
root@1524edfbce9e:~# ping 172.19.0.2 -c 1
IP与容器名映射
虽然网桥为我们容器分配啦 IP
地址,但是该地址属于自动分配不是静态的地址,大多数的时候我们需要一个固定的 IP
地址,在Docker中会将容器 IP
地址与容器名称进行映射,当我们访问容器名称的时候就是访问容器的 IP
地址,简单粗暴的认为此时容器名称就是容器的 IP
地址。
root@1524edfbce9e:~# ping nginx0 -c 1
root@1524edfbce9e:~# curl nginx0
host模式
简介
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的网络名称空间(Network Namespace),而是和宿主机共用一个网络名称空间(Network Namespace)。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
图解
测试
[root@localhost ~]# docker run -d -p 80:80 -h nginx --name nginx --restart=always --network=host nginx:1.13.12
# 进入容器
[root@localhost ~]# docker exec -it nginx bash
container模式
简介
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信
图解
测试
# 由于nginx2与nginx1共用同一网络空间 因此此时不需要做端口映射了
[root@localhost dockercompose]# docker run --network container:nginx -d --name nginx2 --restart always nginx:1.13.12
Docker数据卷
作用
在Docker中一般使用容器用来进行计算,通俗点来说数据卷是将容器文件与宿主机文件进行映射实现将容器内的数据保存到宿主机器内,这样不但实现了数据的持久化保存同时实现了数据的共享,当我们操作宿主机器时候会将操作的结果同步到容器内。
特点
- 数据卷可以在容器与容器之间进行共享
- 对数据卷的操作会立马生效
- 对数据卷的更新不会影响镜像
- 容器是否存在不会影响数据卷
常用命令
创建数据卷
[root@localhost ~]# docker volume create test
查看数据卷
[root@localhost ~]# docker volume ls
查看详细信息
[root@localhost ~]# docker volume inspect test
删除数据卷
# 删除指定数据卷
[root@localhost ~]# docker volume rm test
# 删除未使用的数据卷
[root@localhost ~]# docker volume prune test
挂载映射
# 自动创建挂载目录会在docker默认的挂载目录下生成目录
[root@localhost ~]# docker run -d -p 80:80 --name nginx0 -h nginx0 -v nginx:/usr/share/nginx/html nginx:latest
[root@localhost ~]# cd /var/lib/docker/volumes/nginx/_data
# 向挂载点写入数据
[root@localhost _data]# echo "hello world" > index.html
# 容器向宿主机器写入数据
root@nginx0:/usr/share/nginx/html/projectA# echo "hello world" > test.txt
# 容器只读
[root@localhost ~]# docker run -d -p 81:80 --name nginx1 -h nginx1 --restart=always -v nginx:/usr/share/nginx/html:ro nginx:latest
# 外部访问容器数据
[root@localhost ~]# curl 172.17.0.2/projectA/index.html
Docker安装常用服务
安装mysql
# 1.拉取mysql镜像到本地
docker pull mysql:tag (tag不加默认最新版本)
# 2.运行mysql服务
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:tag --没有暴露外部端口外部不能连接
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:tag --没有暴露外部端口
# 3.进入mysql容器
docker exec -it 容器名称|容器id bash
# 4.外部查看mysql日志
docker logs 容器名称|容器id
# 5.使用自定义配置参数
docker run --name mysql -v /root/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -d mysql:tag
# 6.将容器数据位置与宿主机位置挂载保证数据安全
docker run --name mysql -v /root/mysql/data:/var/lib/mysql -v /root/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:tag
# 7.通过其他客户端访问 如在window系统|macos系统使用客户端工具访问
# 8.将mysql数据库备份为sql文件
docker exec mysql|容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql --导出全部数据
docker exec mysql sh -c 'exec mysqldump --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql --导出指定库数据
docker exec mysql sh -c 'exec mysqldump --no-data --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql --导出指定库数据不要数据
# 9.执行sql文件到mysql中
docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/xxx.sql
安装Redis服务
# 1.在docker hub搜索redis镜像
docker search redis
# 2.拉取redis镜像到本地
docker pull redis
# 3.启动redis服务运行容器
docker run --name redis -d redis:tag (没有暴露外部端口)
docker run --name redis -p 6379:6379 -d redis:tag (暴露外部宿主机端口为6379进行连接)
# 4.查看启动日志
docker logs -t -f 容器id|容器名称
# 5.进入容器内部查看
docker exec -it 容器id|名称 bash
# 6.加载外部自定义配置启动redis容器
默认情况下redis官方镜像中没有redis.conf配置文件 需要去官网下载指定版本的配置文件
1. wget http://download.redis.io/releases/redis-5.0.8.tar.gz 下载官方安装包
2. 将官方安装包中配置文件进行复制到宿主机指定目录中如 /root/redis/redis.conf文件
3. 修改需要自定义的配置
bind 0.0.0.0 开启远程权限
appenonly yes 开启aof持久化
4. 加载配置启动
docker run --name redis -v /root/redis:/usr/local/etc/redis -p 6379:6379 -d redis redis-server /usr/local/etc/redis/redis.conf
# 7.将数据目录挂在到本地保证数据安全
docker run --name redis -v /root/redis/data:/data -v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf -p 6379:6379 -d redis redis-server /usr/local/etc/redis/redis.conf
安装Nginx
# 1.在docker hub搜索nginx
docker search nginx
# 2.拉取nginx镜像到本地
[root@localhost ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
afb6ec6fdc1c: Pull complete
b90c53a0b692: Pull complete
11fa52a0fdc0: Pull complete
Digest: sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
# 3.启动nginx容器
docker run -p 80:80 --name nginx01 -d nginx
# 4.进入容器
docker exec -it nginx01 /bin/bash
查找目录: whereis nginx
配置文件: /etc/nginx/nginx.conf
# 5.复制配置文件到宿主机
docker cp nginx01(容器id|容器名称):/etc/nginx/nginx.conf 宿主机名录
# 6.挂在nginx配置以及html到宿主机外部
docker run --name nginx02 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/html:/usr/share/nginx/html -p 80:80 -d nginx
安装Tomcat
# 1.在docker hub搜索tomcat
docker search tomcat
# 2.下载tomcat镜像
docker pull tomcat
# 3.运行tomcat镜像
docker run -p 8080:8080 -d --name mytomcat tomcat
# 4.进入tomcat容器
docker exec -it mytomcat /bin/bash
# 5.将webapps目录挂载在外部
docker run -p 8080:8080 -v /root/webapps:/usr/local/tomcat/webapps -d --name mytomcat tomcat
安装MongoDB数据库
# 1.运行mongDB
docker run -d -p 27017:27017 --name mymongo mongo ---无须权限
docker logs -f mymongo --查看mongo运行日志
# 2.进入mongodb容器
docker exec -it mymongo /bin/bash
直接执行mongo命令进行操作
# 3.常见具有权限的容器
docker run --name mymongo -p 27017:27017 -d mongo --auth
# 4.进入容器配置用户名密码
mongo
use admin 选择admin库
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]}) //创建用户,此用户创建成功,则后续操作都需要用户认证
exit
# 5.将mongoDB中数据目录映射到宿主机中
docker run -d -p 27017:27017 -v /root/mongo/data:/data/db --name mymongo mongo
安装ElasticSearch
注意:
调高JVM线程数限制数量
拉取镜像运行elasticsearch
# 1.dockerhub 拉取镜像
docker pull elasticsearch:6.4.2
# 2.查看docker镜像
docker images
# 3.运行docker镜像
docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.4.2
- 启动出现如下错误
预先配置
# 1.在centos虚拟机中,修改配置sysctl.conf
vim /etc/sysctl.conf
# 2.加入如下配置
vm.max_map_count=262144
# 3.启用配置
sysctl -p
注:这一步是为了防止启动容器时,报出如下错误:
bootstrap checks failed max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
启动EleasticSearch容器
# 0.复制容器中data目录到宿主机中
docker cp 容器id:/usr/share/share/elasticsearch/data /root/es
# 1.运行ES容器 指定jvm内存大小并指定ik分词器位置
docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -v /root/es/plugins:/usr/share/elasticsearch/plugins -v /root/es/data:/usr/share/elasticsearch/data elasticsearch:6.4.2
安装IK分词器
# 1.下载对应版本的IK分词器
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.2/elasticsearch-analysis-ik-6.4.2.zip
# 2.解压到plugins文件夹中
yum install -y unzip
unzip -d ik elasticsearch-analysis-ik-6.4.2.zip
# 3.添加自定义扩展词和停用词
cd plugins/elasticsearch/config
vim IKAnalyzer.cfg.xml
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext_dict.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">ext_stopwords.dic</entry>
</properties>
# 4.在ik分词器目录下config目录中创建ext_dict.dic文件 编码一定要为UTF-8才能生效
vim ext_dict.dic 加入扩展词即可
# 5. 在ik分词器目录下config目录中创建ext_stopword.dic文件
vim ext_stopwords.dic 加入停用词即可
# 6.重启容器生效
docker restart 容器id
# 7.将此容器提交成为一个新的镜像
docker commit -a="xiaochen" -m="es with IKAnalyzer" 容器id xiaochen/elasticsearch:6.4.2
安装Kibana
# 1.下载kibana镜像到本地
docker pull kibana:6.4.2
# 2.启动kibana容器
docker run -d --name kibana -e ELASTICSEARCH_URL=http://10.15.0.3:9200 -p 5601:5601 kibana:6.4.2
Dockerfile
简介
Dockerfile内部是由一系列的指令组成,可以类似看成一个脚本,当运行Dockerfile文件可以帮我们生成一个自定义的镜像
自定义镜像
我们可以根据自己的业务专门制作专属的镜像,同时可以将自己的应用打包制作成镜像,后期我们进行项目迁移,或者多台服务器运行该应用我们只需要运行该镜像即可,真正的做到了一次制作,终身使用。
Dockerfile运行解析
宿主机在某目录下创建 Dockerfile
文件,包含该 Dockerfile
的目录被称之为上下文目录,在 Dockerfile
目录下写入构建镜像的指令,当 Dockerfile
文件书写完毕之后执行 Docker build
命令, Docker
会将 Dockerfile
所在的上下文目录发送给 Docker
服务端,服务端解析 Dockerfile
文件中的指令,执行一条指令会生成一个镜像文件,并且将生成的镜像文件存放在 Docker Cache
中,最终所有的镜像组合成一个最终的镜像暴露给外部用户。
Dockerfile命令简介
保留字 | 作用 |
---|---|
FROM | 当前镜像是基于哪个镜像的 |
MAINTAINER | 镜像维护者的姓名和邮箱地址(已经启用无需再写) |
RUN | 构建镜像时需要运行的指令:例如运行mysql 需要使用mysql -u root - p |
EXPOS | 当前容器对外暴露出的端口号:方便宿主机器与容器映射** |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量:例如mysql的MYSQL_ROOT_PASSWORD |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包 |
COPY | 类似于ADD,拷贝文件和目录到镜像中 将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 |
ENTRYPOINT | 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数 |
Dockerfile命令详解
FROM
- 基于那个镜像进行构建新的镜像,在构建时会自动从docker hub拉取base镜像 必须作为Dockerfile的第一个指令出现
- 语法:
FROM <image>
FROM <image>[:<tag>] 使用版本不写为latest
FROM <image>[@<digest>] 使用摘要
[root@localhost dockerfile]# vim Dockerfile
# 基于centos镜像
FROM centos:7
# 构建上下文生成镜像
[root@localhost dockerfile]# docker build -t mycentos7:01 ./
MAINTAINER
- 镜像维护者的姓名和邮箱地址[废弃]
- 语法:
MAINTAINER <name>
RUN
-
RUN指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交映像将用于Dockerfile中的下一步
-
语法:
RUN ["executable", "param1", "param2"] (exec form)
RUN ["/bin/bash", "-c", "echo hello"]
[root@localhost dockerfile]# vim Dockerfile
# 基于centos镜像
FROM centos:7
# 给新镜像添加vim命令
RUN yum -y install vim
# 构建上下文生成镜像
[root@localhost dockerfile]# docker build -t mycentos7:02 ./
EXPOSE
- 用来指定构建的镜像在运行为容器时对外暴露的端口
- 语法:
EXPOSE 80/tcp 如果没有显示指定则默认暴露都是tcp
EXPOSE 80/udp
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
[root@localhost dockerfile]# docker build -t mycentos7:03 ./
[root@localhost dockerfile]# docker run -p 80:80 mycentos7:03
WORKDIR
- 用来为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockerfile指令中使用,它也将被创建。
- 语法:
WORKDIR /path/to/workdir
# 注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对
WORKDIR /a
WORKDIR b
WORKDIR c
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
# 配置工作路径
WORKDIR /path/test
[root@localhost dockerfile]# docker build -t mycentos7:04 ./
COPY
-
用来将context目录中指定文件复制到镜像的指定目录中
-
语法:
COPY src dest
COPY ["<src>",... "<dest>"]
[root@localhost dockerfile]# cat Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
WORKDIR /path/test
# 将a.txt文件复制到/path/test中
COPY a.txt /path/test
[root@localhost dockerfile]# docker build -t mycentos7:05 ./
ADD
-
用来从context上下文复制新文件、目录或远程文件url,并将它们添加到位于指定路径的映像文件系统中,如果是压缩包在镜像中会自动解压。
-
语法:
ADD hom* /mydir/ 通配符添加多个文件
ADD hom?.txt /mydir/ 通配符添加
ADD test.txt relativeDir/ 可以指定相对路径
ADD test.txt /absoluteDir/ 也可以指定绝对路径
ADD url
[root@localhost dockerfile]# cat Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
WORKDIR /path/test
# 将a.txt文件复制到/path/test中
COPY a.txt /path/test
# 复制b.txt到/path/test中
ADD b.txt /path/test
# 复制url到指定目录下
ADD https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.70/bin/apache-tomcat-8.5.70-fulldocs.tar.gz /path/test/download
[root@localhost dockerfile]# docker build -t mycentos7:06 ./
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
WORKDIR /path/test
COPY a.txt /path/test
ADD b.txt /path/test
# 复制压缩包到指定目录在容器内部会被自动解压
ADD apache-tomcat-8.5.70-fulldocs.tar.gz /path/test
[root@localhost dockerfile]# docker build -t mycentos7:08 ./
VOLUME
- 用来定义容器运行时可以挂在到宿主机的目录
- 语法:
VOLUME ["/path1","path2"]
VOLUME /path
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
WORKDIR /path/test
COPY a.txt /path/test
ADD b.txt /path/test
# 复制压缩包到指定目录在容器内部会被自动解压
ADD apache-tomcat-8.5.70-fulldocs.tar.gz /path/test
VOLUME /path/test
[root@localhost dockerfile]# docker build -t mycentos7:10 ./
[root@localhost dockerfile]# docker run -itd --restart=always -v /path/test:/path/test mycentos7:10
[root@localhost dockerfile]# echo mysql hostos path is /path/tes > /path/test/test.txt
ENV
-
用来为构建镜像设置环境变量。这个值将出现在构建阶段中所有后续指令的环境中。
-
语法:
ENV <key> <value>
ENV <key>=<value> ...
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
RUN mkdir -p /path/test
# 将/path/test设置成环境变量
ENV BASE_DIR /path/test
# 调用环境变量BASE_DIR
WORKDIR $BASE_DIR
COPY a.txt $BASE_DIR
ADD b.txt $BASE_DIR
ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
VOLUME $BASE_DIR
[root@localhost dockerfile]# docker build -t mycentos7:13 .
CMD 命令
- 用来为启动的容器指定执行的命令,在Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
- 如果我们在运行容器的时候给CMD传入命令,则默认的命令会被传入的命令覆盖
- 语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
RUN mkdir -p /path/test
ENV BASE_DIR /path/test
WORKDIR $BASE_DIR
COPY a.txt $BASE_DIR
ADD b.txt $BASE_DIR
ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
VOLUME $BASE_DIR
[root@localhost dockerfile]# docker build -t mycentos7:14
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
RUN mkdir -p /path/test
ENV BASE_DIR /path/test
WORKDIR $BASE_DIR
COPY a.txt $BASE_DIR
ADD b.txt $BASE_DIR
ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
VOLUME $BASE_DIR
# 启动查看目录
CMD ls $BASE_DIR
[root@localhost dockerfile]# docker build -t mycentos7:17
[root@localhost dockerfile]# docker run -it mycentos7:17 ls /path/test
ENTRYPOINT
- 用来为启动的容器指定执行的命令,当有多个命令的时候其只执行最后一条命令
- 默认情况下如果我们我们在运行容器的时候给ENTRYPOINT传入命令其不会覆盖原有指令
- 语法:
["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
RUN mkdir -p /path/test
ENV BASE_DIR /path/test
WORKDIR $BASE_DIR
COPY a.txt $BASE_DIR
ADD b.txt $BASE_DIR
ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
VOLUME $BASE_DIR
ENTRYPOINT ls $BASE_DIR
# 只会执行最后一条
ENTRYPOINT echo "hello world"
[root@localhost dockerfile]# docker build -t mycentos7:19
# entrypoint默认情况下该命令不会被覆盖
[root@localhost dockerfile]# docker run -it mycentos7:19 ls /path/test
# 添加entrypoint参数覆盖指定命令
[root@localhost dockerfile]# docker run -it --entrypoint=ls mycentos7:19 /path/test
CMD与ENTRYPOINT共用
ENTRYPOINT指令,往往用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的。CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。
[root@localhost dockerfile]# vim Dockerfile
FROM centos:7
RUN yum -y install vim
EXPOSE 80/tcp
EXPOSE 80/udp
RUN mkdir -p /path/test
ENV BASE_DIR /path/test
WORKDIR $BASE_DIR
COPY a.txt $BASE_DIR
ADD b.txt $BASE_DIR
ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
VOLUME $BASE_DIR
CMD ["echo test cmd argument"]
ENTRYPOINT ["echo"]
[root@localhost dockerfile]# docker build -t mycentos7:27 .
# 此时CMD会以参数的形式传递给ENTRYPOINT 在运行的时候没有传入参数会以默认参数
[rootvim@localhost dockerfile]# docker run -it mycentos7:27
# 手动传入会覆盖默认参数
[root@localhost dockerfile]# docker run -it mycentos7:27 hello world
Dockerfile构建Django
[root@localhost dockerfile]# vim Dockerfile
#指定基础镜像
FROM python:3.6.12
RUN pip3 install django==1.11.11 -i https://pypi.douban.com/simple/
# 创建Django项目
RUN django-admin startproject app
# 配置工作目录
WORKDIR /app
# 暴露外部端口
EXPOSE 8000
# 启动服务
ENTRYPOINT ["python3","manage.py","runserver"]
# 当作参数
CMD [""]
# 构建镜像
[root@localhost dockerfile]# docker build -t demo:01 .
# 启动镜像 0.0.0.0:8000会被CMD以参数的形式传递给ENTRYPOINT
root@localhost test]# docker run -d -p 8000:8000 --name demo1 --restart=always demo:01 0.0.0.0:8000
Docker-compose
简介
Docker-compose
项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。所谓容器编排即是按照一种指定顺序对相应的容器启动。
在上述中使用一个 Dockerfile
模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
Docker-compose
恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件来定义一组相关联的应用容器为一个项目(project)。
Docker-compose
中有两个重要的概念:
- 服务 (
service
):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 - 项目 (
project
):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
文件中定义。
安装
# 下载二进制文件
[root@localhost dockerfile]# curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 添加执行权限
[root@localhost dockerfile]# chmod +x /usr/local/bin/docker-compose
# 查询是否安装成功
[root@localhost ~]# docker-compose -v
简单使用
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0" # 项目版本
services:
nginx: # 服务名称
image: nginx # 当前服务所使用的镜像
container_name: nginx # 容器名称
ports:
- 80:80 # 映射端口
# 运行
[root@localhost ~]# docker-compose up
模板文件命令
image
指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose
将会尝试拉取这个镜像。
# 语法
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0" # 项目版本
services:
nginx: # 服务名称
image: nginx # 当前服务所使用的镜像不指定tag默认为最新的
# 运行
[root@localhost ~]# docker-compose up
[root@localhost ~]# docker images
ports
暴露端口信息。使用宿主端口:容器端口 (HOST:CONTAINER)
格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
'''
当使用 `HOST:CONTAINER` 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 `YAML` 会自动解析 `xx:yy` 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
'''
# 语法
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
# 运行
[root@localhost ~]# docker-compose up
[root@localhost ~]# docker ps
networks
配置容器连接的网络。
# 语法
networks:
# 网络名称 如果只是这样定义需要手动创建网络
- some-network
- other-network
# 自动创建上述网桥
networks:
some-network:
other-network:
[root@localhost dockercompose]# cat docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
networks:
test:
# 运行
[root@localhost ~]# docker-compose up
[root@localhost dockercompose]# docker network ls
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
[root@localhost dockercompose]# docker-compose up
# 创建网桥
[root@localhost dockercompose]# docker network create test
[root@localhost dockercompose]# docker-compose up
# 查看详情
[root@localhost dockercompose]# docker inspect dockercompose_tomcat_1
# 自定义网络
[root@localhost dockercompose]# vim docker-compose.yml
version: "3"
services:
nginx:
image: tomcat:8.0-jre8
container_name: tomcat
networks:
test:
# 指定容器ip地址
ipv4_address: 172.66.0.2
networks:
test:
ipam:
config:
# 配置网段
- subnet: 172.66.0.0/16
# 配置网关
gateway: 172.66.0.1
[root@localhost dockercompose]# docker inspect tomcat
container_name
配置容器运行名称
# 语法
container_name: 容器名称 # 容器名称
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat # 配置容器名称
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
[root@localhost dockercompose]# docker-compose up
[root@localhost dockercompose]# docker ps
hostname
配置容器运行内部名称
# 语法
hostname: 容器名称
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat # 配置容器名称
hostname: tomcat
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
[root@localhost dockercompose]# docker exec -it tomcat bash
root@tomcat:/usr/local/tomcat# cat /etc/hostname
restart
配置容器开机自启动
# 语法
restart: always
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat # 配置容器名称
hostname: tomcat
restart: always
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
working_dir
配置进入容器所处目录
# 语法
restart: path
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat # 配置容器名称
hostname: tomcat
restart: always
working_dir: /root/test
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
volumes
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER
)或者数据卷名称(VOLUME:CONTAINER
),并且可以设置访问模式 (HOST:CONTAINER:ro
)。
# 语法
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
volumes:
- /root/test:/root/test
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
# 写入数据
[root@localhost dockercompose]# echo "hello world" > /root/test/test.txt
[root@localhost dockercompose]# docker exec -it tomcat bash
root@tomcat:~/test# cat test.txt
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
volumes:
- /root/test:/root/test
# 使用相对路径进行映射 必须需要声明
- tomcat01:/usr/local/tomcat/webapps
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
[root@localhost dockercompose]# vim docker-compose.yml
# 声明数据卷
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapp
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
volumes:
# 声明数据卷
tomcat01:
[root@localhost dockercompose]# docker volume ls
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
volumes:
# 使用此种方式必须先声明数据卷
tomcat01:
# 使用指定数据卷名称
external:
true
[root@localhost dockercompose]# docker volume inspect tomcat01
environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。
# 语法
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
[root@localhost dockercompose]# vim docker-compose.yml
version: "3.0"
services:
tomcat:
image: tomcat:8.0-jre8
ports:
- "8080:8080"
networks:
- test
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
mysql:
image: mysql:5.7.31
# 配置环境变量
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3306:3306"
networks:
test:
external: # 使用指定网络名称
true # 如果为true网桥必须先创建
volumes:
tomcat01:
external:
true
$ mysql -uroot -proot -h10.1.1.2
env_file
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE
方式来指定 Compose 模板文件,则 env_file
中变量的路径会基于模板文件路径。
如果有变量名称与 environment
指令冲突,则按照惯例,以后者为准。
# 语法
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
[root@localhost dockercompose]# vim docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
networks:
test:
ipv4_address: 172.66.0.2
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
# 写配置文件路径
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
$ mysql -uroot -proot -h10.1.1.2
command
覆盖容器启动后默认执行的命令。
# 语法
command: "执行命令"
[root@localhost dockercompose]# vim docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
networks:
test:
ipv4_address: 172.66.0.2
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
working_dir: /var/lib/mysql
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
# 远程连接redis
$ redis-cli -h 10.1.1.2
# 写入数据
10.1.1.2:6379> set namq SR
# 查看数据
[root@localhost _data]# cat appendonly.aof
depends_on
解决容器的依赖、启动先后的问题。以下例子中会先启动 redis
再启动 mysql
# 语法
depends_on:
# 服务名称
- mysql
- redis
[root@localhost dockercompose]# vim docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
depends_on:
# 填写服务名称
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.2
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
healthcheck
通过命令检查容器是否健康运行。
# 语法
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
[root@localhost dockercompose]# cat docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
depends_on:
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.2
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost" ]
interval: 1m30s
timeout: 10s
retries: 3
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
sysctls
配置容器内核参数。
# 语法
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
[root@localhost dockercompose]# cat docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
depends_on:
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.2
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost" ]
interval: 1m30s
timeout: 10s
retries: 3
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
ulimits
指定容器的 ulimits 限制值。
例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。
# 语法
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
[root@localhost dockercompose]# cat docker-compose.yml
version: "3"
services:
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
depends_on:
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.2
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost" ]
interval: 1m30s
timeout: 10s
retries: 3
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
build
指定 Dockerfile
所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose
将会利用它自动构建这个镜像,然后使用这个镜像。
# 语法
version: '3'
services:
webapp:
build:
# 指定dockerfile上下文目录
context: ./dir
# dockerfile文件
dockerfile: Dockerfile
# 构建镜像时候变量
args:
buildno: 1
[root@localhost dockercompose]# vim docker-compose.yml
version: "3"
services:
django:
build:
# dockerfile上下文目录路径
context: ./dockerfile
# dockerfile文件
dockerfile: Dockerfile
container_name: django
hostname: django
ports:
- "8000:8000"
restart: always
depends_on:
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.5
tomcat:
image: tomcat:8.0-jre8
container_name: tomcat
hostname: tomcat
restart: always
working_dir: /root/test
ports:
- "8080:8080"
volumes:
- /root/test:/root/test
# 使用相对路径进行映射
- tomcat01:/usr/local/tomcat/webapps
depends_on:
- mysql
- redis
networks:
test:
ipv4_address: 172.66.0.2
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost" ]
interval: 1m30s
timeout: 10s
retries: 3
mysql:
image: mysql:5.7.31
container_name: mysql
hostname: mysql
restart: always
working_dir: /var/lib/mysql
env_file:
- ./mysqlconfig.env
ports:
- "3306:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
networks:
test:
ipv4_address: 172.66.0.3
redis:
image: redis:5.0.10
container_name: redis
hostname: redis
restart: always
working_dir: /data
ports:
- "6379:6379"
volumes:
- redisdata:/data
networks:
test:
ipv4_address: 172.66.0.4
command: "redis-server --appendonly yes"
networks:
test:
ipam:
config:
- subnet: 172.66.0.0/16
gateway: 172.66.0.1
volumes:
tomcat01:
external: true
mysqlconf:
mysqldata:
redisdata:
docker-compose常用命令
命令对象与格式
对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
执行 docker-compose [COMMAND] --help
或者 docker-compose help [COMMAND]
可以查看具体某个命令的使用格式。
docker-compose
命令的基本的使用格式是
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
命令选项
-f, --file FILE
指定使用的 Compose 模板文件,默认为docker-compose.yml
,可以多次指定。-p, --project-name NAME
指定项目名称,默认将使用所在目录名称作为项目名。--x-networking
使用 Docker 的可拔插网络后端特性--x-network-driver DRIVER
指定网络后端的驱动,默认为bridge
--verbose
输出更多调试信息。-v, --version
打印版本并退出。
命令使用案例
up
格式为 docker-compose up [options] [SERVICE...]
。
-
该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
-
链接的服务都将会被自动启动,除非已经处于运行状态。
-
可以说,大部分时候都可以直接通过该命令来启动一个项目。
-
默认情况,
docker-compose up
启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。 -
当通过
Ctrl-C
停止命令时,所有容器将会停止。 -
如果使用
docker-compose up -d
,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。 -
默认情况,如果服务容器已经存在,
docker-compose up
将会尝试停止容器,然后重新创建(保持使用volumes-from
挂载的卷),以保证新启动的服务匹配docker-compose.yml
文件的最新内容
# 后台启动
[root@localhost dockercompose]# docker-compose up -d
down`
- 此命令将会停止
up
命令所启动的容器,并移除网络
[root@localhost dockercompose]# docker-compose down
exec
- 进入指定的容器。
# exec后跟服务名称
[root@localhost dockercompose]# docker-compose exec redis bash
ps
- 列出项目中目前的所有容器。
[root@localhost dockercompose]# docker-compose ps
rm
删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop
命令来停止容器。
选项:
-f, --force
强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。-v
删除容器所挂载的数据卷。
[root@localhost dockercompose]# docker-compose stop tomcat
[root@localhost dockercompose]# docker-compose rm -f tomcat
[root@localhost dockercompose]# docker-compose ps
top
- 查看各个服务容器内运行的进程。
[root@localhost dockercompose]# docker-compose top
pause
- 将运行的容器暂停
[root@localhost dockercompose]# docker-compose pause redis
[root@localhost dockercompose]# docker-compose ps redis
unpause
- 恢复处于暂停状态中的服务
[root@localhost dockercompose]# docker-compose unpause redis
[root@localhost dockercompose]# docker-compose ps redis
stop
停止已经处于运行状态的容器,但不删除它。通过 docker-compose start
可以再次启动这些容器。
选项:
-t, --timeout TIMEOUT
停止容器时候的超时(默认为 10 秒)。
[root@localhost dockercompose]# docker-compose stop redis
[root@localhost dockercompose]# docker-compose ps redis
start
- 启动已经存在的服务容器。
[root@localhost dockercompose]# docker-compose start redis
[root@localhost dockercompose]# docker-compose ps redis
restart
格式为 docker-compose restart [options] [SERVICE...]
。
重启项目中的服务。
选项:
-t, --timeout TIMEOUT
指定重启前停止容器的超时(默认为 10 秒)。
Docker可视化工具
安装Portainer
[root@localhost ~]# docker pull portainer/portainer
[root@localhost ~]# docker volume create portainer_data
'''
1:Portainer内部端口8000 web界面端口9000
2:需要与docker引擎通信 因此需要映射scok文件
'''
[root@localhost ~]#docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer