步入社会的第一个项目部署的时候就用到了docker,之前从未接触过docker,从零开始学习。嫌看视频慢,本着理论与实战相结合的遵旨,看着Docker中文文档直接上手使用。
1、Docker概述
Docker是一款针对程序开发人员和系统管理员来开发、部署、运行应用的一款虚拟化平台。Docker 可以让你像使用集装箱一样快速的组合成应用,并且可以像运输标准集装箱一样,尽可能的屏蔽代码层面的差异。Docker 会尽可能的缩短从代码测试到产品部署的时间。
1.1 什么是docker
Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初的发起者是dotCloud公司。Docker的主要目标是“Build,Ship and Run Any App,Anywhere"等生命周期的管理,达到应用组件级别的”一次封装,到处运行“。
Docker引擎的基础是Linux容器(Linux Containers,LXC)技术。目前LXC已被集成到主流的Linux内核中,成为Linux系统轻量级容器技术的事实标准。
容器技术准确的描述是:容器有效的将由单个操作系统管理的资源划分到孤立的组中,以便更好的在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样即不需要指令级模拟,也不需要即时编译。
1.2 为什么使用docker
Docker在开发和运维过程中,有如下几个方面的优势:
A. 更快速的交换和部署。
开发人员可以使用镜像来快速构建一套标准的开发环境;开发、测试、运维人员可以直接使用相同环境来部署代码。Docker可以快速创建、删除容器,实现快速迭代,节约大量开发、测试、部署时间。
B. 更高效的资源利用。
Docker是内核级的虚拟化,启动更快,消耗资源更小。
C. 更轻松的迁移和扩展。
Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云等。
D. 更简单的更新管理 。
Docker所有修改都以增量的方式进行分发和更新,从而更容易的实现自动化。
1.3 docker与虚拟机的比较
特性 | 容器 | 虚拟机 |
启动速度 |
秒级 |
分钟级 |
硬盘使用 |
一般MB |
一般GB |
性能 |
接近原生 |
弱于 |
系统支持量 |
单机支持上千容器 |
一般几十个 |
隔离性 |
安全隔离 |
完全隔离 |
2、Docker核心概念及安装
docker镜像:类似于虚拟机镜像,可以将它理解为一个面向Docker引擎的只读模板,包含了文件系统。
docker容器:容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是相互隔离、互不可见的。
形象的比喻解释这两个概念,就像是模型与产品。当一个镜像建好以后就不再改变,根据这一个镜像可以启动好多容器。把镜像就比作那模型,把容器就比作产品。也好比类与对象的关系,一个类可以构建出多个对象。
Docker仓库:类似于代码仓库,是Docker集中存放镜像文件的场所。注册服务器是存放仓库的地方,其中放着多个仓库。每个仓库集中存放一类镜像,通过不同的标签(tag)来进行区分。
docker的安装
Docker 的安装和使用有一些前提条件,主要体现在体系架构和内核的支持上。对于体系架构,除了 Docker 一开始就支持的 X86-64 ,其他体系架构的支持则一直在不断地完善和推进中。
Docker 分为 CE 和 EE 两大版本。 CE 即社区版(免费,支持周期 7 个月), EE 即企业版,强调安全,付费使用,支持周期 24 个月。
我的安装环境:linux centos7 64位
首先卸载掉旧版docker
[root@slave1 ~]# sudo 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(以下是安装命令及安装日志输出)
[root@slave1 ~]# sudo yum install docker
已加载插件:fastestmirror
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
(1/4): extras/7/x86_64/primary_db | 205 kB 00:00:01
(2/4): base/7/x86_64/group_gz | 166 kB 00:00:01
(3/4): updates/7/x86_64/primary_db | 6.5 MB 00:00:17
(4/4): base/7/x86_64/primary_db | 6.0 MB 00:00:31
Determining fastest mirrors
* base: mirrors.tuna.tsinghua.edu.cn
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
正在解决依赖关系
--> 正在检查事务
---> 软件包 docker.x86_64.2.1.13.1-96.gitb2f74b2.el7.centos 将被 安装
--> 正在处理依赖关系 docker-common = 2:1.13.1-96.gitb2f74b2.el7.centos,它被软件包 2:docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64 需要
--> 正在处理依赖关系 docker-client = 2:1.13.1-96.gitb2f74b2.el7.centos,它被软件包 2:docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64 需要
--> 正在处理依赖关系 subscription-manager-rhsm-certificates,它被软件包 2:docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64 需要
--> 正在检查事务
....
.....
......
已安装:
docker.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos
作为依赖被安装:
PyYAML.x86_64 0:3.10-11.el7 atomic-registries.x86_64 1:1.22.1-26.gitb507039.el7.centos
audit-libs-python.x86_64 0:2.8.4-4.el7 checkpolicy.x86_64 0:2.5-8.el7
container-selinux.noarch 2:2.99-1.el7_6 container-storage-setup.noarch 0:0.11.0-2.git5eaf76c.el7
containers-common.x86_64 1:0.1.35-2.git404c5bd.el7.centos docker-client.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos
docker-common.x86_64 2:1.13.1-96.gitb2f74b2.el7.centos libcgroup.x86_64 0:0.41-20.el7
libsemanage-python.x86_64 0:2.5-14.el7 libyaml.x86_64 0:0.1.4-11.el7_0
oci-register-machine.x86_64 1:0-6.git2b44233.el7 oci-systemd-hook.x86_64 1:0.2.0-1.git05e6923.el7_6
oci-umount.x86_64 2:2.3.4-2.git87f9237.el7 policycoreutils-python.x86_64 0:2.5-29.el7_6.1
python-IPy.noarch 0:0.75-6.el7 python-backports.x86_64 0:1.0-8.el7
python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.el7 python-ipaddress.noarch 0:1.0.16-2.el7
python-pytoml.noarch 0:0.1.14-1.git7dea353.el7 python-setuptools.noarch 0:0.9.8-7.el7
setools-libs.x86_64 0:3.3.8-4.el7 subscription-manager-rhsm-certificates.x86_64 0:1.21.10-3.el7.centos
yajl.x86_64 0:2.0.4-4.el7
作为依赖被升级:
audit.x86_64 0:2.8.4-4.el7 audit-libs.x86_64 0:2.8.4-4.el7 libselinux.x86_64 0:2.5-14.1.el7 libselinux-python.x86_64 0:2.5-14.1.el7
libselinux-utils.x86_64 0:2.5-14.1.el7 libsemanage.x86_64 0:2.5-14.el7 libsepol.x86_64 0:2.5-10.el7 policycoreutils.x86_64 0:2.5-29.el7_6.1
selinux-policy.noarch 0:3.13.1-229.el7_6.12 selinux-policy-targeted.noarch 0:3.13.1-229.el7_6.12
完毕!
安装完毕后验证!
[root@slave1 ~]# docker version
Client:
Version: 1.13.1
API version: 1.26
Package version:
3、使用笔记
3.1 首先启动Docker-CE
[root@slave1 ~]# sudo systemctl enable docker
[root@slave1 ~]# sudo systemctl start docker
使用docker启动第一个容器Hello World,这是一个默认的docker仓库中已有镜像,我们直接使用该镜像启动一个容器。
[root@slave1 ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
Trying to pull repository docker.io/library/hello-world ...
latest: Pulling from docker.io/library/hello-world
1b930d010525: Pull complete
Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
Status: Downloaded newer image for docker.io/hello-world:latest
Hello from Docker!
[root@slave1 ~]# docker run hello-world
执行该条命令,首先会在本地找有没有hello-world镜像,如果没有的话就去docker仓库去下载,默认的docker仓库在国外,为了加快下载速度可以修改为国内的镜像仓库,修改文件/etc/docker/daemon.json。
在该文件中添加"registry-mirrors": ["https://registry.docker-cn.com"]。
[root@slave1 ~]# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
3.2 常用docker命令
- 查看本地已有的镜像
[root@slave1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/hello-world latest fce289e99eb9 6 months ago 1.84 kB
- 查看所有容器
[root@slave1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
43e769a7273f hello-world "/hello" 11 minutes ago Exited (0) 11 minutes ago hardcore_noether
- 查看正在运行的容器
[root@slave1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 删除容器
[root@slave1 ~]# docker rm 43e769a7273f
43e769a7273f
- 删除镜像
[root@slave1 ~]# docker rmi fce289e99eb9
Untagged: docker.io/hello-world:latest
Untagged: docker.io/hello-world@sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e
Deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3
##注意:在删除镜像前需要先删掉使用该镜像启动的容器,否则报错。
[root@slave1 ~]# docker rmi fce289e99eb9
Error response from daemon: conflict: unable to delete fce289e99eb9 (must be forced) - image is being used by stopped container 619c2a70aeb3
3.3 使用dockerfile创建自定义镜像
Dockerfile 由一行行命令语句组成,并且支持以 #
开头的注释行。
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。例如:
#基于centos建镜像
FROM centos:7
MAINTAINER Docker liuww <[email protected]>
#安装jdk
COPY ./jdk1.8.0_171 /apps/jdk1.8.0_171
#安装Tomcat
COPY ./apache-tomcat-8.5.42 /apps/apache-tomcat-8.5.42
#配置环境变量
ENV JAVA_HOME /apps/jdk1.8.0_171/
ENV JRE_HOME /apps/jdk1.8.0_171/jre/
ENV CLASS_PATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
EXPOSE 8080
#容器启动后执行的命令
CMD ["/apps/apache-tomcat-8.5.42/bin/catalina.sh", "run"]
常用指令
指令的一般格式为 INSTRUCTION arguments
,指令包括 FROM
、MAINTAINER
、RUN
等。
FROM
格式为 FROM <image>
或FROM <image>:<tag>
。
第一条指令必须为 FROM
指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM
指令(每个镜像一次)。
MAINTAINER
格式为 MAINTAINER <name>
,指定维护者信息。
RUN
格式为 RUN <command>
或 RUN ["executable", "param1", "param2"]
。
前者将在 shell 终端中运行命令,即 /bin/sh -c
;后者则使用 exec
执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]
。
每条 RUN
指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \
来换行。
CMD
支持三种格式
CMD ["executable","param1","param2"]
使用exec
执行,推荐方式;CMD command param1 param2
在/bin/sh
中执行,提供给需要交互的应用;CMD ["param1","param2"]
提供给ENTRYPOINT
的默认参数;
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD
命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD
指定的命令。
EXPOSE
格式为 EXPOSE <port> [<port>...]
。
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。
ENV
格式为 ENV <key> <value>
。 指定一个环境变量,会被后续 RUN
指令使用,并在容器运行时保持。
例如
#配置环境变量
ENV JAVA_HOME /apps/jdk1.8.0_171/
ENV JRE_HOME /apps/jdk1.8.0_171/jre/
ENV CLASS_PATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
ADD
格式为 ADD <src> <dest>
。
该命令将复制指定的 <src>
到容器中的 <dest>
。 其中 <src>
可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY
格式为 COPY <src> <dest>
。
复制本地主机的 <src>
(为 Dockerfile 所在目录的相对路径)到容器中的 <dest>
。
当使用本地目录为源目录时,推荐使用 COPY
。
ENTRYPOINT
两种格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
(shell中执行)。
配置容器启动后执行的命令,并且不可被 docker run
提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT
,当指定多个时,只有最后一个起效。
Dockerfile实战:构建Tomcat镜像
步骤:
1.新建docker_demo文件夹,并进入。
[root@slave1 apps]# mkdir docker_demo
[root@slave1 apps]# cd do_demo/
[root@slave1 do_demo]# pwd
/apps/do_demo
2.将Tomcat和jdk安装包复制到该目录中。
3.在该目录下新建Dockerfile文件,文件名首字母D必须为大写。
[root@slave1 docker_dome]# ll
总用量 0
drwxr-xr-x. 9 root root 220 7月 23 21:08 apache-tomcat-8.5.42
-rw-r--r--. 1 root root 0 7月 23 21:09 Dockerfile
drwxr-xr-x. 8 root root 255 7月 23 21:09 jdk1.8.0_171
4.根据上述基本结构来编辑Dockerfile文件。
#基于centos建镜像
FROM centos:7
MAINTAINER Docker liuww <[email protected]>
#安装jdk
COPY ./jdk1.8.0_171 /apps/jdk1.8.0_171
#安装Tomcat
COPY ./apache-tomcat-8.5.42 /apps/apache-tomcat-8.5.42
#配置环境变量
ENV JAVA_HOME /apps/jdk1.8.0_171/
ENV JRE_HOME /apps/jdk1.8.0_171/jre/
ENV CLASS_PATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
EXPOSE 8080
#容器启动后执行的命令
CMD ["/apps/apache-tomcat-8.5.42/bin/catalina.sh", "run"]
5.使用docker build命令来构建镜像。
[root@slave1 docker_dome]# docker build -t="tomcat:v1" .
Sending build context to Docker daemon 403.6 MB
Step 1/9 : FROM centos:7
---> 9f38484d220f
Step 2/9 : MAINTAINER Docker liuww <[email protected]>
---> Using cache
---> 29064dbda2ca
Step 3/9 : COPY ./jdk1.8.0_171 /apps/jdk1.8.0_171
---> Using cache
---> 6453cfc8d0fd
Step 4/9 : COPY ./apache-tomcat-8.5.42 /apps/apache-tomcat-8.5.42
---> Using cache
---> 88ca237ba792
Step 5/9 : ENV JAVA_HOME /apps/jdk1.8.0_171/
---> Using cache
---> 2a24716882fd
Step 6/9 : ENV JRE_HOME /apps/jdk1.8.0_171/jre/
---> Using cache
---> 3e32d8e91fac
Step 7/9 : ENV CLASS_PATH .:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
---> Using cache
---> 12b2048ee776
Step 8/9 : EXPOSE 8080
---> Using cache
---> 100a8bfad5bc
Step 9/9 : CMD /apps/apache-tomcat-8.5.42/bin/catalina.sh run
---> Using cache
---> 6d57a44ff41a
Successfully built 6d57a44ff41a
docker build后面使用-t来指定镜像的标签信息。-t="tomcat:v1",表示镜像名为tomcat,版本为v1。
查看构建的镜像:
[root@slave1 docker_dome]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
172.18.231.30/si-tech/lww-tomcat v1 6d57a44ff41a 28 hours ago 603 MB
tomcat v1 6d57a44ff41a 28 hours ago 603 MB
paas-web v1 bb1e42c79a83 35 hours ago 977 MB
docker.io/centos 7 9f38484d220f 4 months ago 202 MB
docker.io/hello-world latest fce289e99eb9 6 months ago 1.84 kB
6.使用docker run命令来启动容器。
[root@master tomcat]# docker run -p 8080:8080 --name myTomcat tomcat:v1
23-Jul-2019 13:28:28.397 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.42
23-Jul-2019 13:28:28.403 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Jun 4 2019 20:29:04 UTC
23-Jul-2019 13:28:28.408 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 8.5.42.0
23-Jul-2019 13:28:28.409 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
23-Jul-2019 13:28:28.409 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 3.10.0-957.21.3.el7.x86_64
23-Jul-2019 13:28:28.410 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
23-Jul-2019 13:28:28.410 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /apps/jdk1.8.0_171/jre
...
.....
.......
.42/webapps/manager] has finished in [86] ms
23-Jul-2019 13:28:30.226 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
23-Jul-2019 13:28:30.287 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
23-Jul-2019 13:28:30.312 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1506 ms
访问:
docker入门到此结束,希望同学们多多指正。