Docker基础学习笔记
一、Docker:
Docker是一个开源的应用容器引擎,可以用于创建、部署和运行应用程序。
二、Docker与传统虚拟机:
1、Docker与传统虚拟化方式的不同之处:
(1)、传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
(2)、容器相较于传统虚拟机技术区别在于,容器内的应用进程是直接运行于宿主的操作系统内核,容器内没有自己的内核,也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。但是由于容器与宿主机共享内核,所以在隔离性和安全性方面不如虚拟机。
2、Docker的优势:
优势 |
说明 |
高效资源利用率 |
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。 |
轻量级和快速启动 |
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。 |
环境一致性 |
Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。这消除了“在我机器上能够运行”的问题,简化了开发、测试和部署过程。 |
跨平台和可移植性 |
由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。 |
高度可扩展性 |
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。 |
简化部署与管理 |
Docker提供了方便易用的工具和API,可以自动化构建、部署和管理容器。可以使用Docker Compose或Docker Swarm来编排和管理多个容器,简化了应用程序的部署和维护过程 |
综上所述,Docker可以使得开发人员和系统管理员能够更高效地构建、部署和运行应用程序。
三、Docker的安装:
四、Docker的架构:
1、Docker客户端(Docker Client):
用户与Docker交互的主要方式,可以通过命令行或者API向Docker守护进程发送请求。Docker客户端将用户的操作请求转发给Docker守护进程,并显示执行结果。
2、Docker镜像(Docker Image):
Docker镜像是用于创建Docker容器的模板,包含了文件系统、运行时环境和系统工具等。它可以看作是容器的“原型”。
因为镜像包含操作系统完整的ROOT文件系统,其体积往往是庞大的,因此在Docker设计时,就充分利用Union FS的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
3、Docker容器(Docker Container):
Docker容器是Docker镜像的运行实例,每个容器都是相互独立的、拥有互相隔离的运行环境,而同一个Docker镜像可以创建并运行多个相互隔离的容器。
镜像(Image)和容器(Container)的关系类似于面对对象程序设计中类与实例的关系或者是程序与进程的关系,其中镜像是静态的,而容器是动态的。容器包含了应用程序及其依赖的所有内容,有其自己的生命周期,所以容器是可以删除的,容器被删除后其镜像是不会被删除。
每一个容器运行时,会在当前容器创建一个存储层,容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。按照 Docker最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所以需要将数据存储到容器之外,这样删除容器也不会丢失数据。一旦容器故障,我们可以重新创建一个容器,将数据挂载到容器里,就可以快速的恢复。
4、Docker仓库(Docker Registry):
Docker镜像可以保存在Registry仓库中,供用户下载使用。仓库可分为公共与私有仓库,Docker Hub是最常用的公共仓库,Docker命令默认从Docker Hub中拉取镜像。私有仓库除了官方的Docker Registry外,还有第三方软件实现了Docker Registry API,甚至提供了用户界面以及一些高级功能。比如Harbor和Sonatype Nexus。
五、Docker常用命令:
1、启动Docker:
systemctl start docker
2、停止Docker:
systemctl stop docker
3、重启Docker:
systemctl restart docker
4、查看Docker状态:
systemctl status docker
5、开机自启动Docker:
systemctl enable docker
6、查看Docker系统信息,包括镜像和容器数:
docker info
7、查看Docker版本:
docker -v
8、查看Docker帮助文档:
docker --help
六、Docker Hub公共仓库访问:
Docker Hub是最常用的公共仓库,Docker命令默认从Docker Hub中拉取镜像。
访问地址:https://hub-stage.docker.com/
七、Image镜像基本操作:
Docker镜像是用于创建Docker容器的模板,Docker在运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker会从镜像仓库中下载该镜像。
1、拉取镜像:
docker pull [选项] [Registry地址[:端口号]/]镜像名[:Tags标签] |
|
选项 |
说明 |
-a |
下载仓库所有镜像 |
--disable-content-trust |
忽略镜像的校验,默认开启 |
--platform |
设置镜像所属平台, 如果有多个镜像服务 |
实例 |
|
docker pull nginx |
不写默认是latest,一般不建议使用latest,因为最新的镜像是滚动更新的 |
docker pull nginx:1.22 |
指定镜像Tags |
Docker pull xxx.xxx.x.xxx:5000/centos:7 |
从指定镜像仓库拉取镜像,不写默认地址是Docker Hub |
docker pull --platform=arm64|amd64... image_name |
用于获取指定编译平台的镜像 |
2、查看镜像列表:
docker images [选项] 镜像名[:Tags标签] |
|
选项 |
说明 |
-a |
列出本地所有的镜像(含中间层镜像,默认情况下是过滤掉中间映像层) |
--digests |
显示镜像的摘要信息 |
-f |
显示满足条件的镜像 |
--format |
指定返回值的模板文件 |
--no-trunc |
显示完整的镜像信息 |
-q |
只显示镜像ID |
实例 |
|
docker images |
列出所有顶层镜像,不包含中间层镜像 |
docker images -a |
列出所有的镜像,包含中间层镜像 |
docker images -f since=nginx:1.25.0 |
使用过滤器来列出虚悬镜像,(since:查询在nginx:1.25.0之后建立的镜像,可用函数before,LABEL等) |
docker images -q nginx |
显示nginx镜像ID |
docker images --format "table {{.ID}}\t{{.Repository}}" |
格式化展示 |
备注:
虚悬镜像(dangling image):仓库名、标签均为<none>的无标签镜像,由于镜像名被转移到了新下载的镜像身上,而旧的镜像上的这个名称则被取消导致(IMAGE ID镜像唯一标识,一个镜像可以对应多个Tags标签);
3、查看指定镜像创建历史:
docker history [选项] 镜像 |
|
选项 |
说明 |
-H |
以可读的格式打印镜像大小和日期,默认开启 |
--no-trunc |
显示完整的提交记录 |
-q |
仅列出提交记录ID |
实例 |
|
docker history nginx |
|
4、删除本地镜像:
操作 |
说明 |
docker rmi 镜像 |
删除指定的镜像(没有容器使用该镜像才能成功删除) |
docker rmi $(docker images -q) |
删除所有镜像(没有容器使用该镜像才能成功删除) |
docker rmi -f 镜像 |
强制删除指定镜像(无论有无使用该镜像) |
docker image prune |
删除虚悬镜像(没有标签和没有被任何容器引用的镜像) |
docker image prune -a |
删除所有未被容器使用的镜像 |
实例 |
|
docker rmi -f nginx |
|
5、查看镜像的元信息数据:
docker inspect [选项] 镜像 |
|
选项 |
说明 |
-f |
指定返回值的模板文件 |
-s |
显示总的文件大小 |
--type |
为指定类型返回JSON |
八、Container容器基本操作:
Docker容器是Docker镜像的运行实例。镜像(Image)和容器(Container)的关系类似于面对对象程序设计中类与实例的关系或者是程序与进程的关系,其中镜像是静态的,而容器是动态的。容器包含了应用程序及其依赖的所有内容,有其自己的生命周期。
1、创建容器并运行:
docker run [选项] IMAGE [COMMAND] [ARG...] |
|
选项 |
说明 |
-d |
后台运行容器,并返回容器ID |
-it |
以交互模式运行容器,并分配一个伪输入终端 |
--name |
为容器指定一个名称 |
-p |
指定端口映射,格式为:主机(宿主)端口:容器端口 |
-e |
设置环境变量 |
-v |
绑定存储卷 |
--rm |
在容器退出时自动删除容器。一般在使用客户端程序时使用此参数(--rm选项不能与-d同时使用) |
--restart 1、--restart=no 2、--restart=always 3、--restart=on-failure 4、--restart=unless-stopped |
指定容器的重启策略: 1、默认选项,表示容器退出时不会自动重启。 2、表示容器无论在何种情况下都会自动重启。 3、表示只有在非0状态码退出的情况下才会自动重启容器。 4、表示除非手动停止容器,否则容器会在各种退出情况下都会自动重启。 |
实例 |
|
#后台启动,定义容器名为demo01,设置自动启动,端口映射到8080端口 docker run -d --name demo01 --restart always -p 80:8080 nginx:latest #交互模式启动一个容器,在容器内执行/bin/bash命令(进入伪终端),使用exit退出 docker run -it nginx:latest /bin/bash #交互模式运行容器,在容器退出时自动删除容器 docker run -it --rm nginx:latest |
2、创建容器但不启动:
docker create [选项] IMAGE |
说明 |
创建一个容器但不启动(可用选项参考run命令),返回容器ID |
实例 |
#创建一个容器但不启动(可用选项参考run命令),返回容器ID docker create --name demo01 nginx:latest |
3、启动已创建的(已停止)容器:
docker start [选项] CONTAINER【容器名或容器ID】 |
说明 |
启动一个或多个已经被停止(即未启动)的容器 |
实例 |
docker start 65d4a94f7a39 docker container start 65d4a94f7a39 |
4、停止运行中容器(释放/不释放资源方式):
用于完全停止容器的运行并释放资源 |
docker stop [选项] CONTAINER |
用于暂时挂起容器内的所有活动,保留其状态但不释放资源 |
docker pause CONTAINER #挂起容器进程 docker unpause CONTAINER #恢复容器进程 |
实例 |
docker stop 65d4a94f7a39 docker container stop 65d4a94f7a39 |
5、重启容器:
docker restart [选项] CONTAINER |
实例 |
docker restart 65d4a94f7a39 docker container restart 65d4a94f7a39 |
6、查看容器:
docker ps [选项] |
|
选项 |
说明 |
-a |
显示所有的容器,包括未运行的 |
-q |
只显示容器编号 |
-n |
列出最近创建的n个容器 |
实例 |
|
#列出运行中容器 docker ps docker container ls #显示所有的容器,包括未运行的(即包括创建的容器) docker ps –a #列出所有运行的容器ID docker ps -q #列出最近创建的5个容器信息 docker ps -n 5 |
7、删除容器:
docker rm [选项] CONTAINER |
|
选项 |
说明 |
-f |
通过 SIGKILL 信号强制删除一个运行中的容器 |
-v |
删除与容器关联的卷 |
实例 |
|
#删除未运行的指定容器(若该容器运行中则删除失败) docker rm 65d4a94f7a39 #删除所有已经停止的容器(若存在容器运行中则删除失败) docker rm $(docker ps -a -q) #强制删除容器(包括运行的容器,创建的容器) docker rm -f 65d4a94f7a39 #删除未运行的容器, 并删除容器挂载的数据卷 docker rm -v 65d4a94f7a39 |
备注:
#容器是一个进程,可采用kill命令删除,杀掉运行中的容器
#docker kill [OPTIONS] CONTAINER
docker kill -s KILL 65d4a94f7a39
8、查看容器的元信息数据:
docker inspect [选项] 容器 |
|
选项 |
说明 |
-f |
指定返回值的模板文件 |
-s |
显示总的文件大小 |
--type |
为指定类型返回JSON |
9、查看容器中运行的进程信息:
docker top [选项] CONTAINER |
说明 |
支持ps命令参数 |
10、查看容器日志:
docker日志文件通常存储在/var/lib/docker/containers/{container_id}/下面,以json.log结尾的文件中
docker logs [OPTIONS] CONTAINER |
|
选项 |
说明 |
-f |
跟踪日志输出 |
--since |
显示某个开始时间的所有日志 |
-t |
显示时间戳 |
--tail |
仅列出最新N条容器日志 |
实例 |
|
docker logs --since="2023-11-01" --tail=10 demo01 |
11、容器与宿主机间的数据拷贝:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH |
说明 |
docker cp 容器ID:容器内路径 目的主机路径 docker cp 主机路径 目的容器ID:容器内路径 |
实例 |
#将宿主机./some_file目录拷贝到容器65d4a94f7a39的/work目录下 docker cp ./some_file 65d4a94f7a39:/work #将容器65d4a94f7a39的/var/logs/目录拷贝到宿主机的/tmp/app_logs目录中 docker cp 65d4a94f7a39:/var/logs/ /tmp/app_logs |
12、查看容器资源的使用情况:
docker stats [选项] [CONTAINER...] |
|
选项 |
说明 |
-a |
显示所有的容器,包括未运行的 |
--no-stream |
展示当前状态就直接退出了,不再实时更新 |
--format |
指定返回值的模板文件 |
13、容器导入与导出:
导出容器 |
docker export 容器ID > (可以添加目录)文件名.tar |
导入容器 |
cat (可以添加目录)文件名.tar | docker import - 镜像用户/镜像名:镜像版本号 |
实例 |
docker export 7691a814370e > ubuntu.tar cat ubuntu.tar | docker import - test/ubuntu:v1.0 |
14、容器伪终端交互:
方式一:创建容器并进入伪终端 |
docker run -it 镜像:Tags标签 /bin/bash |
方式二:attach命令(不推荐) |
docker attach 容器ID/容器name #由于进入容器后,交互键盘出错,执行exit命令后,容器消失,所以不建议使用 #可携带--sig-proxy=false来确保CTRL-D或CTRL-C不会关闭容器 |
方式三:exec命令(推荐) |
docker exec -it 容器ID或容器名 /bin/bash #-d:采用分离模式,在后台运行 #-i:保持STDIN 打开 #-t:分配一个伪终端 |
九、Docker容器存储管理:
Docker设计时,就充分利用Union FS的技术,将整体设计为分层存储的架构。每一个容器运行时,会根据分层机制在当前容器的最顶层创建一个存储层,为了保护下面每一层的镜像不被修改,所以才有CopyOnWrite的特性。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。在某些特殊情况下,我们可能希望对容器内的某些文件进行持久化存储,而不是一次性的,这里就有必要进行相应的容器存储管理。
1、Tmpfs Mount临时挂载:
Tmpfs Mount临时挂载仅存储在主机系统的内存中,从不写入宿主机的文件系统中。当容器停止时,数据将被删除
# /tmp是Linux下的临时文件夹
docker run -d -it --tmpfs /tmp nginx:latest
2、Bind Mount挂载主机目录:
Bind Mount绑定挂载可以将宿主机文件系统上的目录或文件装载到容器中,但是宿主机上非Docker的所有进程都可以修改它们,同时在容器中也可以更改主机文件系统,包括创建、修改或删除文件或目录。(Docker挂载主机目录的默认权限是读写,用户也可以通过增加 readonly指定为只读)
说明 |
#方式一:使用--mount参数挂载时如果本地目录不存在,Docker 会报错 --mount type=bind,source=宿主机源文件,target=容器目标文件 IMAGE |
#方式一:使用-v参数挂载时如果本地目录不存在,Docker会自动创建一个文件夹 -v宿主机源文件:容器目标文件 IMAGE |
实例 |
# \字符表示换行 docker run –d \ --name demo01 \ # -v /src/webapp:/opt/webapp \ #--mount type=bind,source=/src/webapp,target=/opt/webapp \ # readonly指定挂载文件的权限为只读 --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \ image_name |
3、Volume数据卷(推荐使用):
Volume数据卷存储在主机文件系统分配一块专有存储区域,由Docker(在Linux 上)管理,并且与主机的核心功能隔离。非Docker的所有进程不能修改文件系统的这一部分。卷是在Docker中持久化保存数据的最佳方式,数据卷默认会一直存在,它的生命周期独立于容器,即使容器被删除或重启,数据也不会丢失。(卷可以在多个容器之间的数据共享与重用,仅显式删除卷时,才会进行删除卷)
#创建数据卷my-volume: docker volume create my-volume
#查看所有数据卷: docker volume ls
#查看指定my-volume数据卷信息: docker volume inspect my-volume
#启动一个挂载数据卷的容器:(\字符表示换行) docker run –d \ --name demo01 \ #使用-v参数挂载时如果数据卷不存在,Docker会自动创建一个数据卷 # -v my-volume:/opt/webapp \ #使用--mount参数挂载时如果数据卷不存在,Docker会报错 #--mount type=bind,source=my-volume,target=/opt/webapp \ # readonly指定挂载文件的权限为只读 --mount type=bind,source=my-volume,target=/opt/webapp,readonly \ image_name
#查看容器的元信息数据(数据卷信息在 “Mounts” Key下面): docker inspect demo01
#删除数据卷: docker volume rm my-volume
#删除未运行的容器, 并删除容器挂载的数据卷: docker rm -v 65d4a94f7a39
十、Docker网络管理:
Docker网络是Docker容器与容器之间和容器与外部网络之间的通信和连接的一种机制。在Docker中,每个容器都可以有自己的网络栈,包括网络接口、IP地址和网络配置。由于容器之间只能通过IP地址相互访问,容器的IP会随着启动顺序发生变化,故Docker网络提供了一种灵活且可定制的方式,使得容器之间可以相互通信,并与主机或其他网络资源进行交互。
1、网络模式:
通过docker network ls命令查看所有网络 |
|
bridge网络模式 |
|
说明 |
如果不显式指定网络模式,默认情况下,容器会使用bridge网络模式。在bridge网络模式下,宿主机会虚拟一个docker0虚拟网桥(在内核层连通了其他的物理或虚拟网卡,将所有容器和本地主机都放到同一个物理网络中),Docker启动一个容器时会根据docker0网桥的网段分配给容器一个IP地址,容器可以通过该网桥与宿主机或其他容器进行通信(即,宿主机可以PING通容器IP,容器中也能PING通宿主机,外部网络可以通过宿主机的IP地址和映射的端口来访问容器内的服务)。 由于容器的IP会随着启动顺序发生变化,这意味着如果先启动的容器被停止或删除,后续启动的容器可能会获得先前已释放的IP地址,因此,不推荐容器之间使用IP进行相互访问,如果对容器的IP地址有特定的依赖或需求,建议使用静态IP地址,即可通过创建自定义网络并手动分配IP地址来实现。 |
操作 |
#查看bridge网络的具体信息 docker network inspect bridge #查看docker0网桥的详细信息 ip addr show docker0 #启动容器采用端口映射,未指定network,默认使用的bridge网桥模式 docker run -d --name demo01 -p 宿主机端口:容器端口 镜像 |
host网络模式 |
|
说明 |
在Host网络模式下,容器与宿主机共享Network Namespace网络命名空间,容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口(-p端口映射选项会被忽略)。如果宿主机和容器同时安装相同服务,并监听相同的端口,那么访问该端口时将优先访问宿主机上的服务,容器内部的服务将不会被访问到。要访问容器内部的服务,则需要停止宿主机上的相关服务,或者使用不同的端口避免冲突。 |
操作 |
#启动容器,指定host网络模式 docker run -d --name demo01 --net host 镜像 #查看host网络的具体信息 docker network inspect host |
Container网络模式 |
|
说明 |
新建的容器和已经存在的一个容器共享一个网络IP配置而不是和宿主机共享(端口由容器内部区别)。两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。 |
操作 |
#启动容器,指定Container网络模式,指定共享网络的容器 docker run -d --name demo01 --net container:已运行的容器名称|ID 镜像 |
none网络模式 |
|
说明 |
在none模式下,并不为Docker容器进行任何网络配置,禁用网络功能,只有lo标识(环回地址:127.0.0.1),容器将处于隔离状态,仅能通过进程间通信(IPC)和文件系统共享与宿主机进行通信。由于容器没有网络连接,所以无法自定义网络,如果需要自定义网络配置,可以考虑使用其他网络模式。 |
操作 |
#启动容器,指定none网络模式,禁用容器网络功能,处于隔离状态 docker run -d --name demo01 --net none 镜像 |
2、自定义网络(容器互联):
在bridge网络模式下,由于容器的IP会随着启动顺序发生变化,这意味着如果先启动的容器被停止或删除,后续启动的容器可能会获得先前已释放的IP地址,因此,不推荐容器之间使用IP进行相互访问,如果对容器的IP地址有特定的依赖或需求,建议使用静态IP地址,即可通过创建自定义网络并手动分配IP地址来实现。
#创建一个新的网络(bridge网络模式) docker network create 网络名称 #列出所有网络 docker network ls #查看创建网络的详情 docker network inspect 网络名称 #查看容器的网络信息,NetworkSettings节点 docker inspect 容器名称|ID #方式一:创建容器时指定自定义网络 docker run -d --name my_container --network=网络名称 镜像|ID #方式二:已有容器连接到自定义网络 docker network connect 网络名称 容器名称|ID #使用相同自定义网络的容器可采用容器名进行相互访问(容器内) ping 容器名 #断开自定义网络 docker network disconnect 网络名称 容器名称 #删除网络 docker network rm 网络名称
#删除所有未使用的网络 docker network prune
十一、私有仓库:
Docker私有仓库为组织和个人提供了更高的安全性、版本控制、性能和自定义构建等优势。
1、Docker-Registry私有仓库:
Docker Registry私有仓库是Docker提供的基本镜像仓库解决方案。
2、Harbor私有仓库:
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源DockerDistribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全,同时其还提供了管理图形界面,原生地支持中文,极大提升用户使用Registry构建和运行环境传输镜像的效率。Harbor的每个组件都是以Docker容器的形式构建的,可以使用DockerCompose容器编排来进行部署,同时Harbor也提供了Kubernetes的相关配置文件。
3、Nexus私有仓库:
Nexus号称是世界上最流行的仓库管理软件,Nuexu3能够支持Maven、npm、Docker、YUM、Helm等格式数据的存储和发布,并且能够与Jekins、SonaQube和IDEA等工具进行集成。Nexus3支持作为宿主和代理存储库的Docker存储库,可以直接将这些存储库暴露给客户端工具;也可以以存储库组的方式暴露给客户端工具,存储库组是合并了多个存储库的内容的存储库,能够通过一个URL将多个存储库暴露给客户端工具,从而便于用户的使用。通过Nexus3自建能够有效减少访问获取镜像的时间和对带宽的使用,并能够通过自有的镜像仓库共享企业自己的镜像。
(1)、安装:
#宿主机新建一个目录用于存储nexus3数据 /data/nexus-data #启动nexus3容器 # 8081:web管理界面的默认端口 # 6660:自定义此端口号用于使用docker账号进行推送push与下载pull #挂载本地目录到容器内部目录: /data/nexus-data docker run -d \ --name nexus3 \ --restart=always \ -p 6660:6660 \ -p 6661:8081 \ -v /data/nexus-data:/var/nexus-data \ sonatype/nexus3 #查看启动日志: docker logs -f nexus3 #访问nexus3网页端: http://宿主机IP:6661 #进入容器,查看登入密码 docker exec -it nexus3 /bin/bash cat /nexus-data/admin.password
注:
1)、如下启动日志,表示启动成功:
2)、如下表示磁盘空间不足:
解决方案:
#新建一个data目录(赋予对应权限) mkdir data #拷贝nexus配置文件: docker cp nexus3:/opt/sonatype/nexus/bin/nexus.vmoptions /data #添加扩容声明,如果要改成2048M,则:-Dstorage.diskCache.diskFreeSpaceLimit=2048 vim /data/nexus.vmoptions #本地修改完了再拷回 docker cp /data/nexus.vmoptions nexus3:/opt/sonatype/nexus/bin/nexus.vmoptions #重启容器nexus3 docker container restart nexus3
(2)、推送本地镜像到Nexus私有仓库:
1)、仓库说明:
Docker仓库 |
备注 |
docker(group) |
仓库组,用来合并多个hosted私有仓库和proxy代理的组,只能pull |
docker(hosted) |
私有仓库,可以pull和push |
docker(proxy) |
代理远程公共仓库,只能pull |
2)、创建docker(hosted)私有仓库:
3)、Docker添加信任仓库地址:
由于docker不允许非https推送镜像,所以需要配置一下,不然无法推送拉取以及登录
#打开配置 vi /etc/docker/daemon.json #添加仓库地址配置:(宿主机IP:用于推送与下载的仓库http端口) "insecure-registries": ["192.168.1.119:6660"]
4)、重启docker:
systemctl daemon-reload
systemctl restart docker
5)、docker登入nexus:
docker login -u admin -p <密码> <宿主机IP>:6660
6)、镜像上传与下载:
#对需要上传的镜像打成标签 #docker tag 原镜像名称:版本 仓库主机IP:6660/新镜像名字:版本号 docker tag nginx:latest 192.168.1.119:6660/new-nginx:v1 #上传 #docker push 仓库主机IP:6660/新镜像名字:版本号 docker push 192.168.1.119:6660/new-nginx:v1 #下载 #docker pull 仓库主机IP:6660/新镜像名字:版本号 docker pull 192.168.1.119:6660/new-nginx:v1
(3)、参考:
搭建Nexus私有仓库参考:
4、基于Nexus3作为Maven私服:
Nexus自带的仓库中有两个hosted仓库,分别是snapshot快照库和release发布库
(1)、Nexus仓库配置:
1)、创建Blob Stores存储媒介:
Nexus以Blob格式存储。Blob Stores可以被一个或者多个仓库或者仓库组使用。默认的Blob Stores是基于文件系统的,可以简单的理解为服务器上的一个目录。
2)、创建maven2 (hosted)类型的SNAPSHOT快照库:
http://nexus-ip:port/repository/maven-snapshots-my/
3)、创建maven2 (hosted)类型的RELEASE发布库:
http://nexus-ip:port/repository/maven-releases-my/
4)、创建maven2 (proxy)类型的proxy代理库:
http://nexus-ip:port/repository/maven-proxy-aliyun/
5)、创建maven2 (group)类型的group聚合库:
对用户暴露统一的地址。当用户需要获取某一个依赖包时,请求的是仓库组的地址,系统将会根据仓库组配置的仓库顺序从上到下依次查找。
http://nexus-ip:port/repository/maven-public-my/
(2)、Maven相关setting.xml配置:
1)、配置访问私有仓库的用户名密码:
<server> <id>标签名</id> <username>admin</username> <password>密码</password> </server>
2)、镜像配置:
Maven对于任何构件的下载请求都会被拦截跳转到 Nexus 私服中,可以将镜像替换为阿里云。
<mirrors> <mirror> <id>用户信息标签id</id> <name>自定义名</name> <mirrorOf>*</mirrorOf> <url>http://nexus-ip:port/repository/maven-public-my/</url> </mirror> </mirrors>
3)、Nexus仓库拉取配置:
<profiles> <profile> <id>central</id> <repositories> <repository> <id>central</id> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> <profile> <id>my-nexus-maven-releases</id> <repositories> <repository> <!--配置<server>的id 声明账号信息--> <id>my-nexus-maven-releases</id> <!-- 配置的插件仓库的地址 --> <url>http://nexus-ip:port/repository/maven-releases-my/</url> <!-- 是否开启该插件仓库的 release 版本下载支持 --> <releases> <enabled>true</enabled> </releases> <!-- 是否开启该插件仓库的 snapshot 版本下载支持 --> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> <profile> <id>my-nexus-maven-snapshots</id> <repositories> <repository> <!--配置<server>的id 声明账号信息--> <id>my-nexus-maven-snapshots</id> <!-- 配置的插件仓库的地址 --> <url>http://nexus-ip:port/repository/maven-snapshots-my/</url> <!-- 是否开启该插件仓库的 release 版本下载支持 --> <releases> <enabled>true</enabled> </releases> <!-- 是否开启该插件仓库的 snapshot 版本下载支持 --> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> </snapshots> </repository> </repositories> </profile> </profiles> <!--激活相关依赖配置--> <activeProfiles> <activeProfile>my-nexus-maven-releases</activeProfile> <activeProfile>my-nexus-maven-snapshots</activeProfile> <activeProfile>central</activeProfile> </activeProfiles>
(3)、POM配置:
<distributionManagement> <!--正式版本--> <repository> <!-- settings.xml中配置<server>的id --> <id>my-nexus</id> <url>http://nexus-ip:port/repository/maven-releases-my/</url> </repository> <!--快照版本--> <snapshotRepository> <!-- settings.xml中配置<server>的id --> <id>my-nexus</id> <url>http://nexus-ip:port/repository/maven-snapshots-my/</url> </snapshotRepository> </distributionManagement>
(4)、基于Nexus3作为Maven私服相关参考:
备注:
Maven将JAR文件上传至本地仓库及私服
基础命令 |
# \字符表示换行 mvn deploy:deploy-file \ -DgroupId=com.example \ -DartifactId=my-artifact \ -Dversion=1.0 \ -Dpackaging=jar \ -Dfile=/path/to/my-artifact-1.0.jar \ -Durl=https://your.private.repo.com/repository/maven-releases/ \ -DrepositoryId=private-repo |
参数说明 |
mvn deploy:deploy-file:maven版本发布命令 -DgroupId:相关groupId名称 -DartifactId:相关artifactId名称 -Dversion:相关版本号 -Dpackaging:打包方式,一般为jar -Dfile:上传源文件路径,这里可以写绝对路径 -Durl:私服的地址 -DrepositoryId:setting.xml配置server私服地址的id |
十二、Dockerfile定制镜像:
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
1、Dockerfile基础指令详解:
2、Dockerfile构建SpringBoot项目:
(1)、SpringBoot项目运行maven.install生成JAR包
(2)、Linux创建相关目录:
上传JAR包,当前JAR名为:pagehelperdemo.jar
(3)、Dockerfile编写:
1)、在JAR同级目录下编写Dockerfile文件
2)、执行命令:
vim Dockerfile
3)、输入内容:
FROM openjdk:8 VOLUME /opt/install/data/demo01/data ADD pagehelperdemo.jar pagehelperdemo.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/pagehelperdemo.jar"]
(4)、定制JAR镜像:
#定制JAR镜像, #docker build -t <镜像名称>:<标签> <Dockerfile路径> #-t代表要构建的镜像的tag,“.”代表当前目录,也就是Dockerfile所在的目录 docker build -t pagehelperdemo . #创建容器并启动, docker run -d -p <映射端口>:<SpringBoot服务端口> --name pagehelperdemo #查看启动日志 docker logs -f pagehelperdemo
(5)、采用shell脚本定制镜像方式:
1)、同级目录下添加service-config.properties基础声明配置:
执行命令 |
vim service-config.properties |
输入内容 |
#自定义docker镜像/容器名,建议直接使用JAR名 SERVER_NAME=pagehelperdemo #服务端口 SERVER_PORT=8888 #私有仓库名地址(Nexus) DOCKREPOSITORY_URL=192.110.120.130:6666/ |
赋予文件相关权限
chmod +x service-config.properties
2)、同级目录下添加makeServiceAndRestart.sh启动定制镜像脚本配置:
执行命令 |
vim makeServiceAndRestart.sh |
输入内容 |
#执行以下指定的脚本文件 |
#执行指定的脚本文件 source ./service-config.properties #Dockerfile存放路径,当前脚本与Dockerfile存放路径一致 BASE_PATH=$PWD #自定义docker镜像/容器名,建议直接使用JAR名 VERSION=`date +%Y%m%d-%H%M%S`.SNAPSHOT #镜像名 BUILD_IMAGE_NAME=${DOCKREPOSITORY_URL}${SERVER_NAME}:${VERSION} #容器名 BUILD_NAME=${SERVER_NAME} #容器id CID=$(docker ps | grep "$BUILD_NAME" | awk '{print $1}') #镜像id IID=$(docker images | grep "$BUILD_NAME" | awk '{print $3}') #主机端口号 HOST_PORT=$SERVER_PORT #容器端口号 C_PORT=$SERVER_PORT #时间 DATE=`date +%Y%m%d%H%M` function build(){ #判断镜像是否存在 if [ -n "$IID" ]; then echo "存在$BUILD_IMAGE_NAME镜像,IID=$IID,删除镜像" docker rmi $IID cd $BASE_PATH docker build -t $BUILD_IMAGE_NAME . echo "$BUILD_IMAGE_NAME镜像重新构建完成" docker images $BUILD_IMAGE_NAME echo "上传$BUILD_IMAGE_NAME镜像到私有仓库" docker push $BUILD_IMAGE_NAME else echo "不存在$BUILD_IMAGE_NAME镜像,开始构建镜像" cd $BASE_PATH docker build -t $BUILD_IMAGE_NAME . echo "$BUILD_IMAGE_NAME镜像构建完成" docker images $BUILD_IMAGE_NAME echo "上传$BUILD_IMAGE_NAME镜像到私有仓库" docker push $BUILD_IMAGE_NAME fi } function run(){ echo "开始时间>>>>>>$DATE" #判断容器是否存在 if [ -n "$CID" ]; then echo "存在$BUILD_NAME容器,CD=$CID,停止运行并删除" docker stop $CID docker rm $CID echo "$BUILD_NAME容器已经停止运行并删除" build echo "开始重新运行$BUILD_IMAGE_NAME镜像" docker run -p $HOST_PORT:$C_PORT --name $BUILD_NAME -d $BUILD_IMAGE_NAME echo "$BUILD_NAME已经重新运行" docker ps -f name=$BUILD_NAME echo "结束时间>>>>>>$DATE" else echo "不存在$BUILD_NAME容器,判断是否存在$BUILD_IMAGE_NAME镜像" build echo "开始运行$BUILD_IMAGE_NAME镜像" docker run -p $HOST_PORT:$C_PORT --name $BUILD_NAME -d $BUILD_IMAGE_NAME echo "$BUILD_NAME已经运行" docker ps -f name=$BUILD_NAME echo "结束时间>>>>>>$DATE" fi } #运行 run
赋予文件相关权限
chmod +x makeServiceAndRestart.sh
3)、当前目录下启动脚本:
./makeServiceAndRestart.sh
4)、查看启动日志:
docker logs -f pagehelperdemo
3、相关参考:
https://www.runoob.com/docker/docker-dockerfile.html
https://www.jianshu.com/p/4508784f6ddc
https://blog.csdn.net/wzn1054162229/article/details/101096720
https://blog.csdn.net/wzn1054162229/article/details/101199872
十三、Docker Compose容器编排:
在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。因此,Docker官方编排的Docker Compose可以实现对Docker容器集群的快速编排。Docker Compose允许用户通过一个单独的配置文件(docker-compose.yml)对多个容器进行创建、启动、停止和删除,并管理它们之间的网络连接和依赖关系。
1、Docker Compose的安装:
(1)、下载二进制文件:
https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64
(2)、移入docker-compose文件中:
mv docker-compose-linux-x86_64 /usr/local/bin/ docker-compose
chmod +x docker-compose
(3)、查看Docker Compose版本:
docker-compose --version
2、Docker Compose的基础命令:
(1)、启动Compose应用:
docker-compose [OPTIONS] up |
|
选项 |
说明 |
-p |
自定义Compose项目名称 |
-f |
指定docker-compose.yml文件路径 |
-d |
后台启动 |
实例 |
|
docker-compose -d -p my-web -f ./demo/docker-compose.yml up |
(2)、查看Compose应用中的容器:
docker-compose ps |
备注 |
输出内容包括当前状态、容器运行的命令以及网络端口 |
(3)、停止与重启Compose应用中容器:
停止 |
docker-compose stop [compose] |
重启 |
docker-compose restart [compose] |
(4)、删除Compose应用中容器:
删除已停止容器和网络,但是不会删除卷和镜像 |
docker-compose rm [compose] |
停止并删除运行中容器和网络,但是不会删除卷和镜像 |
docker-compose down [compose] |
3、Docker Compose的使用:
(1)、在JAR同级目录下编写Dockerfile文件
(2)、执行命令:
vim Dockerfile
(3)、输入内容:
FROM openjdk:8 VOLUME /opt/install/data/demo02/data ADD pagehelperdemo.jar pagehelperdemo.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/pagehelperdemo.jar"]
(4)、编写docker-compose.yml配置文件
version: "3" services:
#自定义服务名称 my-db: image: mysql:5.7 container_name: my_mysql volumes: - ../mysql/my.cnf:/etc/mysql/my.cnf:ro - ../mysql/data:/var/lib/mysql environment: - MYSQL_DATABASE=demo - MYSQL_ROOT_PASSWORD=123456 ports: - 3306:3306 #自定义服务名称 my-app: #指定Dockerfile文件的路径 build: . #启动容器名 container_name: my_web #暴露端口:服务端口 ports: - "8888:8888" #Docker Compose启动项目的时候,会检查所有依赖,形成正确的启动顺序并按这个顺序来依次启动容器 #先启动数据库 depends_on: my-db: #确保应用服务在数据库初始化完成后再启动 #service_started容器已启动 #service_healthy容器处于健康状态 #service_completed_successfully容器执行完成且成功退出(退出状态码为0) condition: service_healthy
(5)、启动Docker Compose项目:
docker-compose -d -p my-app up
十四、Docker Portainer可视化管理工具:
Portainer是一个可视化的Docker管理系统,功能十分全面,提供状态显示面板、应用模板快速部署、容器镜像、网络、数据卷的基本操作、事件日志显示、容器控制台操作、登录用户管理和控制等功能。
1、Portainer可视化管理工具安装:
#查看所有数据卷: docker volume ls
#创建数据卷portainer_data docker volume create portainer_data #启动portainer容器 # docker.scok是docker的守护进程 # Portainer容器默认使用9000端口来提供Web界面访问 # 8000端口:用于Swarm集群管理 # 9443端口:用于提供加密的HTTPS访问 docker run -d -p 31000:8000 -p 31001:9443 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ --restart=always \ --name portainer \ portainer/portainer-ce:2.14.2
2、Portainer可视化管理工具的使用:
#访问Portainer地址 https://宿主机IP:31001/
#重启容器
docker restart portainer