步入社会的第一个项目部署的时候就用到了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)来进行区分。
2.1 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:
2.2 用户赋权
安装完docker后,执行docker相关命令,出现
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/json: dial unix /var/run/docker.sock: connect: permission denied
原因:docker进程使用Unix Socket而不是TCP端口。而默认情况下,Unix socket属于root用户,需要root权限才能访问。
Manage Docker as a non-root user
The docker daemon binds to a Unix socket instead of a TCP port. By default that Unix socket is owned by the user root and other users can only access it using sudo. The docker daemon always runs as the root user.
If you don’t want to use sudo when you use the docker command, create a Unix group called docker and add users to it. When the docker daemon starts, it makes the ownership of the Unix socket read/writable by the docker group.
解决办法:
(1)使用sudo获取管理员权限,运行docker命令
(2)docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,因此只要创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket了,进而也就可以执行docker相关命令
sudo groupadd docker #添加docker用户组
sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组
docker ps #测试docker命令是否可以使用sudo正常使用
sudo service docker restart #重启Docker服务
exit #退出当前用户,重新进入(否则不生效)
2.3 docker 命令自动补全
ls /usr/share/bash-completion/bash_completion
出现:/usr/share/bash-completion/bash_completion
如果没有出现,安装:yum install bash-completion
source /usr/share/bash-completion/completions/docker
source /usr/share/bash-completion/bash_completion
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 <123123@qq.com>
#安装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 <123123@qq.com>
#安装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 <2463471464@qq.com>
---> 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入门到此结束,希望同学们多多指正。