文章目录
介绍
-
Docker是一个用来装应用的容器,就好比杯子用来装水,笔筒用来装笔,书包用来装书一样,你可以把hello world放到Docker里,你可以把网站放到Docker里,你可以把你想的到的任何程序放到Docker里。
-
Docker 有三大重要的概念:仓库、镜像、容器
-
特性:
-
- 组织有序性
以传统的方式部署你的应用,可能出现由于多个应用程序的依赖不用,导致应用之间的依赖变得非常混乱,若此时出现两个应用依赖同一个程序但却依赖不同版本,便会出现让人比较头痛的问题,使用Docker便可以很方便的帮我们管理各个应用的依赖,并以容器为基础将应用的运行环境独立开来,从而不会互相影响,还能提高资源利用率。
- 组织有序性
-
- 便携性
另一问题是,以传统的方式部署你的应用,如果我们的应用如果后期需要迁移(这里的迁移包括相同操作系统和不同操作系统的迁移),还是需要做大规模的集群,都是一件工作量非常大的操作。而容器化了的应用,对这些操作都是非常方便的。
- 便携性
-
- 安全性
最后一个不得不提的问题就是安全,以传统的方式部署你的应用,如果该应用被攻击者攻击,或者因为程序自身的bug,又或是运行环境多个应用间混乱的依赖关系导致的问题,这样的话,你的服务器系统安全危险级别会很高,因为这些问题将直接影响你的系统安全。但如果你的应用是运行在Docker容器中,那么一切的危害都会被隔离在容器内,因为容器的资源跟系统是隔离的,危害将被降到最低。
- 安全性
安装
- Docker 的安装相对来说也算比较简单,咱们使用 CentOS7 来安装 Docker,不过 Docker 官方要求 CentOS 操作系统内核必须在 3.10 以上,所以我们这边使用 CentOS7 来安装;
PS:可以使用 uname -r 来查看当前系统的内核版本
基于 CentOS7 的安装步骤如下:
-
- 更新 yum 仓库,确保 yum 包都是最新版本
yum update
-
- 查看是否有安装 docker,若有则将其删除
yum list installed|grep docker
- 如果有的话则删除对应的包(
没有则不用操作这一步
)
yum remove docker......
-
- 安装需要的软件包,yum-util 提供 yum-config-manager 功能,另外两个是 devicemapper 驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
-
- 设置 yum 源
yum-config-manager --add-repo http://mirrors.aliyun.com/repo/Centos-7.repo
-
- 查看仓库中所有 docker 版本,选择你需要的版本安装
yum list docker-ce --showduplicates | sort -r
-
- 安装 docker
yum install -y docker-ce 或者 yum install -y docker
-
- 设置 docker 开机自动启动
systemctl start docker # 启动 docker 服务端
systemctl enable docker # 启用 docker 服务开机自启
-
- 校验 docker 是否启动成功 及其版本
systemctl status docker
docker version
-
9.安装阿里云镜像映射
-
账号登录阿里云搜索容器镜像服务, 找到镜像加速器
-
该页面找到代码 直接copy到命令行 然后回车运行即可
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
基本命令操作
docker基本操作
- 查看本地镜像
docker images
- 删除镜像(通过
docker images
查看各镜像id)
docker rmi 镜像id
- 网络搜索镜像(redis为举例子)
docker search redis
- 从docker仓库拉取镜像下载到本地,若要指定版本可去官网
https://hub.docker.com/
查看有哪些版本即可命令后面加版本下载,例如docker pull redis:5.0
docker pull redis
-
新建容器:
docker run IMAGE [COMMAND] [ARGS…]
run 命令解释.- 命令会检测当前要运行的镜像在本地存不存在,若不存在他会自动 pull 下来再运行
- 运行后会启动一个容器, 并且开启一个文件系统, 你可以直接在容器内创建文件夹. 运行一个指定的程序, 当程序退出后, 容器也就退出了
- 运行时的容器无法删除, 只能停止后删除, 或者加上 -f 参数强制删除
示例:docker run centos echo 'hello docker'
-
新建启动容器:
-i :保持运行
-t :交互式容器,指定一个伪终端或终端(启动后默认进入容器内部.输入命令exit
退出后,容器则关闭)
-d :守护式容器,后台启动(启动后不默认进入容器内部.输入命令exit
退出后,容器不关闭)
–name : 为容器命名
示例(这里的centos:7
是 版本为7的centos类型镜像):
docker run -it --name=c1 centos:7 /bin/bash
- 退出容器.
`exit`
- 进入容器
docker exec -it 容器名 /bin/bash
- 查看容器:
docker ps [-a] [-l]
-a:表示列举所有的容器
-l :表示列举最近创建的容器.
默认情况容器在运行之后就停止了,ps只是显示正在运行的容器.
- 查看容器详细信息:
docker inspect [容器名字|容器唯一标识]
- 停止运行中的容器
docker stop 容器名称
- 重新启动停止的容器:
docker start -i 容器名
- 删除停止的容器:
docker rm 容器名
只能删除停止的容器,但是不能删除正在运行中的容器.
- 删除所有已停止的容器
docker rm $(docker ps -aq)
- 退出但不关闭容器:
Ctrl+P Ctrl+Q (快捷键先后顺序)
- 新建启动守护式容器并让它执行命令:
docker run -d 镜像名 [COMMAND] [ARG…]
示例:
docker run --name dc1 -d centos /bin/sh -c "while true; do echo helloworld;sleep 1;done"
- 查看容器日志:
docker logs -f -t --tail=xx 容器名
- 查看容器内进程:
docker top 容器名
应用部署
mysql部署
- 拉取mysql镜像
docker pull mysql:5.6
- 创建容器(这里的
-p 3307:3306
是宿主机的3307端口
则映射到该容器3306端口
,外部直接访问该宿主机3307即可访问该mysql容器)
docker run -id -p 3307:3306 --name=c_mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.6
- 进入该容器
docker exec -it c_mysql /bin/bash
- 进入mysql容器后输入命令 登录mysql
mysql -uroot -p123456
部署Tomcat
- 拉取镜像
docker pull tomcat
- 创建一个宿主机目录充当数据卷
mkdir ~/tomcat
- 创建tomcat容器(进入以上目录后,输入以下命令)
docker run -id --name=c_tomcat -p 8080:8080 -v $PWD:/usr/local/tomcat/webapps tomcat
Nginx部署流程
-
可用以上方法完成(模仿mysql即可)
-
Nginx部署流程
创建映射80端口的交互式容器
安装Nginx
安装文本编辑器vim
创建静态页面
修改Nginx配置文件
运行Nginx
验证网站访问 -
步骤:
1.创建一个守护式容器,并映射容器的80端口.
docker run -p 80 --name=web -it centos /bin/bash
2.进入容器后,需要安装nginx和vim,执行如下命令:
yum install -y epel-release
yum install -y nginx
3.在容器内部,进入到/usr/share/nginx/html 目录,修改index.html文件
vim index.html
4.运行nginx命令,启动服务
/usr/sbin/nginx
5.Ctrl+P和Ctrl+Q退出容器.
6.在宿主机上使用curl命令查看是否能访问.
curl http://127.0.0.1:32769/index.html (通过docker ps 查看端口)
配置数据卷(很少用)
- 数据卷则是宿主机与容器共享一个目录数据,就算容器被删除或关闭,宿主机目录的数据依旧不会被删除,可被其他容器继续挂载
- 目录必须是绝对路径
- 如果目录不存在,会自动创建
- 可以挂载多个数据卷
- 参考模板如下(新建容器的命令)
docker run .... -v 宿主机目录(文件):容器内目录(文件)
- 实际命令模板如下(容器挂载单个数据卷)
- 这里的宿主机中的
data
目录,与该新建容器中的data_container
共享同步数据
docker run -it --name=c1 -v /root/data:/root/data_container centos:7 /bin/bash
使用commit将容器构建成镜像(简单但不常用)
-
构建镜像可以让我们保存对容器的修改,并再次使用.提供了自定义镜像的能力,以软件的形式打包并方法服务及其运行环境.
docker里面提供了两种方式来构建镜像:
方式一:docker commit 通过容器构建
方式二:docker build 通过Dockerfile文件构建. -
使用commit构建镜像:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-a, --author=”” 指定镜像的作者.
-m, --message=”” 提交信息,构建信息
-p, --pause=true 默认情况在commit的时候会暂停容器,使用这个参数可以在构建的时候不暂停容器.- 操作模板(通过
docker ps -a
查看所有容器及其id信息): - commit创建的镜像,
不包含容器内挂载数据卷的数据
(细节)
- 操作模板(通过
docker commit 容器id 镜像名称
- 将镜像转成压缩文件
docker save - o 压缩包名称.tar 要被压缩的镜像
- 将压缩文件转成镜像
docker load -i 镜像压缩包名称.tar
使用DockerFile构建镜像(复杂却常用)
-
使用Dockerfile构建镜像:
什么是Dockerfile文件呢?其实就是包含了一些执行命令的文本文件. -
基本上一个项目 对应一个dockerFile
步骤(演示):- 1.在宿主机中,我们创建存放Dockerfile文件的目录和Dockerfile文件
- dockerFile文件 和 项目放在同一个目录
mkdir -p dockerfile/df_test1
cd dockerfile/df_test1/
vi Dockerfile
- 2.编写Dockfile文件
from
:父镜像是java:8 基于该镜像maintainer
:是作者名称add
:将jar包(该jar包位置和dockerFile一个目录,同级关系)加入到容器cmd
:
# First docker file for test
from java:8
maintainer tzh
add xk-practice-admin-application-1.0-SNAPSHOT.jar app.jar
cmd java -jar app.jar
- 3.使用build命令构建镜像模板.
docker build -t='镜像名称' Dockfile文件路径
- 实际参考模板 (
./springboot_dockerfile
为dockfile文件的路径,app
为构建的镜像名称 ,.
为版本最新意思)
docker build -f ./springboot_dockerfile -t app .
- 4.通过我们构建好的镜像来创建容器.(
app
为以上建立的镜像名称, 将宿主机的9000
端口映射到该容器8080
端口)
docker run -id -p 9000:8080 app
DockerFile的指令(详细)
-
指令主要分为两种:
注释 : # Comment
指令 : INSTRUCTION argument -
FROM:
包含两种格式:- FROM < image>
- FROM < image>:< tag>
image要求是已经存在的镜像,我们也称为基础镜像.必须是第一条非注释指令
-
MAINTAINER:
指定镜像的作者信息,包含镜像的所有者和联系信息. -
RUN:
指定当前镜像中运行的命令
RUN (shell模式)
/bin/sh -c command
RUN echo helloRUN [“executable”,”param1”,”param2”] (exec模式)
RUN [“/bin/bash”,”-c”,”echo hello”]每个RUN命令都会在当前镜像的上层创建一个新的镜像来运行指令.
-
EXPOSE:
指定运行该镜像的容器使用的端口.
虽然我们在构建镜像的时候暴露了端口号,但是我们在运行容器的时候依然需要指定端口的映射.
我们使用EXPOSE只是告诉Docker运行该镜像的容器会使用80端口,出于安全的考虑,docker并不会打开该端口.
而是需要我们在使用该镜像运行容器的时候指定端口的映射. -
CMD:
CMD指令提供容器默认运行的命令,和之前讲的RUN指令类似.都是执行一个命令,但是RUN命令指定的命令是在镜像构建的过程运行的.
CMD的命令是在容器运行的时候运行的.如果我们在docker run命令中指定运行的命令的时候,CMD的指令会被覆盖,默认命令就不会执行.
CMD命令是指定容器启动的时候默认命令.
两种模式.
CMD [“executable”,”param1”,”param2”] (exec模式)
CMD command param1 param2 (shell 模式)
CMD [”param1”,”param2”] (作为ENTRYPOINT指令的默认参数.)通过构建的镜像来创建容器
docker run -p 80 --name cmd_test1 -itd fjl0720/df_test3
docker top cmd_test1
发现已经启动nginx了.
如果我们在启动的时候指定了参数,默认的CMD命令就会被覆盖了. -
ENTRYPOINT:
这个和我们刚刚讲的CMD指令非常相似,唯一的区别:不会给docker run的启动命令给覆盖.
如果需要覆盖ENTRYPOINT的指令,需要在docker run使用docker run --entrypoint覆盖.
ENTRYPOINT [“executable”,”param1”,”param2”] (exec模式)
ENTRYPOINT command param1 param2 (shell 模式)
docker build -t=“fjl0720/df_test4” .
docker run -p 80 --name ep_test1 -d lanxw0720/df_test4
docker ps -l
可以发现,启动的容器依然使用的ENTRYPOINT指定的命令执行. -
ADD:
将文件和目录复制到使用dockerfile构建的镜像中.
目标的来源可以本地的地址也可以是远程地址.
如果是本地地址,本地地址必须是构建目录中的相对地址
对于远程URL,docker并不推荐使用,更建议使用的是curl或者wget的命令来获取
目标路径需要指定镜像中的绝对路径
ADD …
ADD “”…”” -
COPY:
同上.
COPY…
COPY“”…””在Dockerfile所在目录添加index.html文件
docker build -t=“lanxw0720/df_test6” .
docker run -p 80 --name add_test1 -d lanxw0720/df_test6
curl http://127.0.0.1:32775 -
VOLUME:
用于基于镜像创建的容器添加卷,一个卷可以存在一个或者多个容器的特定目录.这个目录可以绕过联合文件系统.提供共享数据和持久化数据的 功能.(后面单独讲) -
WORKDIR:
WORKDIR /path/to/workdir
这个指令从指令创建一个容器是,在容器内部设置工作目录.ENTRYPOINT和CMD的命令都会在这个目录下执行.
我们也可以使用这个命令给后续的构建中指定工作目录.
通常会使用绝对路径,如果使用了相对路径,那这个路径会一致传递下去.如下所示:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
结果====>/a/b/c -
ENV:
ENV
ENV …
这个指令主要是来设置环境变量,这个环境变量在构建过程中和运行过程中都有效. -
USER:
USER daemon
指定镜像会以什么样的用户去运行.
比如:USER nginx
基于该镜像启动的容器就会以nginx的用户来运行.
如果没有指定USER,容器会使用root用户来运行. -
ONBUILD:
ONBUILD [INSTRUCTION]
镜像触发器.
当一个镜像被其他镜像作为基础镜像时执行
会在构建过程中插入指令
示例:
docker run -p 80 --name onbuild_test1 -d lanxw0720/df_test7
curl http://127.0.0.1:32776
发现在构建这个镜像的时候并没有执行COPY命令.
接下来我们基于这个镜像来构建新的镜像.docker build -t=“lanxw0720/df_test8” .
docker run -p 80 --name onbuild_test2 -d lanxw0720/df_test8
curl http://127.0.0.1:32777
此时发现已经执行COPY命令了.