Docker--简介
关于Docker我们来看一下百度百科给出的介绍:
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
上面提到Dockers是个容器能实现虚拟化,那么我们看一下Docker与虚拟机的区别
[图片上传失败...(image-e9d569-1543800377211)]
我们能看出docker容器要比传统的虚拟机要轻,传统的虚拟机需要创建一个guest系统环境,docker不需要他可以依赖本地的系统环境,很轻。Docker的容器本身不需要额外创建虚拟机管理系统,因此你可以启动多套Docker容器,这样就可以充分发挥主机服务器的物理资源,也可以降低因为采购服务器licenses而带来的额外成本。
Docker核心--镜像和容器
首先我们来看一下官方给出的解释:
A container is launched by running an image. An image is an executable package that includes everything needed to run an application--the code, a runtime, libraries, environment variables, and configuration files.
A container is a runtime instance of an image--what the image becomes in memory when executed (that is, an image with state, or a user process). You can see a list of your running containers with the command,
docker ps
, just as you would in Linux.
镜像包含了一系列可运行的代码、架包、环境变量、配置文件等等的可执行的包,而容器的创建需要一个可运行的镜像,容器就是一个运行时镜像的实例。
我们再来看下这张图:
[图片上传失败...(image-777eb2-1543800081343)]
一般认为,没有继承自其他镜像的镜像为Base Image,也就是rootfs,图片中的bootfs和rootfs两个概念,来源于Linux,鉴于笔者对Linux只停留在应用的情况下,对于bootfs与rootfs就不做更深入的解释,下面我们来讲一下docker运行的基本原理。
- Docker镜像是由文件系统叠加而成。最低端是一个引导文件系统,即bootfs。当一个容器启动后,它将会被移到内存中,而引导文件系统则会被卸载,以留出更多的内存供initrd磁盘镜像使用。
- Docker镜像的第二层是root文件系统rootfs,它位于引导文件系统之上。rootfs可以是一种或多种操作系统。
- 在Docker里,root文件系统永远只能是只读状态,并且Docker利用联合加载技术又会在root文件系统层上加载更多的只读文件系统。联合加载指的是一次同时加载多个文件系统,但是在外面看起来只能看到一个文件系统。联合加载会将各层文件系统叠加到一起,这样最终的文件系统会包含所有底层的文件和目录。
- 当从一个镜像启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统。 当Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。如果修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏。
- 如此强大的技术之一。每个只读镜像层都是只读的,并且以后永远不会变化。当创建一个新容器时,Docker会构建出一个镜像栈,并在栈的最顶端添加一个读写层。这个读写层再加上其下面的镜像层以及一些配置数据,就构成了一个容器
也就是说镜像制作好了之后,是只读的不可以更改,当进行运行启动容器是,会在最顶层加载一个读写文件系统,所有的数据都会保存到这个文件系统上面,对底层的镜像是零浸入的,这也就是说我们能够将一个application制作成一个镜像,这个镜像是可复用的,这大大节省了运维成本,针对一些镜像,例如mysql,centos我们直接可以下载镜像,直接运行!!
Docker 基本语法
查看docker 镜像
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
node Node.js is a JavaScript-based platform for s… 6670 [OK]
tomcat Apache Tomcat is an open source implementati… 2191 [OK]
java Java is a concurrent, class-based, and objec… 1905 [OK]
openjdk OpenJDK is an open-source implementation of … 1395 [OK]
ghost Ghost is a free and open source blogging pla… 879 [OK]
anapsix/alpine-java Oracle Java 8 (and 7) with GLIBC 2.28 over A… 373 [OK]
jetty Jetty provides a Web server and javax.servle… 281 [OK]
couchdb CouchDB is a database that uses JSON for doc… 246 [OK] ```
**拉取镜像**
```root@tuxiaolei:/home/nvshenluoxiaobai# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a5a6f2f73cd8: Pull complete
1ba02017c4b2: Pull complete
33b176c904de: Pull complete
Digest: sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
Status: Downloaded newer image for nginx:latest
查看本地镜像列表
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 5958914cc558 3 days ago 94.9MB
nginx latest 568c4670fa80 4 days ago 109MB
查看某个镜像的详细信息
[
{
"Id": "sha256:5958914cc55880091b005658a79645a90fd44ac6a33abef25d6be87658eb9599",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:f57d1597d038a742dfba6acfaf48b10e6383466eea2aef95d1ee76f32633f959"
],
"Parent": "",
"Comment": "",
"Created": "2018-11-28T23:30:01.179460123Z",
"Container": "dfc3616dd94b0f16f74ad3c738baa37168d6f782685c763391dc1fe5e4fa1569",
"ContainerConfig": {
"Hostname": "dfc3616dd94b",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.10",
"REDIS_VERSION=5.0.2",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.2.tar.gz",
"REDIS_DOWNLOAD_SHA=937dde6164001c083e87316aa20dad2f8542af089dfcb1cbb64f9c8300cd00ed"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"redis-server\"]"
],
"ArgsEscaped": true,
"Image": "sha256:0d301a3ab4ce5b07faab5375b0a2d09247e337c75a39a0edb6cae3034641ef47",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "17.06.2-ce",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.10",
"REDIS_VERSION=5.0.2",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.2.tar.gz",
"REDIS_DOWNLOAD_SHA=937dde6164001c083e87316aa20dad2f8542af089dfcb1cbb64f9c8300cd00ed"
],
"Cmd": [
"redis-server"
],
"ArgsEscaped": true,
"Image": "sha256:0d301a3ab4ce5b07faab5375b0a2d09247e337c75a39a0edb6cae3034641ef47",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": [],
"Labels": null
},
"Architecture": "amd64",
"Os": "linux",
"Size": 94925974,
"VirtualSize": 94925974,
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/32d07536d351114ebefc53daff1094e9ca6c37d282b04136eb6e1b9a6affdaab/diff:/var/lib/docker/overlay2/d338e933b9e1877932f2ce4e7ff25bbaf8c30a6fb7ab8ade9497f3bd633daafc/diff:/var/lib/docker/overlay2/bf74e4d9e35815d13204572b9592890ad4b86c853d814dff97930253d6695706/diff:/var/lib/docker/overlay2/c32e23b8e5b5d222f9467a10f41fd33ac41916b1c042304012f85b50f9eef9a7/diff:/var/lib/docker/overlay2/54c65094137a50d0c34363abbb4c29a2dd771f12e70761fae95da3fb5f7daef6/diff",
"MergedDir": "/var/lib/docker/overlay2/9a0ab9655a90ac0b9bb09bae4e2ff1f725e1d30fccfc9bb0dc2ad66d5c4164f1/merged",
"UpperDir": "/var/lib/docker/overlay2/9a0ab9655a90ac0b9bb09bae4e2ff1f725e1d30fccfc9bb0dc2ad66d5c4164f1/diff",
"WorkDir": "/var/lib/docker/overlay2/9a0ab9655a90ac0b9bb09bae4e2ff1f725e1d30fccfc9bb0dc2ad66d5c4164f1/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:ef68f6734aa485edf13a8509fe60e4272428deaf63f446a441b79d47fc5d17d3",
"sha256:2c1e04fae1f2111671c8ab19fee9d5d69ee29709487cac889385ff4bdb5f081f",
"sha256:94bdf74df564a4f3c84f5854c4496f80915a375662f220c74b649878e781a13e",
"sha256:90d2c5d0209d338573643ca0517731154dcc9c49e50ec9d0857eaddee2d871da",
"sha256:dc682cc939702aa54f3aa457b12f9c572dbc0271f3f6e9023a45657cb075cd8e",
"sha256:bb84a87b243fddbd353bedec71dc3fcb4d0b61ff2f8cc8d64730ede22dad09c9"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]
启动镜像
基本命令 docker run + 名字(或者imageID或者containerID)
root@tuxiaolei:~$ ps -ef | grep nginx
root 26523 24712 0 17:03 pts/0 00:00:00 docker run nginx
root 26583 26561 0 17:03 ? 00:00:00 nginx: master process nginx -g daemon off;
systemd+ 26650 26583 0 17:03 ? 00:00:00 nginx: worker process
nvshenl+ 26889 26872 0 17:04 pts/1 00:00:00 grep --color=auto nginx
基本命令就讲到这里,其余常用命令在后面的实战中给出,这里附上docker官方文档地址
Dockerfile
Dockerfile
定义容器内环境中发生的事情。对网络接口和磁盘驱动器等资源的访问在此环境中进行虚拟化,该环境与系统的其他部分隔离,因此您需要将端口映射到外部世界,并具体说明要“复制”到哪些文件那个环境.
MAINTAINER [email protected]
RUN mkdir -p /smart/bin/com.xx.more/smart-gateway
WORKDIR /smart/bin/com.xx.more/smart-gateway
EXPOSE 9999
ADD ./smart-gateway/target/smart-gateway.jar ./
CMD java -Djava.security.egd=file:/dev/./urandom -jar smart-gateway.
我们来解读一下
From
---> 表明当前镜像所基于的镜像,我们是个javaweb 项目,项目依赖于java镜像
MAINTAINER
---->维护者信息
RUN
---> 运行是命令
WORKDIR
--->工作目录
EXPOSE
---> 暴露端口,方便镜像 运行时做映射
ADD
---> 将本地目录文件加入镜像
CMD
--->指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
VOLUME
---> 创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等