一、Docker是什么
说说我自己的理解:Docker里面最需要理解的三个概念,仓库,镜像,容器。 仓库:类似于maven存放jar包的仓库,docker仓库用于存放镜像,每个仓库存放版本不同的镜像,如某个仓库存放不同版本的jdk; 镜像:可以理解为java中的类,是对某一类事物的定义; 容器:可以理解为java中的对象,通过类创建出来,容器就通过镜像创建出来,一个镜像可以创建N个容器,彼此之间互不干扰。
AI 代码解读
二、Docker安装
1.安装环境
当前安装机器为centos7,需联网
2.安装所需软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
AI 代码解读
3.设置Docker镜像仓库
由于网络原因,国外官方镜像仓库存在访问超时问题,好在还有阿里这样的大厂提供国内镜像仓库。
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
AI 代码解读
4.安装社区版docker(Docker CE)
yum install docker-ce
AI 代码解读
安装过程中,出现的选择项,选择y
5.安装失败
如果安装失败,卸载已安装部分,按照上面步骤重新操作。
-- 卸载Docker软件包
yum remove docker-ce
-- 删除容器/镜像等
rm -rf /var/lib/docker
AI 代码解读
6.Docker服务启动/停止
- 启动Docker:systemctl start docker
- 停止Docker:systemctl stop docker
- 重启Docker:systemctl resatrt docker
- 查看Docker状态:systemctl status docker
- 开机自启动Docker:systemctl enable docker
- Docker帮助命令:docker --help
- Docker版本查询:docker version
三、Docker镜像操作
1.镜像概念
官方概念:Docker镜像是由文件系统叠加而成(是一种文件的存储形式)。最底端是一个文件引导系统,即bootfs,这很像典型的Linux/Unix的引导文件系统。Docker用户几乎永远不会和引导系统有什么交互。实际上,当一个容器启动后,它将会被移动到内存中,而引导文件系统则会被卸载,以留出更多的内存供磁盘镜像使用。Docker容器启动是需要的一些文件,而这些文件就可以称为Docker镜像。
我的理解:简单点说就是把我们需要使用的软件最小可用化的打包成一个文件,放到远程/本地仓库,使用者可以通过命令拉到本地进行使用,比如MySQL镜像,把各个版本的MySQL软件打包放到远程仓库,不需要任何额外的安装,拉下来就可通过容器使用。
2.镜像操作命令
- 镜像列表
docker images
AI 代码解读
REPOSITORY:镜像所在仓库的名称
TAG:镜像标签(一般是版本号,latest表示最新镜像)
IMAGE ID:镜像ID
CREATED:镜像的创建日期
SIZE:镜像大小
AI 代码解读
- 只显示镜像ID
docker images -q
AI 代码解读
- 镜像搜索
docker search [OPTIONS] 镜像名称
AI 代码解读
NAME:仓库名称
DESCRIPTION:镜像描述
STARS:关注度,反应一个镜像的受欢迎程度
OFFICIAL:是否官方
AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的
OPTIONS可选参数说明:
-s:列出关注数大于指定数值的镜像 docker search -s 1000 centos (关注数大于1000的centos镜像);
--no-trunc:显示完整的镜像描述 docker search --no-trunc centos
AI 代码解读
- 镜像拉取
docker pull 镜像名:标签名
如拉取mysql镜像最新版本:docker pull mysql (不指定标签名,默认拉取最新版本)
如拉取mysql 5.6版本镜像:docker pull mysql:5.6
拓展:
默认互联网镜像仓库在国外,由于网络原因,会出现拉取镜像超时问题,和别的软件一样,也可以使用镜像源代理,如阿里镜像加速器(阿里云这个是免费的,别的加速方式可自行google)
配置:
1.注册阿里云账号;
2.登录阿里云,搜索“容器镜像服务”;
3.点击左侧容器镜像加速器,复制容器镜像加速器地址(每个阿里云账号的加速器地址都不一样);
4.配置到自己的服务器;
vim /etc/docker/daemon.json
-- 插入以下内容
{
"registry-mirrors": ["复制的地址"]
}
***** 重新加载配置文件:systemctl daemon-reload
***** 重启docker服务:systemctl restart docker
重启完成后,再重新拉取镜像,速度明显提升。
AI 代码解读
- 镜像删除
docker rmi 镜像ID
如删除之前截图中mysql_new镜像,镜像ID为20e70043b0d6(docker images):docker rmi 20e70043b0d6
AI 代码解读
- 删除所有镜像
doker rmi `docker images -q`
(****是反单引号,不是单引号,在键盘左上角,一般在Esc按钮下面,就是中文状态下的 ~ 按钮*****)
这个操作类似于数据库子查询
AI 代码解读
总结一下,镜像操作命令和我们平常的CURD差不多,也是镜像的查询(search/images)、新增(pull)、删除(rmi ),编辑也有,第七章的本地镜像发布,熟悉这三个命令,镜像基本就这样了,好像也不是很难,可能还有别的操作,不过这些基本满足需求。
四、Docker容器操作
1.查看容器
- 查看正在运行中的容器
docker ps
AI 代码解读
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
---|---|---|---|---|---|---|
容器ID | 镜像 | 初始化命令 | 创建日期 | 容器状态 | 端口号 | 容器名称 |
查看所有容器(运行/停止)
docker ps -a
AI 代码解读
- 查看最后一次运行的容器
docker ps -l
AI 代码解读
- 查看指定状态容器
docker ps -f status=exited -- 查看已停止的容器
AI 代码解读
2.创建与启动容器
- 创建容器命令
参数说明
docker run [OPTIONS] 镜像名:标签名称
docker run [OPTIONS] 镜像ID
AI 代码解读
-
- -i 表示交互式运行容器(就是创建容器后,马上会启动容器,并进入容器 ),通常与 -t 同时使用;
-
- -t 启动后会进入其容器命令行, 通常与 -i 同时使用; 加入 -it 两个参数后,容器创建就能登录进去。即分配一个伪终端;
-
- --name 为创建的容器指定一个名称;
-
- -d 创建一个守护式容器在后台运行,并返回容器ID;这样创建容器后不会自动登录容器,如果加 -i 参数,创建后就会运行容器;
-
- -v 表示目录映射, 格式为: -v 宿主机目录:容器目录;
-
- -p 表示端口映射,格式为: -p 宿主机端口:容器端口
创建交互式容器
说明:交互式容器的意思是创建以后,会进入容器内部,比如创建了一个MySQL容器,就会进入MySQL容器内部,而非停留在宿主机命令
docker run -it --name=xxx 镜像名:标签名称|镜像ID
eg:docker run -it --name=test_centos7 7e6257c9f8d8
这是一个全新的小型centos系统,可以在该容器上做与宿主机相同的任何事,你可以在docker里面基于镜像创建N个这样的centos,它们互不影响,完全独立
AI 代码解读
退出并停止当前容器:exit
退出但不停止当前容器:Ctrl+p+q
AI 代码解读
3.启动/停止容器
docker start 容器名称|容器ID -- 启动容器
docker stop 容器名称|容器ID -- 停止容器
docker statr `docker ps -a -q` -- 启动所有容器
docker stop `docker ps -a -q` -- 停止所有容器
docker ps -a -q -- 查询所有容器id
docker kill 容器名称|容器ID -- 强制停止正在运行的容器(相当于电脑直接按电源键关机,stop则是通过界面点击关机按钮)
AI 代码解读
4.创建守护式容器
说明:守护式容器是指创建容器后不会登录到容器操作界面,容器会在后台运行,区别于交互式容器。
AI 代码解读
docker run -id --name=容器名称 镜像名:标签名称|镜像ID
AI 代码解读
说明:
守护式容器和交互式容器的区别在于创建的时候参数是-id还是-it,守护式创建后容器会自动后台运行,后续可通过命令登录到容器内部;交互式容器则在执行创建命令后,自动登录到容器内部,如果使用exit退出,容器会停止运行,如果想交互式容器继续后台运行,可使用Ctrl+p+q退出。
5.登录容器
docker exec -it 容器名称|容器id /bin/bash
AI 代码解读
说明:
exit 针对通过docker exec 进入的容器,只退出但不停止容器;
交互式容器通过docker exec 进入容器后,使用exit 也一样的只退出但不停止容器
6.宿主机与容器文件拷贝
docker cp 宿主机文件或目录 容器名称|容器id:容器文件或目录
docker cp 容器名称|容器id:容器文件或目录 宿主机文件或目录
拷贝命令均在宿主机中操作
AI 代码解读
7.数据目录挂载
docker run -id -v /宿主机绝对路径目录:/容器内目录 --name=容器名 镜像名:标签名称|镜像ID
AI 代码解读
其实就是创建容器的时候 通过可选参数 -v 进行宿主机与容器目录的挂载,挂载后的目录数据将保持一致。可以自己实践一下挂载后,修改某个txt文件的内容,看是否双方保持同步修改。
AI 代码解读
8.查看容器内部细节
docker inspect 容器名称|容器id
AI 代码解读
基于以上容器内容细节返回的json字符串,我们可以通过以下命令查询部分细节内容
eg: docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id -- 查询容器ip地址
查看别的细节只需要替换{{.NetworkSettings.IPAddress}}中的参数,那个点不能少
AI 代码解读
9.删除容器
说明:需要被删除的容器需要处于停止状态,处于运行状态的容器无法删除
AI 代码解读
docker rm 容器名称|容器id
AI 代码解读
思考:如何删除所有容器
10.部分容器创建实践
tomcat容器创建:
docker run -id --name=tomcat8 -p 8888:8080 -v /usr/local/project:/usr/local/tomcat/webapps
--privileged=true tomcat:8
说明:
-p:端口映射,表示将宿主机8888端口映射到docker中tomcat容器8080端口,访问服务的时候,就通过宿主机ip:8888访问服务;
-v:目录映射,表示将宿主机/usr/local/project映射到容器tomcat的/usr/local/tomcat/webapps目录,映射后两个目录数据保持通过,所以部署的时候,只需要将程序包发到宿主机的/usr/local/project目录,而不需要每次通过docker cp目录复制到容器该目录下;
--privileged:表示如果映射的是多级目录,防止有可能会出现没有权限的问题,所以加上此参数。
AI 代码解读
MySQL容器创建:
docker run -id --name=mysql5.7 -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
说明:
-e:表示添加环境变量,MYSQL_ROOT_PASSWORD表示root用户密码
-p:端口映射,同上
AI 代码解读
五、备份与恢复
1.容器保存为镜像
docker commit [-m="提交的描述信息"] [-a="创建者"] 容器名称|容器ID 生成的镜像名[:标签名] -- 将容器保存为镜像
AI 代码解读
2.无目录挂载容器保存为镜像
docker inspect --format='{{.Mounts}}' 容器名|容器ID -- 查看是否有目录挂载
AI 代码解读
eg: 容器 19fc926a19e1为centos容器,查询后无目录挂载,看直接保存为新镜像。
docker commit 19fc926a19e1 test_centos7_new:1.0
19fc926a19e1:需要备份的容器id
test_centos7_new:新的镜像名称
1.0:新镜像版本号,如果为空,默认为latest
AI 代码解读
说明:新生成的镜像与之前的镜像一样,可以进行创建容器等操作。
3.有目录挂在容器保存为镜像
说明:如果容器中存在目录挂载,如tomcat容器webapps中的工程是通过目录挂载进来的,在容器保存镜像时,数据不会被保存到新镜像中。
-- 这里可能有个疑问,Mysql的数据明明在容器里,不是通过挂载形式保存,保存为镜像也会丢失吗?答案是会丢失,我试了下,自己后面创建的数据库,在库里面的数据啥的在保存为镜像时会失。
解决:
1.目录挂载方法:先把在宿主机的数据备份在某个目录下,在docker run的时候使用-v参数将宿主机上的目录映射到容器里的目标路径中(tomcat是/usr/local/tomcat/webapps ,mysql是var/lib/mysql)
2.拷贝方法:先把在宿主机的数据备份在某个目录下,通过拷贝的方法docker cp将备份的数据复制进容器里的目标路径中(tomcat是 /usr/local/tomcat/webapps,mysql是var/lib/mysql)
AI 代码解读
第一种解决方法比较简单,以tomcat为例,复制tomcat工程所在目录到新目录,然后commit容器为新镜像,新镜像创建容器时,利用-v参数进行目录挂载就行了。 下面说一下第二种方法的操作(以MySQL为例)。
AI 代码解读
- 查看数据保存位置
docker inspect --format='{{.Mounts}}'
AI 代码解读
- 将此路径数据备份在宿主机 /mysql(如果后面镜像是提供给别人, 则此备份的数据也同时提供)
cp -rf /var/lib/docker/volumes/ac40703842eeebe85e81e266b47e41c7b3c409972f68b8b9133336faf243e075/_data /mysql
AI 代码解读
- mysql容器保存为镜像
docker commit mysql5.7 mysql_new:1.0
AI 代码解读
- 通过上面保存的镜像创建新的容器
docker run -id --name=mysql_new -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456
mysql_new:1.0
AI 代码解读
- 采用拷贝的方法还原数据,容器的数据目录为: /var/lib/mysql
docker cp /mysql/ mysql_new:/var/lib/
这里有个坑,不要在容器/var/lib/后面再加mysql文件夹名,要不然cp以后,就会变成/var/lib/mysql/mysql这样,直接上面的命令,让文件夹覆盖,变成/var/lib/mysql
AI 代码解读
- 重启MySQL容器
docker restart mysql_new
不重启链接后打开数据库时会报错
AI 代码解读
- 说明:做完mysql备份恢复后,举一反三,其他有这样需求的备份保存镜像也可以这样做。
4.镜像备份
docker save -o xxx.tar 镜像名称:标签名|镜像ID
AI 代码解读
5.镜像恢复
docker load -i xxx.tar
AI 代码解读
4和5的组合操作,可以让你利用物理的方式进行镜像的迁移,比如讲某一台服务器的镜像文件在另一台服务器恢复。第七章可以通过网络的方式进行这个操作。
AI 代码解读
六、Dockerfile语法规则
这里我也就搞懂了点皮毛,欢迎看到这里的同学做补充 ^_^
AI 代码解读
1.Dokcerfile概念
Dockerfile 用于构建一个新的Docker镜像的脚本文件,是由一系列命令和参数构成的脚本。
构建Dockerfile步骤
-
- 编写Dockerfile文件
-
- 通过docker build 命令生成新的镜像
-
- 通过docker run生成新的容器
2.Dockerfile语法规则与常用指令
文件命令从上往下执行
每条指令都会创建一个镜像,并对镜像进行提交
指令 | 作用 |
---|---|
FROM image_name:tag | 基础镜像,基于哪个基础镜像启动构建流程 |
MAINTAINER user_name | 镜像的创建者的姓名和邮箱地址等 |
COPY source_dir/file dest_dir/file | 和ADD相似,但是如果有压缩文件并不能解压 |
ADD source_dir/file dest_dir/file | 将宿主机的文件复制到容器内,如果是一个压缩文件, 将会在复制后自动解压 |
ENV key value | 设置环境变量 (可以写多条) |
RUN command | 是Dockerfile的核心部分(可以写多条),运行到当前行要执行的其他命令 |
WORKDIR path_dir | 设置工作目录,当创建容器后,命令终端默认登录进来后所在的目录。未指定则为根目录 / |
EXPOSE port | 当前对外暴露的端口号,使容器内的应用可以通过端口和外界交互 |
CMD argument | Dockerfile中可以有多个CMD,但是只有最后一个会生效。在构建容器时,会被 docker run 后面指定的参数覆盖 |
ENTRYPOINT argument | 和CMD相似,但是并不会被docker run指定的参数覆盖,而是追加参数 |
VOLUME | 将宿主机文件夹挂载到容器中 |
3.构建镜像
docker build [-f 指定Dockerfile所在路径与文件名] -t 生成的镜像名:标签名 .
AI 代码解读
注意后边的空格 和点 . 不要省略, . 表示当前目录 -f 指定Dockerfile文件所在路径与文件名。如果未指定 -f 值,则找当前目录下名为 Dockerfile 的构建文件。
可以在网上找个构建镜像的demo动动手,比如通过jdk压缩包,构建一个jdk镜像
AI 代码解读
#来自基础镜像
FROM centos:7
#指定镜像创建者信息
MAINTAINER Tara
#切换工作目录 /usr/local
WORKDIR /usr/local
#创建一个存放jdk的路径
RUN mkdir /usr/local/java
#将jdk压缩包复制并解压到容器中/usr/local/java
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]
AI 代码解读
docker build -t jdk:1.8 .
AI 代码解读
七、Docker本地镜像发布
这一章好像没啥说的,就是把本地的镜像发布到远程仓库,这里我们用的仓库还是阿里免费的镜像服务,登录阿里云,然后选择容器镜像服务,点击镜像仓库,创建完以后点击管理,里面会有详细的命令介绍。
AI 代码解读
八、自动化部署浅度实践
1.修改Docker配置
- 修改docker配置,使得外网可以访问docker服务
在 ExecStart= 后添加加配置 -H tcp://0.0.0.0:2375
vim /lib/systemd/system/docker.service
AI 代码解读
- 刷新配置,重启服务
systemctl daemon-reload
systemctl restart docker
AI 代码解读
- 验证是否生效,访问:http://服务器IP:2375/version , 响应如下内容则成功:
如果访问不上,确定一下自己的服务器防火墙是否关闭;如果使用的是阿里云服务器,确定一下安全组是否将2375端口开通
AI 代码解读
2.自动化部署
- 修改本地maven配置文件(setting.xml)
- 修改工程pom.xml
<build>
<finalName>app</finalName>
<plugins>
<!-- 插件一定要在其他构建插件之上,否则打包文件会有问题。 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- docker的maven插件,官网:https://github.com/spotify/docker-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<!--生成镜像相关配置-->
<configuration>
<!-- 将forceTags设为true,这样就会覆盖构建相同标签的镜像 -->
<forceTags>true</forceTags>
<!-- 远程 docker 宿主机地址, 端口号是/lib/systemd/system/docker.service所暴露的端口号, 生成镜像到docker中 -->
<dockerHost>http://47.94.215.233:2375</dockerHost>
<!--内容是之前修改的maven的settings.xml配置文件中,server节点的id-->
<serverId>docker-aliyun</serverId>
<!-- 镜像名:阿里云镜像仓库地址${project.artifactId}引用当前工程名,${project.version}引用当前工程版本号-->
<imageName>registry.cn-hangzhou.aliyuncs.com/tara_name_space/${project.artifactId}:${project.version}</imageName>
<!--基础镜像-->
<baseImage>java</baseImage>
<!--类似于Dockerfile的ENTRYPOINT指令-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<!-- 指定打包的资源文件 -->
<targetPath>/</targetPath>
<!-- 指定要复制的目录路径,这里是当前目录 -->
<directory>${project.build.directory}</directory>
<!--指定要复制的根目录,这里是target目录 -->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
AI 代码解读
- 执行打包推送命令
mvn clean package docker:build -DpushImage
mvn clean package 打包成jar ,然后docker:build构建成镜像,-DpushImage推送到仓库
AI 代码解读
拉取镜像,创建一下容器就可以用了,就这样。如果是微服务,多个工程的也是重复这个操作
AI 代码解读
总结:
Docker到这也就算基本入门了吧,基本的操作命令,使用以及相关语法规则和部署,还有很多用法,有兴趣的可以在网上或者买本书啥的,继续深入一下,配合k8s使用。
参考网站:
DockerHub:https://hub.docker.com/
Docker概念:https://www.jianshu.com/p/dc9677a751f5