Docker
Docker学习笔记,内容包括:Docker的安装,镜像操作、容器操作、数据卷操作,以及部署项目时需要用到的Dockerfile和DockerCompose
1.安装Docker
1.1.卸载旧版本
如果之前安装过旧版本的Docker,可以使用下面命令卸载:
1 | yum remove docker \ |
1.2.安装
首先需要大家虚拟机联网,安装yum工具
1 | yum install -y yum-utils \ |
然后更新本地镜像源:
1 | 设置docker镜像源 |
然后输入命令:
1 | yum install -y docker-ce |
docker-ce为社区免费版本。稍等片刻,docker即可安装成功。
1.3.启动docker
在学习过程中,如果是在虚拟机上可以直接关闭防火墙,避免后续频繁开放所需端口
而云服务器则需要一一开放对应端口
1 | # 关闭 |
通过命令启动docker:
1 | systemctl start docker # 启动docker服务 |
然后输入命令,可以查看docker版本:
1 | docker -v |
1.4.配置镜像加速
docker官方镜像仓库网速较差,我们需要设置国内镜像服务:
参考阿里云的镜像加速文档:容器镜像服务 (aliyun.com)
1 | sudo mkdir -p /etc/docker |
2.Docker的基本操作
2.1.镜像操作
拉取镜像
以nginx为例,首先去镜像仓库搜索nginx镜像,比如DockerHub、DockerHub国内镜像站点:
根据查看到的镜像名称,拉取自己需要的镜像
1 | docker pull nginx #拉取nginx |
查看镜像
1 | docker images #查看拉取到的镜像 |
保存镜像
根据docker save --help可以查看save命令的文档,其命令格式为:
1 | docker save -o [保存的目标文件名称] [镜像名称] |
保存的文件一般为一个tar格式的包,镜像名称则是 名称:标签的格式,所以保存这个nginx镜像可以执行以下命令
1 | docker save -o nginx.tar nginx:latest |
导入镜像
先删除本地的nginx镜像:
1 | docker rmi nginx:latest |
然后运行命令,加载本地文件:
1 | docker load -i nginx.tar |
结果:
2.2.容器操作
相关命令
1 | docker run #创建并运行一个容器,处于运行状态 |
创建并运行一个容器
创建并运行nginx容器的命令:
1 | docker run --name containerName -p 80:80 -d nginx |
命令解读:
- docker run :创建并运行一个容器
- –name : 给容器起一个名字,比如叫做mn
- -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
- -d:后台运行容器
- nginx:镜像名称,例如nginx
**启动容器后,访问虚拟机ip的80端口,可以看到nginx已经成功运行 ↓↓↓ **
2.3.数据卷(容器数据管理)
在之前的nginx案例中,如果需要修改nginx的html页面,需要进入nginx内部。并且因为没有编辑器,修改文件也很麻烦。要解决这个问题,必须将数据与容器解耦,这就要用到数据卷了。
数据卷(volume)是一个虚拟目录,指向宿主机文件系统中的某个目录。
一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
这样,我们操作宿主机的/var/lib/docker/volumes/html目录,就等于操作容器内的/usr/share/nginx/html目录了
数据卷操作命令
数据卷操作的基本语法如下:
1 | docker volume [COMMAND] |
docker volume命令是数据卷操作,根据命令后跟随的command来确定下一步的操作:
- docker volume create:创建数据卷
- docker volume ls:查看所有数据卷
- docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
- docker volume rm:删除指定数据卷
- docker volume prune:删除所有未使用的数据卷
创建和查看数据卷
需求:创建一个数据卷,并查看数据卷在宿主机的目录位置
① 创建数据卷
1 | docker volume create html |
② 查看所有数据
1 | docker volume ls |
③ 查看数据卷详细信息卷
1 | docker volume inspect html |
结果:
可以看到,我们创建的html这个数据卷关联的宿主机目录为/var/lib/docker/volumes/html/_data目录。
挂载数据卷
我们在运行容器时,可以通过 -v 参数来挂载一个数据卷到某个容器内目录,命令格式如下:
1 | docker run \ |
这里的-v就是挂载数据卷的命令:
-v html:/root/htm:把html数据卷挂载到容器内的/root/html这个目录中
案例-给nginx挂载数据卷
① 创建容器并运行容器,同时挂载数据卷到容器内的HTML目录
1 | docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx |
② 进入html数据卷所在位置,并修改HTML内容
1 | # 查看html数据卷的位置 |
案例-给mysql挂载数据卷
①拉取mysql
1 | docker pull mysql |
②创建目录/tmp/mysql/data
1 | mkdir /tmp/mysql/data |
③创建目录/tmp/mysql/conf,上传自定义配置hmy.cnf
1 | mkdir /tmp/mysql/conf |
④去DockerHub查阅资料,创建并运行MySQL容器,要求:
挂载/tmp/mysql/data到mysql容器内数据存储目录
挂载/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
设置MySQL密码
1 | docker run \ |
3.Dockerfile自定义镜像
常见的镜像在DockerHub就能找到,但是我们自己写的项目就必须自己构建镜像了。要构建镜像,其实就是实现打包的过程。
Dockerfile语法
构建自定义的镜像时,并不需要一个个文件去拷贝,打包。
我们只需要通过Dockerfile文件告诉Docker,我们的镜像的组成,需要哪些BaseImage、需要拷贝什么文件、需要安装什么依赖、启动脚本是什么,将来Docker会帮助我们构建镜像。
案例-构建Java项目
实现思路如下:
① 新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
② 将打包好的java项目docker-demo.jar放到到这个目录中
③ 编写Dockerfile文件:
a )基于java:8-alpine作为基础镜像
b )将app.jar拷贝到镜像中
c )暴露端口
d )编写入口ENTRYPOINT
内容如下:
1
2
3
4FROM java:8-alpine
COPY ./docker-demo.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar
④ 在该目录下使用docker build命令构建镜像
- -t 指 tag,也就是给镜像命名,这里名为javaweb:1.0
- . 注意最后有一个“ . ”,也可以是 ./ ,代表build当前目录
1 | docker build -t javaweb:1.0 . |
⑤ 使用docker run创建容器并运行
1 | docker run --name web -p 8090:8090 -d javaweb:1.0 |
⑥ 测试
浏览器打开访问该项目的/hello/count,可以看到项目已经正常运行,可以正常访问了
案例2
1 | FROM maven:3.8.1-jdk-8-slim as builder |
4.DockerCompose
4.1.认识DockerCompose
其实DockerCompose文件可以看做是将多个docker run命令写到一个文件,通过docker-compose up -d一键启动,只是语法稍有差异
Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。格式如下:
1 | version: "3.8" |
上面的Compose文件就描述一个项目,其中包含两个容器:
- mysql:一个基于
mysql:5.7.25镜像构建的容器,并且挂载了两个目录 - web:一个基于
docker build临时构建的镜像容器,映射端口时8090
4.2.安装DockerCompose
安装
1 | # 安装 |
修改文件权限
1 | # 修改权限 |
Base自动补全命令
1 | # 补全命令 |
如果这里出现错误,需要修改自己的hosts文件:
1 | echo "199.232.68.133 raw.githubusercontent.com" >> /etc/hosts |
4.3.案例-部署微服务
准备部署目录及docker-compose
以上一篇文章中的cloud案例为例,创建一个文件夹,编写docker-compose.yml文件,为每一个微服务准备一个独立的目录
内容如下:
1 | version: "3.2" |
修改微服务配置
因为微服务将来要部署为docker容器,而容器之间互联不是通过IP地址,而是通过容器名。这里我们将order-service、user-service、gateway服务的mysql、nacos地址都修改为基于容器名的访问。
如下所示:
1 | spring: |
打包
接下来需要将我们的每个微服务都打包。因为之前查看到Dockerfile中的jar包名称都是app.jar,因此我们的每个微服务都需要用这个名称。
可以通过修改pom.xml中的打包名称来实现,每个微服务都需要修改:
1 | <build> |
拷贝jar包到部署目录
编译打包好的app.jar文件,需要放到Dockerfile的同级目录中。注意:每个微服务的app.jar放到与服务名称对应的目录。
部署
最后,我们需要将文件整个cloud-demo文件夹上传到虚拟机中,理由DockerCompose部署。
进入cloud-demo目录,然后运行下面的命令:
1 | docker-compose up -d |
根据查看日志发现,由于nacos启动速度慢,而其他服务依赖于nacos,所以需要重启一次其他服务
1 | docker-compose logs -f |
1 | docker-compose restart gateway userservice orderservice |
重启后访问正常: