Docker是基于Go语言实现的云开源项目;通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
Docker 是一个开源的应用容器引擎,基于go语言并遵从apache2协议开源。
Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。
Docker的三要素:镜像、容器、仓库
镜像:Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
容器:
Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
仓库:
仓库(Repository)是集中存放镜像文件的场所也是下载镜像的地方。
仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是 Docker Hub(https://hub.docker.com/),
Docker
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云 等
如果之前安装过旧版本的Docker,可以使用下面命令卸载:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
1)首先需要大家虚拟机联网,安装yum工具
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken
2)然后更新本地镜像源:
# 设置docker镜像源
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast
3)然后输入命令:
yum install -y docker-ce
# 关闭
systemctl stop firewalld
# 禁止开机启动防火墙
systemctl disable firewalld
通过命令启动docker:
systemctl start docker # 启动docker服务
systemctl stop docker # 停止docker服务
systemctl restart docker # 重启docker服务
然后输入命令,可以查看docker版本:
docker -v
docker官方镜像仓库网速较差,我们需要设置国内镜像服务:
参考阿里云的镜像加速文档:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
镜像的拉取:
docker pull 镜像:版本(只输入镜像默认为最新版本)
镜像的保存,删除,读取
利用docker save将nginx镜像导出磁盘,然后再通过load加载回来
docker save -o [保存的目标文件名称] [镜像名称]
docker load -i [镜像名称]
2)保存镜像到磁盘
docker save -o /usr/local/nginx.tar nginx
3)删除镜像
docker rmi nginx
4)查看安装的镜像
docker images
5)加载保存到磁盘的镜像
docker load -i /usr/local/nginx.tar
docker run:创建并运行一个容器,处于运行状态
docker pause:让一个运行的容器暂停
docker unpause:让一个容器从暂停状态恢复运行
docker stop:停止一个运行的容器
docker start:让一个停止的容器再次运行
docker rm:删除一个容器
创建并运行nginx容器的命令:
docker run --name mynginx -p 80:80 -d nginx
docker run :创建并运行一个容器
--name : 给容器起一个名字,比如叫做mynginx
-p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
-d:后台运行容器
nginx:镜像名称,例如nginx
2)查看启动的容器
docker ps # 查看所有运行的容器
docker ps -a # 查看所有容器包含关闭的
进入容器。进入创建的容器的命令为:
docker exec -it 容器名称 bash
-it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
查看容器日志的命令:
docker logs
添加 -f 参数可以持续查看日志
复制命令
docker cp 容器:路径 宿主机路径 容器文件复制到宿主机
docker cp 宿主机路径 容器:路径 宿主机文件复制到容器
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
将主机的目录和容器的目录联系起来,操作主机相当于操作容器
数据卷操作的基本语法如下:
docker volume [COMMAND]
create 创建一个volume
inspect 显示一个或多个volume的信息
ls 列出所有的volume
prune 删除未使用的volume
rm 删除一个或多个指定的volume
1)创建数据卷
docker volume create html
2)查看所有数据
docker volume ls
3)查看数据卷详细信息卷
docker volume inspect html
小结:
数据卷的作用:
将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
数据卷操作:
docker volume create:创建数据卷
docker volume ls:查看所有数据卷
docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
docker volume rm:删除指定数据卷
docker volume prune:删除所有未使用的数据卷
在创建容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
docker run \
--name mynginx \
-v html:/root/html \
-p 80:80 \
-d \
nginx \
-v html:/root/html
:把html数据卷挂载到容器内的/root/html这个目录中,如果我们修改html数据卷对应目录的内容,那么/root/html里的内容也会修改。
docker run的命令中通过 -v 参数挂载文件或目录到容器中:
可以同时使用多个-v进行挂载设置
-v volume名称:容器内目录
-v 宿主机文件:容器内文件
-v 宿主机目录:容器内目录
数据卷挂载与目录直接挂载的
数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义的镜像。
【1】编写镜像
#基础镜像
FROM centos
#维护者
MAINTAINER lsh
#启动容器运行命令
CMD echo "hello Dockerfile"
【2】构建镜像
docker build -t 镜像名:版本 .
注意: .代表当前目录去找Dockerfile
指定基础镜像,必须为第一个命令。
指令格式:
FROMFROM :
维护者信息
指令格式
MAINTAINER
工作目录,类似于cd命令
指令格式
WORKDIR /usr/workdir
示例
WORKDIR /a (这时工作目录为/a) WORKDIR b (这时工作目录为/a/b) WORKDIR c (这时工作目录为/a/b/c)
注意
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
构建镜像时执行的命令
指令语法
# 1. shell执行 格式 RUN# 2. exec执行 格式 RUN ["executable", "param1", "param2"]
示例
WORKDIR /OPT RUN mkdir docker WORKDIR /usr/local RUN echo "test" > a.info
注意:
RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。 如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget。
宿主机不支持绝对路径 ,只能用相对路径 ,容器支持绝对路径
指令格式
ADD... ADD [" ",... " "] 用于支持包含空格的路径示例:
示例
添加所有以"hom"开头的文件
ADD hom* /mydir/
? 替代一个单字符,例如:"home.txt"
ADD hom?.txt /mydir/
添加 "test" 到 WORKDIR/relativeDir/
ADD test relativeDir
添加 "test" 到 /absoluteDir/
ADD test /absoluteDir/
功能类似ADD,但是是不会自动解压文件,也不能访问网络资源。
语法格式
COPY <源路径> <目标路径>
构建容器后调用,也就是在容器启动时才进行调用。指定这个容器启动的时候要运行的命令只有最后一个会生效可被替换。
指令格式
1. shell格式:CMD <命令> 2. exec格式: CMD ["可执行文件", "参数1", "参数2", …]
示例
CMD echo "This is a test." - CMD ["/usr/bin/wc","--help"]
注意
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
配置容器,使其可执行化。配合CMD可省去"application",只使用参数。 指定容器启动的要运行的命令,可以追加命令
指令格式:
1.ENTRYPOINT ["executable", "param1", "param2"] 2.ENTRYPOINT command param1 param2 (shell内部令)
示例
ENTRYPOINT ["top", "-b"]
注意:
ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile 中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令。
这个指令非常简单,就是用于设置环境变量而已,无论是接下来的指令,还是在容器中运行的程序,都可以使用这里定义的环境变量。
指令格式
ENV=
示例
ENV JAVA_HOME=/usr/local/jdk1.7.0_79 ENV PATH=$JAVA_HOME/bin:$PATH
指定于外界交互的端口
指令格式
EXPOSE 80
用于指定持久化目录
指令格式
VOLUME ["/path/to/dir"]
示例
VOLUME ["/data"] VOLUME ["/var/www", "/var/log/apache2"]
注意
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
卷可以容器间共享和重用
容器并不一定要和其它容器共享卷
修改卷后会立即生效
对卷的修改不会对镜像产生影响
卷会一直存在,直到没有任何容器在使用它
USER 指令用于将会用以什么样的用户去运行
指令格式
USER user USER user:group
注意
使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、 ENTRYPOINT都将使用该用户。镜像构建完成后,通过 docker run 运行容器时,可以通过-u参数来覆盖所指定的用户。
帮助别人定制而准备的
指令格式
ONBUILD [INSTRUCTION]
evth-pair 就是一对的虚拟设备接口,它们都是成对出现,一段彼此连接。 正是因为这个特性,evth-parit桥梁。连接各种各样网络设备。
docker 使用linux的桥接, 宿主机中时一个docker容器的网桥。 docker0 docker中所有网络接口都是虚拟的。 虚拟转发效率高。只要容器删除对应的网桥就没有了。
创建t2容器的时候连接t1容器
--link :alias
name和id是源容器的name和id,alias是源容器在link下的别名。
docker run --name t2 -d -p 8082:8080 --link t1 mytomcat:v1
docker network --help
docker network connect 将容器连接到网络
docker network create 创建一个网络
docker network disconnect 断开容器的网络
docker network inspect 显示一个或多个网络的详细信息
docker network ls 列出网络
docker network prune 删除所有未使用的网络
docker network rm 删除一个或多个网络
语法结构:
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
注意:
bridge -网络模式桥连接
--subnet=192.168.200.0/24命令指定该网络模式网段范围,其中24代表该网段前24位相同,后8位不同,即该网段范围为:192.168.200.1~192.168.200.254,若该命令改为--subnet=192.168.200.0/16,即该网段范围为: 192.168.0.1-192.168.255.254,这个范围就变的很大了。
--gateway - 路由
mynet- 自定义网络名字
docker network connect 网络名 容器名
docker network inspect 网络名
可以用 --net 选项指定容器的网络模式
可以用--network加入指定网络。
Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。
1)下载
curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2)修改权限
# 修改权限
chmod +x /usr/local/bin/docker-compose
3)补全命令
# 补全命令
curl -L https://raw.githubusercontent.com/docker/compose/1.29.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
docker-compose.yml文件分为三个主要部分:services、networks、volumes
services主要用来定义各个容器。
networks定义需要使用到的network.
volumes定义services使用到的volume.
服务(service)定义包含应用于为该服务启动的每个容器的配置,就像传递命令行参数给docker container create一样。同样,网络和卷的定义类似于给 docker network create 和 docker volume create传递参数。
正如 docker container create 在 Dockerfile 指定选项,如 CMD、 EXPOSE、VOLUME、ENV,在默认情况下,不需要在docker-compose.yml中再次指定它们。
使用当前目录下的Dockerfile进行构建。
version: '3' services: web: build: ./
假设当前文件夹名为composetest,构建出来的镜像名 composetest_web,运行出来的容器名:composetest_web_1
build也可以指定文件路径,Dockerfile的名字.
version: '3' services: web: build: context: ./ dockerfile: mydockerfile
指定运行容器使用的镜像。以下格式都可以。
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
如果本地不存在指定的镜像,则会从repository pull下来。 如果定义了build,那么image指定的就是build后的镜像的名字和tag。
version: '3' services: web: build: ./ image: web:1.0
默认运行出来的容器名:composetest_web_1, 是当前目录名+定义service名+数量 想要修改的话,指定container_name字段。
version: '3' services: web: build: ./ image: web:1.0 container_name: myweb
覆盖容器启动后默认执行的命令(Dockerfile定义的CMD)。当Dockerfile定义了entrypoint的时候,docker-comose.yml定义的command会被覆盖。
version: '3' services: web: build: ./ command: env
可以覆盖Dockerfile中定义的entrypoint命令。
version: '3' services: web: build: ./ entrypoint: java -jar /tmp/app.jar
将容器的端口80映射到宿主机的端口8080
ports: - "8080:80" - "127.0.0.1:8080:80"
挂载一个目录或者一个已存在的数据卷容器, HOST:CONTAINER 格式定义共享的目录 HOST:CONTAINER:RO 定义容器只读的目录。
volumes: - ./conf.d:/etc/nginx/conf.d # nginx.conf对容器来说只读 - ./nginx.conf:/etc/nginx/nginx.conf:ro
加入指定网络
services: some-service: networks: - some-network - other-network
关于这个标签还有一个特别的子标签aliases,这是一个用来设置服务别名的标签
services: some-service: networks: some-network: aliases: - alias1 - alias3 other-network: aliases: - alias2