特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 通常为 MB | 通常为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 通常几十个 |
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和建立 Docker 容器。html
Docker 容器经过 Docker 镜像来建立。mysql
容器与镜像的关系相似于面向对象编程中的对象与类。linux
Docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
名词 | 说明 |
---|---|
镜像(Images) | Docker 镜像是用于建立 Docker 容器的模板。 |
容器(Container) | 容器是独立运行的一个或一组应用。 |
客户端(Client) | Docker 客户端经过命令行或者其余工具使用 Docker API (docs.docker.com/reference/a…) 与 Docker 的守护进程通讯。 |
主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
仓库(Registry) | Docker 仓库用来保存镜像,能够理解为代码控制中的代码仓库。Docker Hub(hub.docker.com) 提供了庞大的镜像集合供使用。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,经过一个简单的命令行便可在相应的平台上安装Docker,好比VirtualBox、 Digital Ocean、Microsoft Azure。 |
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh
复制代码
sudo systemctl enable docker
sudo systemctl start docker
复制代码
/etc/docker/daemon.json
中写入以下内容(若是文件不存在请新建该文件){
"registry-mirrors": [
"https://registry.docker-cn.com"
]
}
复制代码
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
复制代码
Registry Mirrors:
https://registry.docker-cn.com/
复制代码
yum list installed | grep docker
复制代码
yum -y remove 上面列出来的包
复制代码
以前提到过,Docker Hub 上有大量的高质量的镜像能够用,这里咱们就说一下怎么获取这些镜像。nginx
从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:git
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]github
具体的选项能够经过 docker pull --help 命令看到,这里咱们说一下镜像名称的格式。web
docker pull ubuntu:16.04
16.04: Pulling from library/ubuntu
bf5d46315322: Pull complete
9f13e0ac480c: Pull complete
e8988b5b3097: Pull complete
40af181810e7: Pull complete
e6f7c7e5c03e: Pull complete
Digest: sha256:147913621d9cdea08853f6ba9116c2e27a3ceffecf3b492983ae97c3d643fbbe
Status: Downloaded newer image for ubuntu:16.04
复制代码
上面的命令中没有给出 Docker 镜像仓库地址,所以将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:16.04,所以将会获取官方镜像 library/ubuntu 仓库中标签为 16.04 的镜像。sql
从下载过程当中能够看到咱们以前说起的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并不是单一文件。下载过程当中给出了每一层的 ID 的前 12 位。而且下载结束后,给出该镜像完整的 sha256 的摘要,以确保下载一致性。docker
在使用上面命令的时候,你可能会发现,你所看到的层 ID 以及 sha256 的摘要和这里的不同。这是由于官方镜像是一直在维护的,有任何新的 bug,或者版本更新,都会进行修复再以原来的标签发布,这样能够确保任何使用这个标签的用户能够得到更安全、更稳定的镜像。shell
要想列出已经下载下来的镜像,有两个命令。
docker images
复制代码
或者
docker image ls
复制代码
结果以下
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 2a697363a870 38 hours ago 119MB
tomcat latest 27600aa3d7f1 8 days ago 463MB
ubuntu <none> a3551444fc85 2 weeks ago 119MB
复制代码
列表包含了 仓库名、标签、镜像 ID、建立时间 以及 所占用的空间。
若是仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不一样。好比,ubuntu:16.04 镜像大小,在这里是 127 MB,可是在 Docker Hub 显示的倒是 50 MB。这是由于 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程当中镜像是保持着压缩状态的,所以 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 docker image ls 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,由于镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。
另一个须要注意的问题是,docker image ls 列表中的镜像体积总和并不是是全部镜像实际硬盘消耗。因为 Docker 镜像是多层存储结构,而且能够继承、复用,所以不一样镜像可能会由于使用相同的基础镜像,从而拥有共同的层。因为 Docker 使用 Union FS,相同的层只须要保存一份便可,所以实际镜像硬盘占用空间极可能要比这个列表镜像大小的总和要小的多。
你能够经过如下命令来便捷的查看镜像、容器、数据卷所占用的空间。
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 3 1 700.2MB 237.5MB (33%)
Containers 2 0 65.95kB 65.95kB (100%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
复制代码
上面的镜像列表中,还能够看到一个特殊的镜像,这个镜像标签为 none
ubuntu <none> a3551444fc85 2 weeks ago 119MB
复制代码
这个镜像本来是有镜像名和标签的, 镜像发布新版本后,从新docker pull
的时候, 这个镜像名被转移到了新下载的镜像身上, 而旧的镜像上的这个名称则被取消,从而成为了 。除了 docker pull 可能致使这种状况,docker build 也一样能够致使这种现象。因为新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 的镜像。这类无标签镜像也被称为 虚悬镜像(dangling image) ,能够用下面的命令专门显示这类镜像:
docker images -f dangling=true
复制代码
为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。因此在使用一段时间后,可能会看到一些依赖的中间层镜像。默认的 docker image ls 列表中只会显示顶层镜像,若是但愿显示包括中间层镜像在内的全部镜像的话,须要加 -a 参数。
docker images -a
复制代码
不加任何参数的状况下,docker images 会列出全部顶级镜像,可是有时候咱们只但愿列出部分镜像。docker image ls 有好几个参数能够帮助作到这个事情。
docker images ubuntu
ubuntu 16.04 2a697363a870 38 hours ago 119MB
ubuntu <none> a3551444fc85 2 weeks ago 119MB
复制代码
docker images ubuntu:16.04
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 16.04 2a697363a870 38 hours ago 119MB
复制代码
若是要删除本地的一个镜像,可使用 docker image rm 命令,其格式为:
docker image rm [选项] <镜像1> [<镜像2> ...]
复制代码
或者
docker rmi [选项] <镜像1> [<镜像2> ...]
复制代码
docker image prune
复制代码
其中,<镜像> 能够是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要。<>
表明必须参数,[]
表明可选参数
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,所以每一条指令的内容,就是描述该层应当如何构建。
这里以定制 tomcat 镜像为例,咱们使用 Dockerfile 来定制本身的tomcat
docker run -p 8080:8080 tomcat
复制代码
docker exec -it f208e826caf2 bash
复制代码
cd webapps/ROOT
echo "hello docker tomcat" >> index.jsp
复制代码
以上咱们对原来的tomcat容器作了修改,但没有更改镜像,致使每次启动一个容器,都要进入容器进行修改。若是直接修改镜像,那么只会跑起来的容器都不在须要一一修改。
如今建立一个Dockerfile 文件来构建咱们本身的镜像
cd /usr/local
mkdir -p docker/mytomcat
cd docker/mytomcat
复制代码
vi Dockerfile
复制代码
FROM tomcat
WORKDIR /usr/local/tomcat/webapps/ROOT/
RUN rm -rf *
RUN echo "hello docker tomcat" > /usr/local/tomcat/webapps/ROOT/index.html
复制代码
FROM tomcat: 选定基础镜像为tomcat WORKDIR /usr/local/tomcat/webapps/ROOT/:指定工做目录,进入到这个目录 RUN rm -rf * : 删除当前目录全部文件 RUN echo "hello docker tomcat" > /usr/local/tomcat/webapps/ROOT/index.html: 写入一个index.html文件到当前目录
docker build -t mytomcat .
复制代码
mytomcat
为你要构建的镜像的标签名 .
表示当前目录。
好了,如今已经构建好咱们本身的tomcat镜像了。运行起来
docker run -p 8080:8080 mytomcat
复制代码
功能为运行指定的命令
RUN命令有两种格式
在linux操做系统上默认 /bin/sh -c
在windows操做系统上默认 cmd /S /C
第二种是相似于函数调用。
可将executable理解成为可执行文件,后面就是两个参数。
两种写法比对:
RUN /bin/bash -c 'source HOME RUN ["/bin/bash", "-c", "echo hello"] 注意:多行命令不要写多个RUN,缘由是Dockerfile中每个指令都会创建一层.
多少个RUN就构建了多少层镜像,会形成镜像的臃肿、多层,不只仅增长了构件部署的时间,还容易出错。
RUN书写时的换行符是\
看这个名字就知道,又是一个复制命令
语法以下:
COPY的只能是本地文件,其余用法一致
一个复制命令,把文件复制到景象中。
若是把虚拟机与容器想象成两台linux服务器的话,那么这个命令就相似于scp,只是scp须要加用户名和密码的权限验证,而ADD不用。
语法以下:
路径的填写能够是容器内的绝对路径,也能够是相对于工做目录的相对路径
能够是一个本地文件或者是一个本地压缩文件,还能够是一个url
若是把写成一个url,那么ADD就相似于wget命令
若是把的文件是个tar.gz包, 发送以后就会自动解压缩。
docker run -p 8081:8080 tomcat
复制代码
run:启动一个容器,启动一个容器即启动了一个进程
-p: 指定端口, 第一个参数为宿主机的端口,第二个参数为docker容器的端口。意思是把宿主机8081端口映射到容器中的8080端口上, 咱们直接访问宿主机的8081端口就能直接访问到8080
tomcat:镜像名
也就是后台运行,不占用主线程,不会被日志卡住在主线程。
docker run -d -p 8080:8080 tomcat
复制代码
这种方式启动后, 只会返回一个完整的容器Id, 要查看启动时输出的日志使用如下命令查看:
docker container logs 容器Id
复制代码
docker exec -it 容器Id bash
复制代码
进入容器后, 有些linux 命令会不能使用,好比ll
、vi
,由于tomcat这个镜像是基于最简单的linux构建的。
docker container ls -a
复制代码
或者
docker ps -a
复制代码
docker container stop
复制代码
docker container rm 容器Id
复制代码
或者
docker container prune
复制代码
docker container prune
复制代码
一个容器销毁后, 容器里面的数据也就丢失了。 如何把容器中的数据和宿主机之间作读取,作到容器中的数据持久化呢, 这就是容器数据的持久化,须要使用到docker的数据卷
。
数据卷
是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,能够提供不少有用的特性:
下面运行一个tomcat容器, 把ROOT
目录指定为宿主机上的目录
ROOT
mkdir ROOT
cd /ROOT
vi index.html
复制代码
内容为 hello I am domain , this is index.html in volume
docker run -d -p 8081:8080 -v /root/ROOT:/usr/local/tomcat/webapps/ROOT tomcat
复制代码
-v: 第一个参数表示宿主机的目录,第二个参数表示容器中的目录,意思是把容器中的ROOT
目录替换为宿主机中ROOT
目录
浏览器中访问 8081 端口就能看到 刚刚宿主机中index.html中的内容了。
能够查看容器中数据卷的信息:
docker inspect 容器Id
复制代码
数据卷
信息在 "Mounts" Key 下面
不指定标签,默认从官网拉取最新的mysql镜像
docker pull mysql
复制代码
带数据卷启动容器
docker run -p 3306:3306 --name mysql \
-v /usr/local/docker/mysql/logs:/var/log/mysql \
-v /usr/local/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql
复制代码
下面是每行参数的意思
-v /usr/local/docker/mysql/logs:/var/log/mysql
: 挂载日志文件,左边宿主机目录, 右边容器目录。
-v /usr/local/docker/mysql/data:/var/lib/mysql
:挂载 数据文件。
-e MYSQL_ROOT_PASSWORD=123456
:经过环境变量设置root用户的密码
Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。
Compose 中有两个重要的概念:
服务
(service):一个应用的容器,实际上能够包括若干运行相同镜像的容器实例。
项目
(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
Compose 的默认管理对象是项目,经过子命令对项目中的一组容器进行便捷地生命周期管理。
这里使用二进制包的方式来安装和卸载
从github上面下载安装并给docker-compose
命令执行权限
curl -L https://github.com/docker/compose/releases/download/1.17.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
复制代码
删除二进制文件便可。
rm /usr/local/bin/docker-compose
复制代码
这里经过docker-compose
来启动一个项目,启动项目须要启动两个容器, 一个tomcat
,一个mysql
。 这就是前面说的服务
组成项目
。
docker-compose
是经过docker-compose.yml
文件来构建的 .
docker-compose.yml
文件cd /usr/local/docker
mkdir myshop
cd myshop
vi docker-compose.yml
version: '3'
services:
tomcat:
restart: always
image: 'tomcat'
container_name: tomcat
ports:
- 8080:8080
volumes:
- /usr/local/docker/myshop/ROOT:/usr/local/tomcat/webapps/ROOT
mysql:
restart: always
image: mysql
container_name: mysql
ports:
- 3306:3306
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123456
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
复制代码
这里配置了两个服务, 两个服务都使用了数据卷, tomcat
中的使用数据卷是常见的格式: 宿主机目录:容器目录
,mysql
中使用的是 统一管理数据卷的方式, 使用docker分配的宿主机目录,而不是本身指定。下面是配置中的意思:
- mysql-data:/var/lib/mysql
: 左边宿主机目录名,右边是容器目录,而后在下面volumes
节点下声明这个宿主机目录
volumes:
mysql-data:
复制代码
docker-compose.yml
文件所在目录,执行启动命令docker-compose up -d
复制代码
-d
表示以守护态运行,不占用操做系统主线程,不在主线程输出日志。
docker-compose.yml
文件所在目录,执行启动命令docker-compose down
复制代码
那么以守护态运行后,怎么查看日志?经过如下命令:
docker-compose logs
复制代码
version: '3.1'
services:
db:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
command:
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
ports:
- 3306:3306
volumes:
- ./data:/var/lib/mysql
adminer:
image: adminer
restart: always
ports:
- 8080:8080
复制代码
经过docker-compos 来部署一个 git 托管平台,很是的方便。
在/usr/local/docker/gitlab
目录下建立一个docker-compose.yml
配置文件,内容以下:
version: '3'
services:
web:
image: 'twang2218/gitlab-ce-zh'
restart: always
hostname: '192.168.65.130'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.65.130:8080'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
unicorn['port'] = 8888
nginx['listen_port'] = 8080
ports:
- '8080:8080'
- '8443:443'
- '2222:22'
volumes:
- /usr/local/docker/gitlab/config:/etc/gitlab
- /usr/local/docker/gitlab/data:/var/opt/gitlab
- /usr/local/docker/gitlab/logs:/var/log/gitlab
复制代码
下面是每一个节点属性的意思:
去到官网搜索镜像gitlab-ce-zh
,拉取镜像:
docker pull twang2218/gitlab-ce-zh
复制代码
在docker-compose.yml文件所在目录, 执行启动命令:
docker-compose up
复制代码
容器很大, 启动时间较长, 须要等待一段时间。启动成功后,提示修改密码,这里修改的是root的密码。 修改完后就可使用 root 帐号和刚刚修改的密码登陆啦。
Nexus
是一个强大的仓库管理器,部署后,能够把本身的sdk上传这里。 配置后便可拉取使用
/usr/local/docker/nexus3
目录下,建立docker-compose.yml
配置文件,内容以下:version: '3.1'
services:
nexus:
restart: always
image: sonatype/nexus3
container_name: nexus
ports:
- 8081:8081
volumes:
- /usr/local/docker/nexus3/data:/nexus-data
复制代码
docker-compose up
复制代码
启动报错, 没有IO权限,经过更改当前目录的data目录权限解决:
chmod 777 data
复制代码
把以前的容器关闭,再从新启动:
docker-compose down
docker-compose up
复制代码
settings.xml
中添加 Nexus 认证信息(servers 节点下):<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
复制代码
在 pom.xml 中添加以下代码:
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://192.168.65.130:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.65.130:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
复制代码
这里的id
需和上面节点中定义的id
一致,url
为nexus中browse拷贝对应版本的url
mvn deploy
复制代码
# 如第三方JAR包:aliyun-sdk-oss-2.2.3.jar
mvn deploy:deploy-file
-DgroupId=com.aliyun.oss
-DartifactId=aliyun-sdk-oss
-Dversion=2.2.3
-Dpackaging=jar
-Dfile=D:\aliyun-sdk-oss-2.2.3.jar
-Durl=http://127.0.0.1:8081/repository/maven-3rd/
-DrepositoryId=nexus-releases
复制代码
注意事项:
本地->私服->官服