引言
Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。
docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。
1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。隔离
2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。环境软件版本差异
3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。
总之docker就是集装箱原理。
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
官方文档地址:https://www.docker.com/get-started
中文参考手册:https://docker_practice.gitee.io/zh-cn/
# 1.官方介绍
- We have a complete container solution for you - no matter who you are and where you are on your containerization journey.
- 翻译: 我们为你提供了一个完整的容器解决方案,不管你是谁,不管你在哪,你都可以开始容器的的旅程。
- 官方定义: docker是一个容器技术。
Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。
Docker 自开源后受到广泛的关注和讨论,至今其 GitHub 项目 已经超过 5 万 7 千个星标和一万多个 fork。甚至由于 Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用 Docker。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
在开发的时候,在本机测试环境可以跑,生产环境跑不起来
这里我们拿java Web应用程序举例,我们一个java Web应用程序涉及很多东西,比如jdk、tomcat、mysql等软件环境。当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来这种情况。Docker则将程序以及使用软件环境直接打包在一起,无论在那个机器上保证了环境一致。
优势1: 一致的运行环境,更轻松的迁移
服务器自己的程序挂了,结果发现是别人程序出了问题把内存吃完了,自己程序因为内存不够就挂了
这种也是一种比较常见的情况,如果你的程序重要性不是特别高的话,公司基本上不可能让你的程序独享一台服务器的,这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免地就会受到其他程序的干扰,导致自己的程序出现问题。Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序。
优势2:对进程进行封装隔离,容器与容器之间互不影响,更高效的利用系统资源
公司要弄一个活动,可能会有大量的流量进来,公司需要再多部署几十台服务器
在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事,而且每台服务器的环境还不一定一样,就会出现各种问题,最后部署地头皮发麻。用Docker的话,我只需要将程序打包到镜像,你要多少台服务,我就给力跑多少容器,极大地提高了部署效率。
优势3: 通过镜像复制N多个环境一致容器
关于Docker与虚拟机的区别,我在网上找到的一张图,非常直观形象地展示出来,话不多说,直接上图。
比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得非常大,很笨重
。Docker是不携带操作系统的,所以Docker的应用就非常的轻巧。另外在调用宿主机的CPU、磁盘等等这些资源的时候,拿内存举例,虚拟机是利用Hypervisor去虚拟化内存,整个调用过程是虚拟内存->虚拟物理内存->真正物理内存,但是Docker是利用Docker Engine去调用宿主的的资源,这时候过程是虚拟内存->真正物理内存。
传统虚拟机 | Docker容器 | |
---|---|---|
磁盘占用 | 几个GB到几十个GB左右 | 几十MB到几百MB左右 |
CPU内存占用 | 虚拟操作系统非常占用CPU和内存 | Docker引擎占用极低 |
启动速度 | (从开机到运行项目)几分钟 | (从开启容器到运行项目)几秒 |
安装管理 | 需要专门的运维技术 | 安装、管理方便 |
应用部署 | 每次部署都费时费力 | 从第二次部署开始轻松简捷 |
耦合性 | 多个应用服务安装到一起,容易互相影响 | 每个应用服务一个容器,达成隔离 |
系统依赖 | 无 | 需求相同或相似的内核,目前推荐是Linux |
卸载原始docker
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装docker依赖
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
设置docker的yum源
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装最新版的docker社区版(Docker CE)
$ sudo yum install -y docker-ce docker-ce-cli containerd.io
指定版本安装docker
$ yum list docker-ce --showduplicates | sort -r
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
$ sudo yum install docker-ce-18.09.5-3.el7 docker-ce-cli-18.09.5-3.el7 containerd.io
启动docker
$ sudo systemctl start docker
$ sudo systemctl enable docker
关闭docker
$ sudo systemctl stop docker
测试docker安装
$ sudo docker run hello-world
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 --mirror
选项使用国内源进行安装:执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定(stable)版本安装在系统中。
$ curl -fsSL get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh --mirror Aliyun
启动docker
$ sudo systemctl enable docker
$ sudo systemctl start docker
创建docker用户组
$ sudo groupadd docker
将当前用户加入docker组
$ sudo usermod -aG docker $USER
测试docker安装是否正确
$ docker run hello-world
镜像:
一个镜像代表一个应用环境,他是一个只读的文件,如 mysql镜像,tomcat镜像,nginx镜像等容器:
镜像每次运行之后就是产生一个容器,就是正在运行的镜像,特点就是可读可写仓库:
用来存放镜像的位置,类似于maven仓库,也是镜像下载和上传的位置 Docker hubdockerFile:
docker生成镜像配置文件,用来书写自定义镜像的一些配置tar:
一个对镜像打包的文件,日后可以还原成镜像镜像和容器的关系类似于面向对象编程中的类和对象的关系
Docker | 面向对象 |
---|---|
镜像 | 类 |
容器 | 对象 |
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
访问阿里云登录自己账号查看docker镜像加速服务
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://7fsjirqs.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
验证docker的镜像加速是否生效
[root@localhost ~]# docker info
..........
127.0.0.0/8
Registry Mirrors:
'https://lz2nib3q.mirror.aliyuncs.com/'
Live Restore Enabled: false
Product License: Community Engine
docker run hello-world
[root@localhost ~]# docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
$ docker version #显示 Docker 版本信息。
$ docker info #显示 Docker 系统信息,包括镜像和容器数。
$ docker --help #帮助命令
1.查看镜像信息
$ docker images [options] #列出本地所有镜像
-a #列出所有镜像(包含中间映像层)
-q #只显示镜像id
--digests #显示镜像摘要信息
--no-trunc #不截断输出(默认截断过长的列) 完整展示
2.搜索镜像
$ docker search [options] 镜像名 #去dockerhub上查询当前镜像
-s 指定值 #列出收藏数不少于指定值的镜像
--no-trunc #不截断输出(默认截断过长的列) 完整展示
参数说明:
NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: 自动构建。
3.下载镜像
$ docker pull 镜像名[:TAG|@DIGEST]
$ docker pull 镜像名:版本
注意:下载tomcat镜像时有些tomcat版本没有web欢迎页面,可以试试以下版本(7.0.62 8.5.50)
4.删除镜像
$ docker rmi 镜像名:版本 #未指定版本删除最新版本
-f #强制删除
1.运行容器
$ docker run [OPTIONS] 镜像名 [cmd] #镜像名新建并启动容器
-i #以交互模式运行容器,通常与-t同时使用
-t #为容器重新分配一个伪终端,通常与-i同时使用
--name 别名 #为容器指定一个名字
-d #启动守护式容器(在后台启动容器),并返回容器ID
-p 映射端口号:原始端口号 #指定端口号启动,指定端口映射
-P #主机自动分配端口号,随机端口映射
--rm #当容器停止自动移除
例:$ docker run -it --name myTomcat -p 8888:8080 tomcat
$ docker run -d --name myTomcat -P tomcat
注意:
#如果启动报以下错误:
docker: Error response from daemon: driver failed programming external connectivity on endpoint myTomcaaa (1148dccd5673fab421495087d352adc5428ab6ab7cf9f3fd708b662a25d92641): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 32807 -j DNAT --to-destination 172.17.0.5:8080 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1)).
#原因:
#docker服务启动时定义的自定义链DOCKER由于某种原因被清掉
#重启docker服务及可重新生成自定义链DOCKER
#解决:
#重启docker服务后再启动容器
systemctl restart docker
docker start foo
2.查看运行的容器
$ docker ps #列出所有正在运行的容器
-a #显示所有的容器,包括未运行的。
-l #显示最近创建的一个容器
-n 数值 #显示最近n个创建的容器
-q #静默模式,只显示容器编号
--no-trunc #不截断输出(默认截断过长的列) 完整展示
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称
3.退出容器
$ exit #容器停止退出
$ Ctrl+p+q #容器不停止退出
**4.进入容器 **
$ docker attach 容器名字/容器id
5.删除容器
$ docker rm 容器名字/容器id #删除容器
$ docker rm -f 容器名字/容器id #删除正在运行的容器
$ docker rm -f $(docker ps -aq) #删除所有容器
6.重启容器
$ docker start 容器名字/容器id #开启容器
$ docker restart 容器名字/容器id #重启容器
7.停止正在运行的容器
$ docker stop 容器名字/容器id #正常停止容器运行
$ docker kill 容器名字/容器id #立即停止容器运行
8.查看容器日志
$ docker logs [OPTIONS] 容器名字/容器id
-t #加入时间
-f #跟随最新的日志打印
--tail 数字 #显示最后多少条
9.查看容器内的进程
$ docker top 容器名字/容器id
10.查看容器内部细节
$ docker inspect 容器名字/容器id
11.进入容器
$ docker exec [options] 容器名字/容器id 容器内命令
-i #以交互模式运行容器,通常与-t一起使用
-t #分配一个伪终端
eg: docker exec -it centoss ls
docker exec -it mytomcat /bin/bash
12.拷贝
$ docker cp 容器名字/容器id:容器内资源路径 宿主机目录路径 #将容器内资源拷贝到主机上
eg:
[root@localhost~]docker cp centoss:/aaa.txt /root/
#宿主机与容器之间可以相互分享文件
$ docker cp 宿主机目录路径 容器名字/容器id:容器内资源路径
eg:docker cp /root/bbb.txt centoss:/
宿主机:Docker安装在哪谁就是宿主机 centos
容器:在Docker种根据镜像启动的就是容器 centos容器
13.把一个容器副本打包镜像
$ docker commit -a="作者" -m="描述信息" 容器ID 目标镜像名称:TAG
例:docker commit -a="nan" -m="witout docs" b35d35f72b8d nan/mytomcat:1.2
1.从dockerHub上下载tomcat镜像到本地并成功运行
2.删除上一步镜像产生的容器的doc目录
3.以当前没有doc目录的tomcat为模板commit生成一个新的镜像
4.启动新的镜像并和原来的对比
14.将指定镜像保存成 tar 归档文件
$ docker save IMAGEID [OPTIONS] filename
-o #输出到的文件。
eg:docker save tomcat:8.5.50 -o tomcat-8.5.50.tar
15.导入使用 docker save命令导出的镜像
$ docker load [OPTIONS]
-i #指定导入的文件,代替 STDIN。
eg:docker load -i mysql-5.6.tar
16.列出指定的容器的端口映射
$ docker port [OPTIONS] CONTAINER [PRIVATE_PORT[/PROTO]]
简单来说就是做数据持久化的。类似磁带,移动硬盘或者U盘。或者类似Redis中的rdb和aof文件。主要做容器数据的持久化和容器之间数据共享。卷就是目录或者文件,存在一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System 提供一些用于持久储存或者共享数据的特性。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
1、数据卷可在容器之间共享或重用数据。
2、卷中的更改可以直接生效。
3、数据卷中的更改不会包含在镜像的更新中。
4、数据卷的生命周期一直持续到没有容器使用它为止。
5、数据卷也可以完成主机到容器或容器到主机之间的数据共享。
容器内添加数据卷有两种办法。第一种直接命令添加。第二种是用DockerFile添加。
1.添加
命令:docker run -it -v /宿主机的路径:/容器内的路径 镜像名
例子:docker run -it -v /hostDataValueme:/containerDataValueme centos
2.查看数据卷是否挂成功
运行 docker inspect 容器id 命令 检查json串里有没有以下内容,如果有则证明卷挂载成功。
"Mounts": [
{
"Type": "bind",
"Source": "/hostDataValueme",
"Destination": "/containerDataValueme",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
之后可检查容器与主机是否可以共享资源。或者容器关闭之后,再开启容器之后能不能读取并加载主机的卷中数据。
设置容器内数据卷只读。
命令:docker run -it -v /主机路径:/容器内路径:ro 镜像名
例子:docker run -it -v /hostDataValueme:/containerDataValueme:ro centos
检查配置文件
"Mounts": [
{
"Type": "bind",
"Source": "/hostDataValueme",
"Destination": "/containerDataValueme",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
}
],
什么是Dockerfile
简单来说就是一个镜像的描述文件。
1. 在某个目录下新建一个file(dockerfile),在该file中添加以下脚本
例如:在/目录下创建一个mydocker的文件夹,在该文件夹下创建dockerfile文件
# volume test
FROM centos
VOLUME ["/containerDataValueme1","/containerDataValueme2"]
CMD echo "finished,-------success!"
CMD /bin/bash
备注:可在dockerfile中使用volume指令来给镜像添加一个或多个数据卷。
2. build后生产镜像 (用编写好的file文件构建镜像)
$ docker build -f mydocker/dockerfile -t zcn/centos .
-f #指定dockerfile文件路径
-t #指定目标镜像名称
. #在当前文件夹
当镜像创建出来后,以当前镜像运行一个容器实例。这时会发现,容器中已经有了我们之前写好的数据卷,但是容器里数据卷要和主机进行数据共享。那么主机的数据卷体现在哪里?别急,虽然我们不能用dockerfile指定主机的卷。但是docker会为我们提供了默认的主机数据卷。
运行docker inspect 检查一下,就会发现:
"Mounts": [
{
"Type": "volume",
"Name": "459e7a4be53a96eee859f11d10bc0b26a6a91bbd6754ecb8e355e9fe4a31e0b9",
"Source": "/var/lib/docker/volumes/459e7a4be53a96eee859f11d10bc0b26a6a91bbd6754ecb8e355e9fe4a31e0b9/_data",
"Destination": "/containerDataValueme2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "4bf41829e4afaebbb40cf3d0d4725343980afffa04f09a30680fa957d80b6af4",
"Source": "/var/lib/docker/volumes/4bf41829e4afaebbb40cf3d0d4725343980afffa04f09a30680fa957d80b6af4/_data",
"Destination": "/containerDataValueme1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
使用Dockerfile构建镜像的好处
出于可移植性的分享的考虑,用-v这种方式不能够直接在Dockerfile中实现。
由于宿主机目录是依赖于特定宿主机的,并不能保证在所有的宿主机上都存在这样的特定目录。
数据卷
是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
数据卷
可以在容器之间共享和重用数据卷
的修改会立马生效数据卷
的更新,不会影响镜像数据卷
默认会一直存在,即使容器被删除注意:
数据卷
的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。
[root@centos ~]# docker volume create my-vol
my-vol
[root@centos ~]# docker volume inspect my-vol
[
{
"CreatedAt": "2020-11-25T11:43:56+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
[root@centos ~]# docker run -d -P --name web -v my-vol:/usr/share/nginx/html nginx
[root@centos ~]# docker inspect web
"Mounts": [
{
"Type": "volume",
"Name": "my-vol",
"Source": "/var/lib/docker/volumes/my-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
docker volume rm my-vol
docker volume ls
当 Docker 启动时,会自动在主机上创建一个 docker0
虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
同时,Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给 docker0
接口。比如典型的 172.17.42.1
,掩码为 255.255.0.0
。此后启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16
)的地址。
当创建一个 Docker 容器的时候,同时会创建了一对 veth pair
接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0
;另一端在本地并被挂载到 docker0
网桥,名称以 veth
开头(例如 vethAQI2QT
)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
# docker network ls
# docker network create -d bridge 网桥名称
# docker network create 网桥名称
# docker network rm 网桥名称
# 1.查询当前网络配置
- docker network ls
NETWORK ID NAME DRIVER SCOPE
8e424e5936b7 bridge bridge local
17d974db02da docker_gwbridge bridge local
d6c326e433f7 host host local
# 2.创建桥接网络
- docker network create -d bridge info
[root@centos ~]# docker network create -d bridge info
6e4aaebff79b1df43a064e0e8fdab08f52d64ce34db78dd5184ce7aaaf550a2f
[root@centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8e424e5936b7 bridge bridge local
17d974db02da docker_gwbridge bridge local
d6c326e433f7 host host local
6e4aaebff79b info bridge local
# 3.启动容器指定使用网桥
- docker run -d -p 8890:80 --name nginx001 --network info nginx
- docker run -d -p 8891:80 --name nginx002 --network info nginx
`注意:一旦指定网桥后--name指定名字就是主机名,多个容器指定在同一个网桥时,可以在任意一个容器中使用主机名与容器进行互通`
[root@centos ~]# docker run -d -p 8890:80 --name nginx001 --network info nginx
c315bcc94e9ddaa36eb6c6f16ca51592b1ac8bf1ecfe9d8f01d892f3f10825fe
[root@centos ~]# docker run -d -p 8891:80 --name nginx002 --network info nginx
f8682db35dd7fb4395f90edb38df7cad71bbfaba71b6a4c6e2a3a525cb73c2a5
[root@centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8682db35dd7 nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:8891->80/tcp nginx002
c315bcc94e9d nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 0.0.0.0:8890->80/tcp nginx001
b63169d43792 mysql:5.7.19 "docker-entrypoint.s…" 7 minutes ago Up 7 minutes 3306/tcp mysql_mysql.1.s75qe5kkpwwttyf0wrjvd2cda
[root@centos ~]# docker exec -it f8682db35dd7 /bin/bash
root@f8682db35dd7:/# curl http://nginx001
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.....
镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。
镜像就是花卷
UnionFS(联合文件系统):
Union文件系统是一种分层,轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。这种文件系统特性:就是一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录 。
docker的镜像实际是由一层一层的文件系统组成。
最大的一个好处就是资源共享
# 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
1.在DockerHub上查找mysql镜像
$ docker search mysql
2.将mysql拉去到本地
$ docker pull mysql:5.6
3.运行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
#为用户设置客户端连接密码
-e MYSQL_ROOT_PASSWORD=root
**4.进入这个容器 **
$ docker exec -it 容器id /bin/bash
5.Mysql操作
#进入mysql
mysql -u root -p
#输入密码 123456
#查询mysql的库
show databases;
#创建数据库
create database ems;
#切换到db01
use ems;
#建表
create table t_book(id int not null primary key, name varchar(20));
#查询所有表
show tables;
#向表中插入一条数据
insert into t_book values(1,'java');
#查询这张表的数据
select * from t_book;
#用我们外部win10的大黄navcat尝试连接这个mysql
6.查看MYSQL日志
$ docker logs 容器名称|容器id
**7.MYSQL数据备份测试 **
将容器数据位置与宿主机位置挂载保证数据安全
$ docker run -p 映射端口:3306 --name 自定义名字 -v 宿主机目录:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=自定义密码 -d mysql:tag
#eg:
docker run -p 3335:3306 --name mysqlw -v mysqlData:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6
8.自定义的MySQL配置文件
MySQL的默认配置可以在中找到
/etc/mysql/my.cnf
,其中可以包含!includedir
其他目录,例如/etc/mysql/conf.d
或/etc/mysql/mysql.conf.d
。请检查mysql
映像本身中的相关文件和目录,以获取更多详细信息。
$ docker run --name mysql -v /root/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#eg:
docker run -p 3335:3306 --name mysqlw -v mysqlConfig:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6
#启动Mysql 指定端口并数据备份以及本地保存配置文件
docker run -p 3335:3306 --name mysqlw -v mysqlData:/var/lib/mysql -v mysqlConfig:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6
9.将mysql数据库备份为sql文件
# 1.导出全部数据
$ docker exec 容器名|容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql
#eg:
docker exec b8d36482dffc sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
# 2.导出指定库数据
$ docker exec mysql sh -c 'exec mysqldump --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
#eg:
docker exec b8d36482dffc sh -c 'exec mysqldump --databases yingx -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/users.sql
# 3.导出指定库数据不要数据
$ docker exec mysql sh -c 'exec mysqldump --no-data --databases 库表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql
#eg:
docker exec b8d36482dffc sh -c 'exec mysqldump --no-data --databases yingx -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/user.sql
10.从转储文件还原数据
$ docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/xxx.sql
#eg:
docker exec -i b859bba6e061 sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/all-databases.sql
docker exec -i ef12e2c085dd sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/yingx.sql
1. 在DockerHub上查找redis镜像
$ docker search redis
2. 将redis拉去到本地
$ docker pull redis:4.0.14
3. 启动redis服务运行容器
#没有暴露外部端口
$ docker run --name redis -d redis:tag
#暴露外部宿主机端口为6379进行连接
$ docker run -d --name redis -p 6379:6379 redis:tag
$ docker run -it --name redis -p 6379:6379 redis:tag
$ docker run -it --name redis -p 6379:6379 redis:tag redis-server
4.查看启动日志
$ docker logs -t -f 容器id|容器名称
5.连接redis客户端
# 1.默认端口连接
$ docker exec -it 容器id redis-cli
# 2.指定端口连接
$ docker exec -it 容器id redis-cli -h 192.168.253.128 -p 6370
#命令说明:
-h 192.168.253.128 : #指定连接地址
-p 6370 : #指定连接端口
5.指定AOF持久化
如果启用了持久性,则数据存储在中
VOLUME /data
,可以与--volumes-from some-volume-container
或一起使用-v /docker/host/dir:/data
$ docker run --name 容器id -d -p 6379:6379 redis:tag redis-server --appendonly yes
$ docker run --name 容器id -d -p 6379:6379 -v /docker/host/dir:/data redis:tag redis-server --appendonly yes
#eg:
$ docker run --name redis -d -p 6379:6379 -v redisData:/data redis:4.0.14 redis-server --appendonly yes
6. 自定义配置启动Redis容器
默认情况下redis官方镜像中没有redis.conf配置文件 需要去官网下载指定版本的配置文件
- wget http://download.redis.io/releases/redis-5.0.8.tar.gz 下载官方安装包
- 将官方安装包中配置文件进行复制到宿主机指定目录中如 /root/redis/redis.conf文件
1.创建配置文件
#创建文件夹,新建配置文件贴入从官网下载的配置文件并修改
mkdir /root/redis/
vim /root/redis/redis.conf
2.修改需要自定义的配置
bind 0.0.0.0 #开启远程权限
port 7000 #启动端口
appenonly yes #开启aof持久化
3.配置文件介绍
bind 127.0.0.1 #bind:绑定redis服务器网卡IP,默认为127.0.0.1,即本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。
protected-mode yes #默认yes,开启保护模式,限制为本地访问,改为 no关闭保护模式
port 6379 #指定redis运行的端口,默认是6379。由于Redis是单线程模型,因此单机开多个Redis进程的时候会修改端口。
timeout 0 #设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接。默认值为0,表示不关闭。
daemonize no #默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
databases 16 #数据库个数,默认值是 16,也就是说默认Redis有16个数据库。
appendonly no #默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,改为yes开启aof持久化持久化
4…指定配置文件启动
$ docker run -p 7001:7000 --name redis -v /usr/local/docker/redis.conf:/etc/redis/redis.conf -v /usr/local/docker/data:/data -d redis:4.0.14 redis-server /etc/redis/redis.conf --appendonly yes
#eg:
$ docker run -d -p 7001:7000 --name redis -v /root/redis/redis.conf:/etc/redis/redis.conf redis:4.0.14 redis-server /etc/redis/redis.conf
#命令解释说明:
-p 7001:7000 #端口映射:前表示主机部分,:后表示容器部分。
-v #挂载目录,规则与端口映射相同。
redis-server /etc/redis/redis.conf #以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录/usr/local/docker/redis.conf
7.将数据目录挂在到本地保证数据安全
$ docker run -p 6379:6379 -d --name redis -v /root/redis/data:/data -v /root/redis/redis.conf:/etc/redis/redis.conf redis:4.0.14 redis-server /etc/redis/redis.conf
docker run -p 7777:7000 -d --name redisplus -v redisPlusData:/data -v /root/redis.conf:/etc/redis/redis.conf redis:5.0.10 redis-server /etc/redis/redis.conf
注意:调高JVM线程数限制数量
#在centos窗口中,修改配置sysctl.conf
$ vim /etc/sysctl.conf
#加入如下配置
vm.max_map_count=262144
#启用配置
$ sysctl -p
#注:这一步是为了防止启动容器时,报出如下错误:
bootstrap checks failed max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
1. 将es拉到本地
$ docker pull elasticsearch:6.8.2
2. 启动es容器
$ docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" elasticsearch:6.8.2
docker run -d --name es -p 9200:9200 -p 9300:9300 elasticsearch:6.8.2
#参数说明
-p #将docker镜像中的端口号映射宿主机器端口号,宿主机器端口号:docker容器端口号 ,可写多个,如果多个端口号是连续的,可以直接用-连接,如:4560-4600:4560-4600
-v #将docker镜像中的文件映射到宿主机器指定的文件,可以是文件夹,-v 宿主机文件:容器文件映射后可直接修改宿主机上的文件就可以改变docker中的配置,也可写多个。docker镜像中软件的配置文档默认在/usr/share”/{软件名}下
-e #指定环境变量;
注意:根据自己情况来配置 -e ES_JAVA_OPTS="-Xms256m -Xmx256m" 不配置的话,启动会占用你的2G内存,反之,配置的话,启动则根据你配置的内存来分配。
3. 访问测试
访问地址:http://192.168.253.128:9200/
4.指定数据卷启动EleasticSearch容器
# 0.复制容器中data目录到宿主机中
$ docker cp 容器id:/usr/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
#eg:
docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -v esPlugins:/usr/share/elasticsearch/plugins -v esData:/usr/share/elasticsearch/data -v esConfig:/usr/share/elasticsearch/config elasticsearch:6.8.0
4 安装IK分词器
4.1.下载对应版本的IK分词器
$ wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.8.2/elasticsearch-analysis-ik-6.8.2.zip
4.2.解压到plugins/elasticsearch文件夹中
#安装unzip
$ yum install -y unzip
#使用unzip解压zip
$ unzip -d /var/lib/docker/volumes/esPlugins/_data/ elasticsearch-analysis-ik-6.8.2.zip
4.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.4.创建配置文件
#在ik分词器目录下config目录中创建ext_dict.dic文件 编码一定要为UTF-8才能生效
$ vim ext_dict.dic 加入扩展词即可
#在ik分词器目录下config目录中创建ext_stopword.dic文件
$ vim ext_stopwords.dic 加入停用词即可
4.5.将此容器提交成为一个新的镜像
$ docker commit -a="zcn" -m="with IKAnalyzer" 容器id zcn/elasticsearch:6.8.2
4.6.使用新生成的这个es镜像创建容器,并挂载数据卷
$ docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -v /usr/local/IKAnalyzer:/usr/share/elasticsearch/plugins/elasticsearch/config zcn/elasticsearch:6.8.2
#参数说明
-p #将docker镜像中的端口号映射宿主机器端口号,宿主机器端口号:docker容器端口号 ,可写多个,如果多个端口号是连续的,可以直接用-连接,如:4560-4600:4560-4600
-e ES_JAVA_OPTS="-Xms256m -Xmx256m" #指定环境变量,设置初始堆内存和最大内存 也可以调整虚拟机内存
-v #将docker镜像中的文件映射到宿主机器指定的文件,可以是文件夹,-v 宿主机文件:容器文件映射后可直接修改宿主机上的文件就可以改变docker中的配置,也可写多个。docker镜像中软件的配置文档默认在/usr/share”/{软件名}下.
5 安装kibana
5.1.下载kibana镜像到本地
$ docker pull kibana:6.8.2
5.2.启动kibana容器
$ docker run -d --name kibana -e ELASTICSEARCH_URL=http://192.168.253.128:9200 -p 5601:5601 kibana:6.8.2
5.3.访问kibana
访问地址:http://192.168.253.128:5601/
6.挂载配置文件启动
#进入kibana容器内部
$ docker exec -it 容器内部/容器Id bash
#配置文件目录
/usr/share/kibana/config/
#挂载配置文件启动
$ docker run -d --name kibana -v kibanaConfig:/usr/share/kibana/config/ -p 5601:5601 kibana:6.8.2
docker run -d --name kibanaes -v kibanaConfig:/usr/share/kibana/config/ -p 5602:5601 kibana:6.8.0
7.测试数据
DELETE /ems
PUT /ems
{
"mappings":{
"emp":{
"properties":{
"name":{
"type":"text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"age":{
"type":"integer"
},
"bir":{
"type":"date"
},
"content":{
"type":"text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"address":{
"type":"keyword"
}
}
}
}
}
PUT /ems/emp/_bulk
{"index":{}}
{"name":"小黑","age":23,"bir":"2012-12-12","content":"为开发团队选择一款优秀的MVC框架是件难事儿,在众多可行的方案中决择需要很高的经验和水平","address":"北京"}
{"index":{}}
{"name":"王小黑","age":24,"bir":"2012-12-12","content":"Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式","address":"上海"}
{"index":{}}
{"name":"张小五","age":8,"bir":"2012-12-12","content":"Spring Cloud 作为Java 语言的微服务框架,它依赖于Spring Boot,有快速开发、持续交付和容易部署等特点。Spring Cloud 的组件非常多,涉及微服务的方方面面,井在开源社区Spring 和Netflix 、Pivotal 两大公司的推动下越来越完善","address":"无锡"}
{"index":{}}
{"name":"win7","age":9,"bir":"2012-12-12","content":"Spring的目标是致力于全方位的简化Java开发。 这势必引出更多的解释, Spring是如何简化Java开发的?","address":"南京"}
{"index":{}}
{"name":"梅超风","age":43,"bir":"2012-12-12","content":"Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API","address":"杭州"}
{"index":{}}
{"name":"张无忌","age":59,"bir":"2012-12-12","content":"ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口","address":"北京"}
GET /ems/emp/_search
{
"query":{
"term":{
"content":"框架"
}
},
"highlight": {
"pre_tags": [""],
"post_tags": [""],
"fields": {
"*":{}
}
}
}
1. 在DockerHub上查找nginx镜像
$ docker search nginx
2. 将Nginx拉到本地
$ docker pull nginx
3. 运行Nginx容器
$ docker run --name nginx-test -p 8080:80 -d nginx
#参数说明:
--name nginx-test:#容器名称。
-p 8080:80: #端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
-d nginx: #设置容器在在后台一直运行。
4.访问Nginx
访问地址:http://serverip:8080
4.进入容器
$ docker exec -it nginx-test /bin/bash
#查找目录: whereis nginx
#配置文件: /etc/nginx/nginx.conf
5.挂在nginx配置以及html到宿主机外部
#复制配置文件到宿主机
$ docker cp nginx-test(容器id|容器名称):/etc/nginx/nginx.conf 宿主机名录
#启动nginx并挂载数据卷
$ docker run -p 8080:80 -d --name nginx -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/html:/usr/share/nginx/html nginx
#eg:
docker run -p 8787:80 -d --name nginxt -v /root/niginxConfs/nginx.conf:/etc/nginx/nginx.conf -v nginxHtml:/usr/share/nginx/html nginx:1.19
1. 在DockerHub上查找RabbitMQ镜像
$ docker search rabbitmq
2. 将RabbitMQ拉到本地
$ docker pull rabbitmq:3.7.28-management
3. 运行RabbitMQ容器
$ docker run -d --hostname rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 -p 25672:25672 -p 15671:15671 -p 15672:15672 --name okong-rabbit rabbitmq:3.7.28-management
#参数说明:
-d #后台运行容器;
–name #指定容器名;
-p #指定服务运行的端口(5672:应用访问端口;15672:控制台Web端口号);
-v #映射目录或文件;
–hostname #主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名);
-e #指定环境变量;(RABBITMQ_DEFAULT_VHOST:默认虚拟机名;RABBITMQ_DEFAULT_USER:默认的用户名;RABBITMQ_DEFAULT_PASS:默认用户名的密码)
4. 访问RabbitMQ
http://serverip:15672
登录账号:guest,密码:guest
1. 在DockerHub上查找MongoDB镜像
$ docker search mongo
2. 将MongoDB拉到本地
$ docker pull mongo
3. 运行MongoDB容器
#无须权限
$ docker run -d -p 27017:27017 --name mymongo mongo
#查看mongo运行日志
$ docker logs -f mymongo
4. 进入mongodb容器
$ docker exec -it mymongo /bin/bash
#直接执行mongo命令进行操作
5.常见具有权限的容器
$ docker run --name mymongo -p 27017:27017 -d mongo --auth
6.进入容器配置用户名密码
mongo
use admin 选择admin库
#创建用户,此用户创建成功,则后续操作都需要用户认证
db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]})
exit
7.将mongoDB中数据目录映射到宿主机中
$ docker run -d -p 27017:27017 -v /root/mongo/data:/data/db --name mymongo mongo
[root@localhost ~]# docker search mysql 或者 docker pull 这些命令无法使用
Error response from daemon: Get https://index.docker.io/v1/search?q=mysql&n=25: x509: certificate has expired or is not yet valid
# 1.安装时间同步
sudo yum -y install ntp ntpdate
# 2.同步时间
sudo ntpdate cn.pool.ntp.org
# 3.查看本机时间
date
# 4.从新测试
Dockerfile可以认为是Docker镜像的描述文件,是由一系列命令和参数构成的脚本。主要作用是用来构建docker镜像的构建文件。
1.每条保留字指令都必须为大写,且后面都要跟至少一个参数。
2.指令按照从上到下,顺序执行。
3.#表示注释。
4.每条指令都会创建一个新的镜像层,并对镜像进行提交。
官方说明:https://docs.docker.com/engine/reference/builder/
保留字 | 作用 |
---|---|
FROM | 当前镜像是基于哪个镜像的 第一个指令必须是FROM |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 构建镜像时需要运行的指令 |
EXPOSE | 当前容器对外暴露出的端口号 |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包 |
COPY | 类似于ADD,拷贝文件和目录到镜像中 将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 |
ENTRYPOINT | 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数 |
15.4.1 FROM 命令
基于那个镜像进行构建新的镜像,在构建时会自动从docker hub拉取base镜像 必须作为Dockerfile的第一个指令出现
语法:
FROM
FROM [:] 使用版本不写为latest
FROM [@] 使用摘要
15.4.2 MAINTAINER 命令
镜像维护者的姓名和邮箱地址[废弃]
语法:
MAINTAINER
15.4.3 RUN 命令
RUN指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交映像将用于Dockerfile中的下一步
语法:
RUN (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN echo hello
RUN ["executable", "param1", "param2"] (exec form)
RUN ["/bin/bash", "-c", "echo hello"]
15.4.4 EXPOSE 命令
用来指定构建的镜像在运行为容器时对外暴露的端口
语法:
EXPOSE 80/tcp 如果没有显示指定则默认暴露都是tcp
EXPOSE 80/udp
15.4.5 CMD 命令
用来为启动的容器指定执行的命令,在Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
注意: Dockerfile中只能有一条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)
15.4.6 WORKDIR 命令
用来为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockerfile指令中使用,它也将被创建。
语法:
WORKDIR /path/to/workdir
WORKDIR /a
WORKDIR b
WORKDIR c
`注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对`
15.4.7 ENV 命令
用来为构建镜像设置环境变量。这个值将出现在构建阶段中所有后续指令的环境中。
语法:
ENV
ENV = ...
15.4.8 ADD 命令
用来从context上下文复制新文件、目录或远程文件url,并将它们添加到位于指定路径的映像文件系统中。
语法:
ADD hom* /mydir/ 通配符添加多个文件
ADD hom?.txt /mydir/ 通配符添加
ADD test.txt relativeDir/ 可以指定相对路径
ADD test.txt /absoluteDir/ 也可以指定绝对路径
ADD url
15.4.9 COPY 命令
用来将context目录中指定文件复制到镜像的指定目录中
语法:
COPY src dest
COPY ["",... ""]
15.4.10 VOLUME 命令
用来定义容器运行时可以挂在到宿主机的目录
语法:
VOLUME ["/data"]
15.4.11 ENTRYPOINT命令
用来指定容器启动时执行命令和CMD类似
语法:
["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
ENTRYPOINT指令,往往用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的。
CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。
1.Docker从基础镜像运行一个容器
2.执行一条命令并对容器进行修改
3.执行类似docker commit的操作提交一个新的镜像层
4.docker再基于刚提交的镜像运行一个新容器
5.执行dockerfile中的下一条指令直到所有指令都执行完毕
1.从应用软件的角度来看,Dockerfile、docker镜像、docker容器分别代表软件的三个不同阶段
Dockerfile 是软件的原材料
docker镜像 是软件的交付品
docker容器 可以认为是软件的运行状态
2.Dockerfile面向开发,docker镜像成为交付标准,docker容器则涉及部署与运维,三者缺一不可,合力充当docker体系的基石。
1.Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、进程服务和内核进程(当应用就进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
2.docker镜像,在用Dockerfile定义一个文件之后,docker build 时会产生一个docker镜像,当运行docker镜像时,会真正开始提供服务
3.docker容器,容器是直接提供服务的
Base镜像(scratch):Docker Hub中99%的镜像都是由base镜像中安装和配置需要的软件构建出来的。
1. 先了解Docker Hub上的Centos是什么情况。
DockerHub上的centos镜像默认落脚点是/,默认不支持vim。那么现在我们想自定义一个centos,改变其默认落脚点,让其支持vim。
2. 编写Dockerfile
FROM centos
MAINTAINER ZCN<15236674712@163.com>
ENV MYPATH /tmp
WORKDIR $MYPATH
RUN yum -y install vim
EXPOSE 80
CMD echo $MYPATH
CMD echo "build-------success"
CMD /bin/bash
3. 构建镜像
$ docker build -f /myDocker/dockerfile -t zcn/mycentos .
4. 运行容器
$ docker run -it -P zcn/mycentos
1. 先创建/mydocekrfile/tomcat这个目录
将tomcat和jdk8的tar包放进此目录下。然后创建一个dockerfile文件。
2. 编写Dockerfile
FROM centos
MAINTAINER ZCN<15236674712@163.com>
#把宿主机当前上下文的c.txt拷贝进容器的/usr/local/路径下
COPY ./c.txt /usr/local/cincontainer.txt
#把tomcat和jdk的tar包拷贝到容器中
ADD ./apache-tomcat-9.0.22.tar.gz /usr/local/
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#安装vim编辑器
Run yum -y install vim
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh"]
# CMD ["/usr/local/apache-tomcat-9.0.22/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
test
FROM centos
MAINTAINER ZCN<15236674712@163.com>
#把宿主机当前上下文的c.txt拷贝进容器的/usr/local/路径下
COPY ./hello.txt /usr/local/container.txt
#把tomcat和jdk的tar包拷贝到容器中
ADD ./apache-tomcat-8.5.46.tar.gz /usr/local/
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#安装vim编辑器
#Run yum -y install vim
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.46
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.46
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-8.5.46/bin/startup.sh"]
# CMD ["/usr/local/apache-tomcat-8.5.46/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-8.5.46/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.46/bin/logs/catalina.out
java项目创建镜像 jar包
FROM centos
MAINTAINER ZCN<15236674712@163.com>
#把宿主机当前上下文的c.txt拷贝进容器的/usr/local/路径下
#把jdk的tar包拷贝到容器中
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
COPY ./yingx_zhangcn184s-0.0.1-SNAPSHOT.jar yingx_zhangcn184s-0.0.1-SNAPSHOT.jar
EXPOSE 9292
ENTRYPOINT ["java","-jar","./yingx_zhangcn184s-0.0.1-SNAPSHOT.jar"]
3. 构建镜像
$ docker build -t zcn/mytomcat .
这里没写-f是因为如果在当前目录下并且file文件名为正统的dockerfile 那么-f可以省略不写。
4. 运行容器
$ docker run -d -p 8888:8080 --name mytomcat -v /zcn/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /zcn/tomcat/logs:/usr/local/apache-tomcat-9.0.22/logs --privileged=true zcn/tomcat
解释:创建数据卷,让容器中的webapps目录中的项目目录和主机中test目录做一个映射
1. 导入maven依赖
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
resource>
<resource>
<directory>src/main/webapp/directory>
<targetPath>META-INF/resourcestargetPath>
resource>
resources>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>1.4.2.RELEASEversion>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
<configuration>
<encoding>UTF-8encoding>
<useDefaultDelimiters>trueuseDefaultDelimiters>
configuration>
plugin>
plugins>
build>
注意事项:
1)springboot 打包插件的版本必须为1.4.2.RELEASE,只有这个版本支持jsp,高版本不行
2)webapp下所有的前端资源必须打包到jar包的META-INF/resources的目录下,否则无法识别
2. 将项目打成jar包
注意事项:
打好jar包之后使用本地测试
java -jar jar包名.jar
3. 将jar包放入宿主机
4. 配置dockerfile
当前目录下准备: jdk-8u171-linux-x64.tar.gz yingx_zhangcn184s-0.0.1-SNAPSHOT.jar
FROM centos
MAINTAINER ZCN<15236674712@163.com>
#把jdk的tar包拷贝到容器中
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
COPY ./yingx_zhangcn184s-0.0.1-SNAPSHOT.jar yingx_zhangcn184s-0.0.1-SNAPSHOT.jar
EXPOSE 9292
ENTRYPOINT ["java","-jar","./yingx_zhangcn184s-0.0.1-SNAPSHOT.jar"]
5. 构建镜像
docker build -t yingx .
这里没写-f是因为如果在当前目录下并且file文件名为正统的dockerfile 那么-f可以省略不写。
6. 运行镜像
注意:映射端口是项目的端口号
docker run -it --name yingx -p 9292:9090 yingx
7. 访问项目
http://192.168.253.134:9292/yingx/main/main.jsp
#1.启动mysql 192.168.244.131:3333 root:root 添加数据库添加数据
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3333:3306 -d mysql:5.6
#2.启动Redis 192.168.244.131:7001
docker run -d -p 7001:7000 --name redis -v /root/redis.conf:/etc/redis/redis.conf redis:5.0.10 redis-server /etc/redis/redis.conf
#3.启动es 配置ik分词器 192.168.244.131:9200
docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -v esPlugins:/usr/share/elasticsearch/plugins -v esData:/usr/share/elasticsearch/data -v esConfig:/usr/share/elasticsearch/config elasticsearch:6.8.0
#4.启动kibana
docker run -d --name kibana -e ELASTICSEARCH_URL=http://192.168.244.131:9200 -p 5601:5601 kibana:6.8.0
#5.修改项目的配置文件
#6.本地启动测试项目
#7.将项目打成jar 本地测试jar包
java -jar yingxue-service-0.0.1-SNAPSHOT.jar
#8.将jar包传入宿主机
#9.创建DockerFile构建项目镜像
`DockerFile
FROM centos
MAINTAINER ZCN<15236674712@163.com>
#把宿主机当前上下文的c.txt拷贝进容器的/usr/local/路径下
#把jdk的tar包拷贝到容器中
ADD ./jdk-8u171-linux-x64.tar.gz /usr/local/
#设置登录落脚点/usr/local
ENV MYPATH /usr/local/
WORKDIR $MYPATH
#配置java和tomcat的环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin
COPY ./yingxue-service-0.0.1-SNAPSHOT.jar yingxue-service-0.0.1-SNAPSHOT.jar
EXPOSE 9696
ENTRYPOINT ["java","-jar","./yingxue-service-0.0.1-SNAPSHOT.jar"]
`
docker build -t yingxue:1.0 .
#10.运行镜像
docker run -it --name yingxue -p 9696:9696 yingxue:1.0
#11.访问项目
http://192.168.244.131:9696/yingx/video/queryAllPage?page=1&pageSize=10
选择 File | Settings | Build, Execution, Deployment | Deployment 点击 + 添加Docker
设置快捷键
搜索 Browse Remote Host 属性 修改快捷键
#登录阿里云 需要输入阿里云登录密码
$ sudo docker login --username=15236674712@qq.com registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/nanan/mytomcat:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/nanan/mytomcat:[镜像版本号]
#eg:
$ sudo docker login --username=15236674712@qq.com registry.cn-beijing.aliyuncs.com
$ sudo docker tag zcn/mytomcat registry.cn-beijing.aliyuncs.com/nanan/mytomcat:1.0
$ sudo docker push registry.cn-beijing.aliyuncs.com/nanan/mytomcat:1.0
$ docker pull 阿里云地址的镜像名:版本号
从官网复制就行
公网地址:registry.cn-beijing.aliyuncs.com/nanan/mytomcat
#eg:
$ docker pull registry.cn-beijing.aliyuncs.com/nanan/mytomcat:1.0
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: 输入用户名
Password: 输入密码
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
在上传镜像前需更改本地镜像的tag,以账户名/名称形式
$ docker tag 本地镜像名称:版本 docker账户/仓库名称
或
$ docker tag 本地镜像名称:版本 docker账户/仓库名称:版本号
#g:
$ docker tag tomcat zhangcn/toms:1.2
$ docker push docker账户/仓库名称:版本号
#eg:
$ docker push zhangcn/toms:1.2
Portainer 是一个开源、轻量级Docker管理用户界面,基于Docker API,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
官方安装说明手册:https://www.portainer.io/installation/。
建议建议直接使用 docker 安装,方便快捷。
# 搜索镜像
$ docker search portainer/portainer
# 拉取镜像
$ docker pull portainer/portainer
$ docker run -d -p 9001:9000 -v /root/portainer:/data -v /var/run/docker.sock:/var/run/docker.sock --name dev-portainer portainer/portainer
#参数说明:
-d #容器在后台运行
-p 9001:9000 # 宿主机9000端口映射容器中的9000端口
-v /var/run/docker.sock:/var/run/docker.sock # 把宿主机的Docker守护进程(docker daemon)默认监听的Unix域套接字挂载到容器中
-v /root/portainer:/data # 把宿主机目录 /root/portainer 挂载到容器 /data 目录;
–-name dev-portainer # 指定运行容器的名称
注意: 在启动容器时必须挂载本地 /var/run/docker.socker与容器内的/var/run/docker.socker连接。
连接地址:http://192.168.253.128:9001
登录
Compose
项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 OpenStack
中的 Heat
十分类似。
其代码目前在 https://github.com/docker/compose 上开源。
Compose
定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。
通过第一部分中的介绍,我们知道使用一个 Dockerfile
模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
Compose
恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
Compose
中有两个重要的概念:
service
):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。project
):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml
文件中定义。Compose
的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
Compose
项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose
来进行编排管理。
1.linux
# 1.在线安装
$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
# 2.本地安装
# 2-1.修改文件名
$ mv docker-compose-Linux-x86_64 docker-compose
# 2-2.将dockedr-compose 移动到/usr/local/bin/目录下
$ mv docker-compose /usr/local/bin/
# 2-3.将docker-compose赋予执行权限
$ chmod +x /usr/local/bin/docker-compose
# 3.测试docker版本
$ docker-compose -v
2.macos、window
Docker Desktop for Mac/Windows 自带 docker-compose 二进制文件,安装 Docker 之后可以直接使用
。3.bash命令补全
$ curl -L https://raw.githubusercontent.com/docker/compose/1.25.5/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
4.卸载
$ sudo rm /usr/local/bin/docker-compose
5.测试安装成功
$ docker-compose --version
docker-compose version 1.25.5, build 4667896b
# 1.相关概念
首先介绍几个术语。
service
):一个应用容器,实际上可以运行多个相同镜像的实例。project
):由一组关联的应用容器组成的一个完整业务单元。∂一个项目可以由多个服务(容器)关联而成,Compose
面向项目进行管理。# 2.场景
最常见的项目是 web 网站,该项目应该包含 web 应用和缓存。
# 3.docker-compose模板
- 参考文档:https://docker_practice.gitee.io/zh-cn/compose/compose_file.html
version: "3.0"
services:
mysqldb:
image: mysql:5.7.19
container_name: mysql
ports:
- "3306:3306"
volumes:
- /root/mysql/conf:/etc/mysql/conf.d
- /root/mysql/logs:/logs
- /root/mysql/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
networks:
- ems
depends_on:
- redis
redis:
image: redis:4.0.14
container_name: redis
ports:
- "6379:6379"
networks:
- ems
volumes:
- /root/redis/data:/data
command: redis-server
networks:
ems:
# 4.通过docker-compose运行一组容器
- 参考文档:https://docker_practice.gitee.io/zh-cn/compose/commands.html
[root@centos ~]# docker-compose up //前台启动一组服务
[root@centos ~]# docker-compose up -d //后台启动一组服务
模板文件是使用 Compose
的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 docker run
相关参数的含义都是类似的。
默认的模板文件名称为 docker-compose.yml
,格式为 YAML 格式。
version: "3"
services:
webapp:
image: examples/web
ports:
- "80:80"
volumes:
- "/data"
注意每个服务都必须通过 image
指令指定镜像或 build
指令(需要 Dockerfile)等来自动构建生成镜像。
如果使用 build
指令,在 Dockerfile
中设置的选项(例如:CMD
, EXPOSE
, VOLUME
, ENV
等) 将会自动被获取,无需在 docker-compose.yml
中重复设置。
下面分别介绍各个指令的用法。
1.image
指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose
将会尝试拉取这个镜像。
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
2.container_name
指定容器名称。默认将会使用 项目名称_服务名称_序号
这样的格式。
container_name: docker-web-container
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
3.ports
暴露端口信息。
使用宿主端口:容器端口 (HOST:CONTAINER)
格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
注意:当使用 HOST:CONTAINER
格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML
会自动解析 xx:yy
这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
4.volumes
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER
)或者数据卷名称(VOLUME:CONTAINER
),并且可以设置访问模式 (HOST:CONTAINER:ro
)。
该指令中路径支持相对路径。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
如果路径为数据卷名称,必须在文件中配置数据卷。
version: "3"
services:
my_src:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
external: #使用自定义卷名
true #确定使用卷名
5.networks
配置容器连接的网络。
version: "3"
services:
some-service:
networks:
- some-network
- other-network
networks:
some-network:
other-network:
6.environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
如果变量名称或者值中用到 true|false,yes|no
等表达 布尔 含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇,包括
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
7.env_file
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE
方式来指定 Compose 模板文件,则 env_file
中变量的路径会基于模板文件路径。
如果有变量名称与 environment
指令冲突,则按照惯例,以后者为准。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持 #
开头的注释行。
# common.env: Set development environment
PROG_ENV=development
8.depends_on
解决容器的依赖、启动先后的问题。以下例子中会先启动 redis
db
再启动 web
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意:
web
服务不会等待redis
db
「完全启动」之后才启动。
9.command
覆盖容器启动后默认执行的命令。
command: echo "hello world"
10.build
指定 Dockerfile
所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose
将会利用它自动构建这个镜像,然后使用这个镜像。
version: '3'
services:
webapp:
build: ./dir
你也可以使用 context
指令指定 Dockerfile
所在文件夹的路径。
使用 dockerfile
指令指定 Dockerfile
文件名。
使用 arg
指令指定构建镜像时的变量。
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
11.sysctls
配置容器内核参数。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0 # 开启SYN洪水攻击保护
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
12.ulimits
指定容器的 ulimits 限制值。
例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
13.healthcheck
通过命令检查容器是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
对于 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
打印版本并退出。1.up
格式为 docker-compose up [options] [SERVICE...]
。
该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
链接的服务都将会被自动启动,除非已经处于运行状态。
可以说,大部分时候都可以直接通过该命令来启动一个项目。
默认情况,docker-compose up
启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。
当通过 Ctrl-C
停止命令时,所有容器将会停止。
如果使用 docker-compose up -d
,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。
默认情况,如果服务容器已经存在,docker-compose up
将会尝试停止容器,然后重新创建(保持使用 volumes-from
挂载的卷),以保证新启动的服务匹配 docker-compose.yml
文件的最新内容
2.down
up
命令所启动的容器,并移除网络3.exec
4.ps
格式为 docker-compose ps [options] [SERVICE...]
。
列出项目中目前的所有容器。
选项:
-q
只打印容器的 ID 信息。5.restart
格式为 docker-compose restart [options] [SERVICE...]
。
重启项目中的服务。
选项:
-t, --timeout TIMEOUT
指定重启前停止容器的超时(默认为 10 秒)。6.rm
格式为 docker-compose rm [options] [SERVICE...]
。
删除所有(停止状态的)服务容器。推荐先执行 docker-compose stop
命令来停止容器。
选项:
-f, --force
强制直接删除,包括非停止状态的容器。一般尽量不要使用该选项。-v
删除容器所挂载的数据卷。7.start
格式为 docker-compose start [SERVICE...]
。
启动已经存在的服务容器。
8.stop
格式为 docker-compose stop [options] [SERVICE...]
。
停止已经处于运行状态的容器,但不删除它。通过 docker-compose start
可以再次启动这些容器。
选项:
-t, --timeout TIMEOUT
停止容器时候的超时(默认为 10 秒)。9.top
查看各个服务容器内运行的进程。
10.pause
格式为 docker-compose pause [SERVICE...]
。
暂停正在运行状态中的服务。
11.unpause
格式为 docker-compose unpause [SERVICE...]
。
恢复处于暂停状态中的服务。