【devops系列】一文了解Docker
Docker
docker文档:https://docs.docker.com/get-started/
docker是什么
为什么用?
传统部署手法可能因为环境问题出现乱七八糟的问题。
概念
Docker 是一个开源的应用容器引擎
诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc)
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux 机器上。
容器是完全使用沙箱机制,相互隔离
容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版,免费) 和 EE(Enterprise Edition: 企业版,收费)
安装 Docker
Docker可以运行在MAC、Windows、CentOS、UBUNTU等操作系统上,本课程基于CentOS 7 安装
Docker。官网:https://www.docker.com
1 | 1、yum 包更新到最新 |
配置 Docker 镜像加速器
默认情况下,将来从docker hub(https://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:
USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn)
阿里云
1 | { |
- 网易云
- 腾讯云
1 | sudo mkdir -p /etc/docker |
docker命令
Docker 进程相关命令
1 | 启动docker服务: |
镜像相关操作
查看镜像 : 查看本地所有的镜像
1 | docker images |
搜索镜像:从网络中查找需要的镜像
1 | docker search 镜像名称 |
拉取镜像:从Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号,如果版本号不指定则是最新的版本。如果不知道镜像版本,可以去docker hub 搜索对应镜像查看。
1 | docker pull 镜像名称 |
删除镜像: 删除本地镜像
1 | docker rmi 镜像id # 删除指定本地镜像 |
删除所有<none>
版本的镜像
1 | docker images|grep none|awk '{print $3}'|xargs docker rmi |
容器相关命令
- 查看容器
docker ps # 查看正在运行的容器
docker ps -a # 查看所有容器
- 创建并启动容器
docker run 参数
参数说明:
1 | -i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。 |
- 进入容器
docker exec 参数 # 退出容器,容器不会关闭
- 停止容器
docker stop 容器名称
- 启动容器
docker start 容器名称
- 删除容器:如果容器是运行状态则删除失败,需要停止容器才能删除
docker rm 容器名称
- 查看容器信息
docker inspect 容器名称
- 查看容器日志
1 | docker logs 容器名 |
- 查看容器挂载(比如想看docker redis集群挂载的配置文件路径)
1 | docker inspect ab2f940d19ca | grep Mounts -A 20 |
- 容器自启动和取消自启动
1 | # 将正在运行的容器设为自启动 |
docker 数据卷
思考:Docker 容器删除后,在容器中产生的数据还在吗?
1 | 创建启动容器时,使用 –v 参数 设置数据卷 |
多容器进行数据交换
- 多个容器挂载同一个数据卷
数据卷容器
配置数据卷容器
- 创建启动c3数据卷容器,使用 –v 参数 设置数据卷
1 | docker run -it --name=c3 -v /volume centos:7 /bin/bash |
- 创建启动 c1 c2 容器,使用 –-volumes-from 参数 设置数据卷
1 | docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash |
docker应用部署
MySQL部署
- 容器内的网络服务和外部机器不能直接通信
- 外部机器和宿主机可以直接通信
- 宿主机和容器可以直接通信
- 当容器中的网络服务需要被外部机器访问时,可以将容器中提供服务的端口映射到宿主机的端口上。外部机器访问宿主机的该端口,从而间接访问容器的服务。
- 这种操作称为:端口映射
1 | 1. 搜索mysql镜像 |
Tomcat部署
1 | 1. 搜索tomcat镜像 |
Nginx部署
1 | 1. 搜索nginx镜像 |
启动容器
1 | docker run ‐id ‐‐name=c_nginx \ |
Redis部署
1 | 1.搜索redis镜像 |
docker镜像原理
思考:
• Docker 镜像本质是什么?=> 是一个分层文件系统
• Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G? => Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层
• Docker 中一个tomcat镜像为什么有500MB,而一个tomcat安装包只有70多MB? => 由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的 tomcat镜像大小500多MB
操作系统组成部分:
- 进程调度子系统
- 进程通信子系统
- 内存管理子系统
- 设备管理子系统
- 文件管理子系统
- 网络通信子系统
- 作业控制子系统
Linux文件系统由bootfs和rootfs两部分组成,
bootfs:包含bootloader(引导加载程序)和kernel(内核)
rootfs:root文件系统,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件
不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等
Docker镜像是由特殊的文件系统叠加而成
最底端是bootfs,并使用宿主机的bootfs
第二层是root文件系统rootfs,称为baseimage
然后再往上可以叠加其他的镜像文件
统一文件系统(UnionFileSystem)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
一个镜像可以放在另一个镜像的上面。位于下面的镜像称
为父镜像,最底部的镜像成为基础镜像。
当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
复用
镜像制作
1 | docker commit 容器id 镜像名称:版本号 |
dockerfile
Dockerfile 是一个文本文件 ,包含了一条条的指令 ,每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了
- 对于运维人员:在部署时,可以实现应用的无缝移植
Dochub网址:https://hub.docker.com
自定义centos7镜像
要求:
- 默认登录路径为 /usr (官方的默认为/)
- 可以使用vim (官方的默认不可用vim)
① 定义父镜像:FROM centos:7
② 定义作者信息:MAINTAINER itheima itheima@itcast.cn
③ 执行安装vim命令:RUN yum install -y vim
④ 定义默认的工作目录:WORKDIR /usr
⑤ 定义容器启动执行的命令:CMD /bin/bash
⑥ 通过dockerfile构建镜像:docker bulid –f dockerfile文件路径 –t 镜像名称:版本
定义dockerfile,发布springboot项目
① 定义父镜像:FROM java:8
② 定义作者信息:MAINTAINER itheima itheima@itcast.cn
③ 将jar包添加到容器:ADD springboot.jar app.jar
④ 定义容器启动执行的命令:CMD java-jar app.jar
⑤ 通过dockerfile构建镜像:docker bulid -f dockerfile文件路径 -t 镜像名称:版本
Docker 服务编排
微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停 ,维护的工作量会很大。
• 要从Dockerfile build image 或者去dockerhub拉取image
• 要创建多个container
• 要管理这些container(启动停止删除)
服务编排: 按照一定的业务规则批量管理容器
Docker Compose
Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。使用步骤:
- 利用 Dockerfile 定义运行环境镜像
- 使用 docker-compose.yml 定义组成应用的各服务
- 运行 docker-compose up 启动应用
安装
1 | Compose目前已经完全支持Linux、Mac OS和Windows,在我们安装Compose之前,需要先安装Docker。下面我 们以编译好的二进制包方式安装在Linux系统中。 |
卸载
1 | 二进制包方式安装的,删除二进制文件即可 |
编排nginx+springboot项目
1 | 1.创建docker-compose目录 |
Docker 私有仓库
搭建
1 | 1、拉取私有仓库镜像 |
上传
1 | 1、标记镜像为私有仓库的镜像 |
拉取
1 | docker pull 私有仓库服务器ip:5000/centos:7 |
Docker 二次学习
轻量容器引擎Docker
- docker文档:https://docs.docker.com/get-started/
Docker是什么
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。
它基于 Google 公司推出的 Go 语言实现,项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在GitHub 上进行维护
Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc,Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案,Docker 的基础是 Linux 容器(LXC)等技术。
了解Docker的前生LXC
Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
LXC为Linux Container的简写,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性,相当于C++中的NameSpace,容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。
与传统虚拟化技术相比,它的优势在于:
- 与宿主机使用同一个内核,性能损耗小;
- 不需要指令级模拟;
- 不需要即时(Just-in-time)编译;
- 容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
- 避免了准虚拟化和系统调用替换中的复杂性;
- 轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享
Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制,Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。
LXC与docker的关系
docker并不是LXC替代品,docker底层使用了LXC来实现,LXC将linux进程沙盒化,使得进程之间相互隔离,并且能够可控限制各进程的资源分配,在LXC的基础之上,docker提供了一系列更强大的功能。
Docker 的特点
容器化越来越受欢迎,因为容器是:
- 灵活:即使是最复杂的应用也可以集装箱化。
- 轻量级:容器利用并共享主机内核。
- 可互换:您可以即时部署更新和升级。
- 便携式:您可以在本地构建,部署到云,并在任何地方运行。
- 可扩展:您可以增加并自动分发容器副本。
- 可堆叠:您可以垂直和即时堆叠服务。
为什么使用Docker
一款产品:开发-生产2套环境,每个机器都要部署环境(集群redis,es,hadoop…)费时费力,发布一个项目(jar+redis mysql jdk es),能不能带上环境安装的打包。
传统部署手法可能因为环境问题出现乱七八糟的问题。
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多,其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
Docker的优势
具体说来,Docker 在如下几个方面具有较大的优势。
更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高,无论是应用执行速度,内存消耗以及文件存储速度,都要比传统虚拟机技术更高效,因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而Docker容器应用,由于直接运行与宿主内核,无序启动完整的操作系统,因此可以做到秒级,甚至毫秒级的启动时间,大大的节约了开发,测试,部署的时间。
一致的运行环境
开发过程中一个常见的问题是环境一致性问题,由于开发环境,测试环境,生产环境不一致,导致有些bug并未在开发过程中被发现,而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。
持续交付和部署
对于开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用Docker可以通过定制应用镜像来实现持续集成,持续交付,部署,开发人员可以通过Dockerfile来进行镜像构建,并结合持续集成系统进行集成测试,而运维人员则可以在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署
更轻松的迁移
由于Docker确保了执行环境的一致性,使得应用的迁移更加容易,Docker可以在很多平台上运行,无论是物理机,虚拟机,公有云,私有云,甚至是笔记本,其运行结果是一致的,因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
缺点
隔离性
基于hypervisor的虚机技术,在隔离性上比容器技术要更好,它们的系统硬件资源完全是虚拟化的,当一台虚机出现系统级别的问题,往往不会蔓延到同一宿主机上的其他虚机,但是容器就不一样了,容器之间共享同一个操作系统内核以及其他组件,所以在收到攻击之类的情况发生时,更容易通过底层操作系统影响到其他容器。
性能
不管是虚机还是容器,都是运用不同的技术,对应用本身进行了一定程度的封装和隔离,在降低应用和应用之间以及应用和环境之间的耦合性上做了很多努力,但是随机而来的,就会产生更多的网络连接转发以及数据交互,这在低并发系统上表现不会太明显,而且往往不会成为一个应用的瓶颈(可能会分散于不同的虚机或者服务器上),但是当同一虚机或者服务器下面的容器需要更高并发量支撑的时候,也就是并发问题成为应用瓶颈的时候,容器会将这个问题放大,所以,并不是所有的应用场景都是适用于容器技术的。
存储方案
容器的诞生并不是为OS抽象服务的,这是它和虚机最大的区别,这样的基因意味着容器天生是为应用环境做更多的努力,容器的伸缩也是基于容器的这一disposable特性,而与之相对的,需要持久化存储方案恰恰相反。 这一点docker容器提供的解决方案是利用volume接口形成数据的映射和转移,以实现数据持久化的目的,但是这样同样也会造成一部分资源的浪费和更多交互的发生,不管是映射到宿主机上还是到网络磁盘,都是退而求其次的解决方案。
一致性怎么理解?
对比传统虚拟机
特性 | Docker 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
Docker版本
随着Docker的不断流行与发展,docker公司(或称为组织)也开启了商业化之路,Docker 从 17.03版本之后分为 CE(Community Edition) 和 EE(Enterprise Edition),我们来看看他们之前的区别于联系。
版本区别
Docker EE
Docker EE由公司支持,可在经过认证的操作系统和云提供商中使用,并可运行来自Docker Store的、经过认证的容器和插件。
Docker EE提供三个服务层次:
服务层级 | 功能 |
---|---|
Basic | 包含用于认证基础设施的Docker平台 Docker公司的支持 经过 认证的、来自Docker Store的容器与插件 |
Standard | 添加高级镜像与容器管理 LDAP/AD用户集成 基于角色的访问控制(Docker Datacenter) |
Advanced | 添加Docker安全扫描 连续漏洞监控 |
大家可在该页查看各个服务层次的价目:https://www.docker.com/pricing
Docker CE
Docker CE是免费的Docker产品的新名称,Docker CE包含了完整的Docker平台,非常适合开发人员和运维团队构建容器APP
Docker公司认为,Docker CE和EE版本的推出为Docker的生命周期、可维护性以及可升级性带来了巨大的改进。
版本说明
在此之前docker的最新版本更新到docker1.13,而在1.13的基础之上,在2017年的3月1号开始,版本的格式变为如下
项目 | 说明 |
---|---|
版本格式 | YY.MM |
stable版本 | 每个季度发行 |
edge版本 | 每个月发行 |
当前CE版本 | 17.03.0-ce |
小结
- Docker从17.03开始分为企业版与社区版,社区版并非阉割版,而是改了个名称;企业版则提供了一些收费的高级特性。
- EE版本维护期1年;CE的stable版本三个月发布一次,维护期四个月;另外CE还有edge版,一个月发布一次。
Docker使用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境
Docker安装
配置要求:
卸载旧版本
较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
1 | yum remove docker \ |
安装Docker依赖环境
在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库,之后,您可以从仓库安装和更新 Docker。
1 | yum install -y yum-utils \ |
设置 Docker 安装地址
在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库,之后,您可以从仓库安装和更新 Docker,使用以下命令来设置稳定的仓库(阿里云)
1 | sudo yum-config-manager \ |
安装 Docker Engine-Community
安装最新版本的 Docker Engine-Community 和 containerd
1 | sudo yum install -y docker-ce docker-ce-cli containerd.io |
如果提示您接受 GPG 密钥,请选是。
Docker 安装完默认未启动,并且已经创建好 docker 用户组,但该用户组下没有用户。
Docker 镜像加速
阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了:
配置daemon.json
您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
1 | sudo mkdir -p /etc/docker |
启动 Docker
1 | systemctl start docker |
验证docker服务
通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community 。
1 | docker run hello-world |
运行该代码后首先会从仓库拉取
hello-world
镜像,然后运行该镜像,运行后会输出一个Hello from Docker!
开启Docker自动补全
使用docker时无法自动补全镜像名和其他参数,这样使用效率大大降低,下面是解决方法
bash-complete
1 | yum install -y bash-completion |
刷新文件
1 | source /usr/share/bash-completion/completions/docker |
测试
输入
docker p
后docker会将可选项列出来 [tab键]
1 | docker p |
Docker架构
Docker总体架构为c/s架构,模块之间松耦合,包含了Client, Daemon, Registry, Graph, Driver, Libcontainer以及Docker Container
Docker的组件
Docker Client
是用户界面,它支持用户与Docker Daemon
之间通信Docker Daemon
Docker最核心的后台进程,运行于主机上,处理服务请求Docker registry
是中央registry,支持拥有公有与私有访问权限的Docker容器镜像的备份Docker Containers
负责应用程序的运行,包括操作系统、用户添加的文件以及元数据Docker Images
是一个只读模板,用来运行Docker容器DockerFile
是文件指令集,用来说明如何自动创建Docker镜像
Docker 基本概念
Docker 包括三个基本概念:
镜像
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等),镜像不包含任何动态数据,其内容在构建之后也不会被改变。
分层存储
镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
Union FS
联合文件系统是(Union FS)是linux的存储技术,也是Docker镜像的存储方式, 它是分层的文件系统,将不同目录拉到同一个虚拟目录下,下图展示了Docker用Union FS 搭建的分层镜像:(比如最下层是操作系统的引导,上一层是Linux操作系统,再上一层是Tomcat,jdk,再上一层是应用代码)
这些层是只读的,加载完后这些文件会被看成是同一个目录,相当于只有一个文件系统。
我们可以通过docker info查看镜像的一些信息,可以看到存储驱动用的并不是Union FS 而是overlay2,overlay也是一个联合文件系统,所以上述主要介绍联合文件系统的概念,至于这些存储驱动的演变过程和优缺点
镜像构建时,会一层层构建,前一层是后一层的基础,每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。(比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除,在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像,因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉)
容器
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间,因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样,这种特性使得容器封装的应用比直接在宿主运行更加安全,也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。
前面讲过镜像使用的是分层存储,容器也是如此,每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡,因此,任何保存于容器存储层的信息都会随容器删除而丢失。
仓库
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本,我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像,如果不给出标签,将以latest作为默认标签。
以 Ubuntu 镜像为例,ubuntu是仓库的名字,其内包含有不同的版本标签,如,14.04,16.04,我们可以通过ubuntu:14.04,或者ubuntu:16.04来具体指定所需哪个版本的镜像,如果忽略了标签,比如ubuntu,那将视为ubuntu:latest
docker.io/library + nginx 默认拉取
仓库名经常以三段式路径形式出现,比如heima.com/nginx-proxy:tag
,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名,但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。
Docker部署微服务
场景介绍
我们使用Docker完成一个微服务的搭建过程
整体架构如下
使用多个微服务进行项目部署测试
整体服务说明
我们总共涉及到三个微服务以及两个中间件
服务名称 | 描述 |
---|---|
mysql | 数据库服务 |
nacos | 注册中心 |
learn-docker-gateway | 网关服务 |
learn-docker-web | API接口服务 |
learn-docker-storage | 存储服务 |
配置文件提取
因为我们在开发中需要频繁修改
application.yml
文件我们将配置项配置到pom
文件中打包时自动打到配置文件,这样可以用一个pom
文件控制多个不同的服务的配置文件项的修改
pom文件定义属性
我们需要在总
pom
文件定义全局配置,例如nacos
、mysql
等配置
1 | <properties> |
配置编译选项
在子项目的pom文件的
build
构建配置中使用<filtering>true</filtering>
配置,这样就可以将我们的总pom中的配置编译进配置文件了
1 | <build> |
配置文件配置
在子项目的
application.yml
配置文件中注意使用@xxx@
占位符来配置编译占位配置,下面的配置就是用了@@
占位符编译后会将pom中的配置编译到配置文件中
1 | server: |
编译测试
配置完后编译项目后,可以进入target目录下查看编译后的配置文件
我们看到maven已经帮我们将配置编译进了配置文件中了
安装MySQL
MySQL简介
MySQL 是世界上最受欢迎的开源数据库。凭借其可靠性、易用性和性能,MySQL 已成为 Web 应用程序的数据库优先选择。
查找MySQL镜像
我们可以使用 docker search 镜像名称,命令来搜索镜像
1 | docker search mysql |
参数解释
搜索出来的有这么多镜像,怎么选择呢
- NAME: 镜像仓库源的名称
- DESCRIPTION: 镜像的描述
- OFFICIAL: 是否 docker 官方发布
- stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
- AUTOMATED: 自动构建。
根据参数,我们一般选择 官方发布的,并且stars多的。
下载镜像
可以使用
docker pull 镜像名称
来拉取镜像,我们选择了第一个Mysql的镜像,我们把它给拉取下来
1 | docker pull mysql |
注意事项
- 如果不写版本号默认拉取最新的版本好
latest
。 - 拉取的时候是多个层一起拉取的,这样可用让其他镜像复用分层
- 如果拉取的镜像不写仓库地址默认就是
docker.io/library/
下载指定版本的镜像
我们上面下载的镜像不符合我们的预期,我们需要Mysql5.7的镜像
查找指定镜像
可以登录 https://hub.docker.com 地址搜索镜像
输入需要搜索的镜像名称,并选择对应镜像名称
选择
tag
标签,这个就是版本的信息
找到符合的版本 的mysql镜像,这里我们选择
5.7.33
下载指定版本镜像
刚才我们已经找到了
5.7.33
版本的Mysql的镜像,我们使用docker pull
命令下载,镜像后面跟的是tag也就是版本名称
1 | docker pull mysql:5.7.34 |
我们发现,我们的新拉取的mysql镜像共用了 部分分层
查看镜像
安装完镜像后,我们需要看一下我们的本地镜像,使用
docker images
可用查看本地镜像
1 | docker images |
这里有两个镜像,一个是最新版本的一个是我们刚才下载的
5.7.33
版本的
MySQL配置
配置MySQL忽略大小写
创建MySQL挂载目录,等会会解释什么是挂载路径
1 | # 创建MySQL配置的文件夹 |
配置MySQL忽略大小写,在我们创建的MySQL配置文件挂载点的目录的my.cnf文件加入如下内容
1 | [mysqld] |
创建MySQL数据目录
因为默认MySQL启动后他的文件是在容器中的,如果我们删除容器,数据也将会消失,我们需要将数据挂载出来。
1 | #创建mysql存储的目录 |
启动MySql
使用
docker run
启动容器
1 | docker run -d -p 3306:3306 -v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ -v /tmp/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7.34 |
到这里MySQL已经后台运行了
参数解释
- -d:是指容器后台运行,如果不加
-d
,当用户断开客户端时容器会结束运行 - -p:将容器的3306端口映射到主机的3306端口,用来暴漏端口的
- -v:这个命令是用来挂载目录的,将本地目录挂载到容器中,这样容器操作的就是本地目录
- -e:这个命令是配置环境参数的,这里
MYSQL_ROOT_PASSWORD=root
指的是用root用户运行mysql,可以登录Docker容器通过ENV
命令查看 - –name:这个命令是配置Mysql的容器名称的,如果不配置,默认是随机生成的名字
检查MySQL运行状态
现在并不能确认MySQL的运行状态,我们需要去看下
查看容器运行状态
使用
docker ps
可以看到运行中的容器
1 | docker ps |
执行命令后,我们看到mysql的服务已经起来了
查看MySQL运行日志
现在MySQL容器起来了,并不代表MySQL已经成功启动,我们需要使用
docker logs
命令查看MySQL的日志
1 | docker logs -f mysql |
该命令可以查看容器日志
-f
是追踪打印日志,可以看到MySQL已经启动了
客户端连接MySQL
因为我们已经暴漏端口了,可以使用客户端工具连接MySQL
检查配置的大小写参数是否生效
1 | SHOW VARIABLES LIKE '%case_table%'; |
查看容器挂载的配置文件
可以通过
docker exec -ti mysql /bin/bash
命令登录容器,检查挂载的配置文件情况
1 | # 登录容器 |
该命令含义是在mysql容器中以
我们可以看到我们修改的配置文件已经被挂载到了docker内部,这里面用到了exec命令,主要是在docker容器中运行命令,下面我们介绍下
命令格式
主要是在deocker容器中运行命令
1 | docker exec [options] container command [arg...] |
命令参数
名称 | 简写 | 描述 |
---|---|---|
–detach | -d | 后台运行模式,在后台执行命令相关命令 |
–detach-keys | 覆盖容器后台运行的一些参数信息 | |
–env | -e | 设置环境变量 |
–interactive | -i | 展示容器输入信息STDIN |
–privileged | 为命令提供一些扩展权限 | |
–tty | -t | 命令行交互模式 |
–user | -u | 设置用户名(format: <name|uid>[:<group|gid>]) |
–workdir | -w | 指定容器内的目录 |
查看挂载的数据文件
可以看下挂载的数据文件是否存在
1 | cd /tmp/data/mysql/ && ll |
我们看到数据文件已经写入了
MySQL准备数据
MySql需要导入一些数据用来操作,我们用MySQL官方提供的数据库来操作
下载并导入数据
下载MySQL测试数据库
到测试数据官网 下载数据库文件
直接导入无法导入,需要编辑
employees.sql
文件的一些地方
set storage_engine = InnoDB;
修改为:set default_storage_engine = InnoDB;
select CONCAT('storage engine: ', @@storage_engine) as INFO;
修改为:select CONCAT('storage engine: ', @@default_storage_engine) as INFO;
1 | ..... |
导入测试数据
下载解压后,在本地执行命令导入到mysql服务器
1 | mysql -uroot -h192.168.64.152 -p < employees.sql |
客户端检查数据
在登陆客户端就能看到数据库以及表了
安装部署nacos
Nacos是阿里巴巴开源的一款支持服务注册与发现,配置管理以及微服务管理的组件。用来取代以前常用的注册中心(zookeeper , eureka等等),以及配置中心(spring cloud config等等),Nacos是集成了注册中心和配置中心的功能,做到了二合一。
直接运行服务
可以直接用docker 启动服务,镜像不存在会自动拉取
1 | docker run -d -p 8848:8848 --name nacos --env MODE=standalone nacos/nacos-server |
运行容器后可以稍等下,等待nacos启动成功,受环境限制启动可能有些慢
登录页面测试
可以登录服务器测试以下
用户名:nacos 密码:nacos
微服务打包镜像
我们准备将一个微服务打包成Docker镜像,在各种服务器中进行运行,改为服务支持进行查询用户信息
提前说明
因为我们刚开始进行学习Docker,先从单个微服务开始学习,我们就先部署
learn-docker-storage
服务,后面随着课程的深入在慢慢增加其他的微服务
访问测试
在idea中运行
learn-docker-storage
我们配置的端口是8003,我们可以直接访问
http://localhost:8003/storage/employe/findByID/10001
打包上传微服务
将
learn-docker-storage
服务打包后上传到服务器
注意配置项
这里需要检查下maven配置的编译属性是否正确
1 | <mysql.addr>192.168.64.153:3306</mysql.addr> |
我们发现是我们容器中启动的地址
上传打包后的微服务
将target目录中打包完成的微服务上传到服务器
创建DockerFile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
创建一个Dockerfile文件
1 | vi Dockerfile |
具体内容如下
1 | FROM openjdk:8-jdk-alpine |
命令解释
- FORM:定制的镜像都是基于 FROM 的镜像,这里的 openjdk 就是定制需要的基础镜像,后续操作都是基于openjdk
- VOLUME:挂载一个数据卷,这里因为没有名称,所以是一个默认的数据卷(后面详细解释)
- ADD:添加一层镜像到当前镜像,这里就是添加SpringBootTest镜像到当前层,并改名app.jar
- EXPOSE:暴漏端口,因为我们的自己的端口是8003,所以我们暴漏8003
- ENTRYPOINT:设定容器启动时第一个运行的命令及其参数,这里就是容器以启动就执行 java -jar /app.jar
打包镜像
写好DockerFile后就需要用
docker build
命令来构建我们的镜像了,这样就可以将我们的微服务打包成一个镜像了
构建命令格式
构建一个镜像需要使用以下命令
1 | docker bulid -t 仓库名/镜像名:tag . |
参数解释
- -t: 镜像的名字及标签,一般命名规则是 仓库名/镜像名:tag,
- 仓库名:一般是私服或者dockerhub等地址,如果忽略默认就是dockerhub的地址
docker.io.library/
- 镜像名称:就是我们的自己的服务名称,可以随意命名
- tag:就是我们的版本号
- 仓库名:一般是私服或者dockerhub等地址,如果忽略默认就是dockerhub的地址
- **.**:这个
.
表示当前目录,这实际上是在指定上下文的目录是当前目录,docker build
命令会将该目录下的内容打包交给 Docker 引擎以帮助构建镜像。
实战操作
一般来说,应该会将 Dockerfile
置于一个空目录下,或者项目根目录下,如果该目录下没有所需文件,那么应该把所需文件复制一份过来。
一般大家习惯性的会使用默认的文件名 Dockerfile
,以及会将其置于镜像构建上下文目录中。
当前目录的结构如下
构建镜像
进入Dockerfile的目录,通过如下命令构建镜像
1 | docker build -t learn-docker-storage:0.0.1 . |
构建完成如果出现
Successfully
说明已经构建成功了,
查看我们构建的镜像
使用
docker images
命令查看我们构建完成的镜像
1 | docker images |
我们可以看到我们的镜像就在第一个位置
运行镜像
刚才已经打包完成了镜像,现在我们运行我们自己的镜像
1 | 运行容器 |
参数最后的
learn-docker-storage:0.0.1
是镜像的名称,如果启动容器可以使用镜像名称或者镜像ID
参数解释
- -d:后台运行
- -p:映射端口,将宿主机的8080端口映射到docker内部的8080端口上
查看启动日志
使用
docker logs 容器ID
来查看启动日志
1 | docker logs -f 74c239792266 |
尝试访问服务
通过
curl
命令来访问服务
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
我们发现服务调用成功了,我们基本实现了微服务改造为docker方式并运行
删除容器
要删除一个容器首先需要将一个容器停止掉
停止容器
我们要把刚才运行的容器停止掉,使用
docker stop 容器ID
停止一个容器
1 | docker stop 3752f7088a04 |
停止容器后,我们在通过进程查看是看不到容器的,但是容器还是存在我们的服务中的
查看全部容器
通过
docker ps
只能看到运行中的容器,但是我们停止的容器是看不到的,可以加上-a
查看所有的容器
1 | docker ps -a |
我们可以看到 加上
-a
参数可以看到刚才已经停止掉的容器
启动停止的容器
想要启动一个停止的容器可以使用
docker start 容器ID
1 | docker start 3752f7088a04 |
这样就把刚才已经停止的容器启动了
删除容器
已经停止的容器可以使用
docker rm 容器ID
删除容器,但是对于运行中的容器可以加上-f
参数强制删除
1 | docker rm -f 3752f7088a04 |
这样可以将一个运行的容器强制删除,如果停止的容器可以通过通过
docker rm
删除
1 | docker rm 3752f7088a04 |
这个时候就把容器给删除掉了
日志挂载优化
存储卷优化
什么是存储卷
“卷”是容器上的一个或多个“目录”,此类目录可绕过联合文件系统,与宿主机上的某个目录“绑定(关联)”;
在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。
Docker管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录中;(最常用的方式)
存储卷优化写入速度
Docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像层并在镜像栈顶部加一个读写层;
如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制。
为了避免这种情况,构建Dockerfile的时候应该加入一个存储卷
Dockerfile增加存储卷
增加存储卷
编写Dockerfile增加存储卷,增加日志存储卷
/logs
,这会是一个匿名存储卷
1 | FROM openjdk:8-jdk-alpine |
构建镜像
因为我们原来已经构建了镜像,这次使用版本号是
0.0.2
1 | 构建镜像 |
运行容器
通过run命令运行容器
1 | 运行容器 |
查看存储卷
通过
docker volume ls
可以看到存储卷
1 | docker volume ls |
查看容器信息
我们发现都是匿名的存储卷,如何来确定都是那个呢,可以通过
docker inspect 容器ID
来查看存储新鲜
1 | docker inspect 2041965c3e87|grep Mounts -A20 |
通过这个命令可以看到数据卷的名称以及宿主机的存储路径,我们可以直接到宿主机打印日志
1 | 进入文件挂载目录 |
这样就看到了我们的日志文件
验证存储卷
删除容器检查存储卷释放消失
1 | 查看运行的容器列表 |
我们看到容器已经被删除了,检查我们的存储卷
1 | docker volume ls |
发现存储卷还存在,数据还是存在的,并且数据也存在
1 | 查看存储卷列表 |
重新运行镜像启动一个新的容器
1 | 运行容器 |
启动容器后查看存储卷列表
1 | 查看存储卷列表 |
我们发现有创建了两个存储卷,查看容器详情
1 | docker inspect 2041965c3e87|grep Mounts -A20 |
我们发现新启动的容器新开了一个匿名存储卷
bind挂载共享存储
什么是bind
Bind mounts模式和Volumes非常相似,不同点在于Bind mounts模式是将宿主机上的任意文件或文件夹挂载到容器,而Volumes本质上是将Docker服务管理的一块区域(默认是/var/lib/docker/volumes下的文件夹)挂载到容器。
共享存储
经过上面的测试,我们发现每一个容器都是单独用一个存储卷,用于临时文件没有问题的,但是如果要让容器都用同一个存储路径怎么办呢,这个时候就用到了 bind挂载了,可以使用
-v
进行挂载挂载刚才的存储卷。
1 | 级联创建文件夹 |
这里面
--name
是指定docker容器的名称,我们操作容器就可以使用名称进行操作了
然后使用
docker inspect
命令来检查容器详情
1 | docker inspect learn-docker-storage|grep Mounts -A20 |
我们发现挂载日志的挂载方式已经变了,由原来的volume变为了bind,并且挂载路径变为了我们自己定义的路径,进入目录查看
1 | 进入目录并浏览目录文件 |
验证共享存储
我们也按照上面步骤验证下bind方式挂载的存储,先删除容器,检查日志文件是否存在
1 | 停止并删除容器 |
我们发现容器被删除但是日志文件还存在本地
启动一个新的容器
1 | 运行容器,指定挂载路径 |
我们发现新的容器的日志文件追加进来了
我们发现日志已经追加,我们让不同的容器挂载同一个目录了
volume和bind的区别
对于多个容器需要共享访问同一数据目录,或者需要持久化容器内数据(如数据库)时,我们都是采用挂载目录形式(bind mounts),将宿主机的某一目录挂载到容器内的指定目录,这种方式能解决问题,但这种方式也一直有一些缺点
- 容器在不同的服务器部署需要根据实际磁盘挂载目录修改路径
- 不同操作系统的文件和目录权限会搞得你昏头转向,火冒三丈 ?
bind mount和volume其实都是利用宿主机的文件系统,不同之处在于volume是docker自身管理的目录中的子目录,所以不存在权限引发的挂载的问题,并且目录路径是docker自身管理的,所以也不需要在不同的服务器上指定不同的路径,你不需要关心路径。
清理volume挂载
volume挂载方式,会生成很多匿名的目录,我们可以找到对应的没有使用的volume进行删除
1 | docker volume ls |
通过查看我们发现里面,有很多的volume,我们可以找到没有用的删除
1 | docker volume rm volume_name |
还可以通过命令将没有引用的全部volume清除掉,但是这个命令很危险
1 | docker volume prune |
这样就将我们服务器上无效的volume清除掉了
网络优化
Docker网络原理
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关,因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器,如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
Docker网络模式
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | –net=host | 容器和宿主机共享Network namespace。 |
container模式 | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
none模式 | –net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 |
overlay模式 | – driver overlay | Docker跨主机通信模式,使用分布式计算机架构后需要使用overlay网络模式 |
bridge模式 | –net=bridge | (默认为该模式) |
host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。
容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口,但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
Host模式如下图所示
不推荐,会占用宿主机的端口,其他服务想用用不了
container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享
新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等,同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的,两个容器的进程可以通过 lo 网卡设备通信
Container模式示意图
none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置,也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡,none模式可以在容器创建时通过–network=none来指定,这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
None模式示意图
一般用来跑定时任务,不需要外部访问的服务
overlay模式
容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信,如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信,overlay它会虚拟出一个网络比如10.0.9.3这个ip地址,在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。
bridge模式
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关,在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看
bridge模式是docker的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
bridge模式如下图所示
我们的网络结构
下图是我们自己的网络结构,我们是通过宿主机访问Mysql容器的,刚才我们学过,默认Docker已经接入了一个名字叫
bridge
的桥接网络
我们可以让我们的网络直接接入桥接网络,例如下图
创建网络
查看网络列表
可以通过
docker network ls
命令查看网络列表
1 | # 查看网络列表 |
上面就是容器默认几种网络
创建一个桥接网络
默认容器启动会自动默认接入
bridge
的桥接网络,为了区分我们的服务也防止各种网络问题,我们创建一个专用网络,可以通过docker network create 网络名称
来创建一个默认的桥接网络
1 | # 创建一个桥接网络 |
服务接入网络
停止并删除原有容器
停止和删除我们的微服务以及mysql服务
1 | 删除当前运行中的容器 |
创建MySQL
因为我们的微服务依赖MySQL先启动MySQL并接入网络,因为MySQL不需要通过宿主机访问,所有也不需要映射端口了,–network 是配置接入哪一个网络
1 | docker run -d \ |
这样我们就把我们的MySQL服务启动起来了并且加入了learn-docker-network的网络
创建Nacos
我们的nacos是需要暴漏端口的,因为我们需要外部能够看到nacos页面,但是我们也需要我们的nacos连接到当前网络
1 | docker run -d -p 8848:8848 \ |
查看网络详情
可以通过
docker network inspect 网络名称
可以查看当前的网络的详细信息
1 | docker network inspect learn-docker-network|grep Containers -A 20 |
修改微服务配置
因为需要使用自定义网络访问mysql容器以及nacos容器,需要修改微服务数据库连接地址,
docker 网络访问 可以通过IP或者通过服务名称都是可以的,这里我们通过服务名称访问,因为我们使用了maven打包的方式,我们只需要将pom文件修改就可以
1 | <properties> |
修改完成后进行编译项目
这里将数据库连接地址改为mysql容器的服务名称
mysql
,nacos的连接地址变为了nacos
重新打包服务
将打包的文件上传服务器后按照上面步骤同上面打包,打包版本为 0.0.3
1 | docker build -t learn-docker-storage:0.0.3 . |
创建微服务
下面就按部就班的创建微服务就可以,只是注意需要加入网络,这里这个端口需要映射外网访问
1 | docker run -d \ |
测试微服务
到现在微服务已经启动,我们尝试访问以下
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
访问测试数据没有问题,到现在我们服务已经搭建完成,并且使用网络进行了优化
Docker 集群管理
镜像仓库管理
docker仓库,用来管理镜像
主要分为公共仓库和私人仓库,下面介绍了公共仓库Docker Hub、私人仓库Registry和harbor
DockerHUb仓库管理
什么是DockerHUb
保存和分发镜像的最直接方法就是使用 Docker Hub
Docker Hub 是 Docker 公司维护的公共 Registry,用户可以将自己的镜像保存到 Docker Hub 免费的 repository 中,如果不希望别人访问自己的镜像,也可以购买私有 repository
账号注册和登陆
一般,你需要先在docker中心创建一个账户(如果您尚未有),你可以直接在Docker Hub创建你的账户。
如果有已有账号可以点击
sign in
进行登录,登陆后是这个样子
Docker客户端登录
使用
docker login
登录dockerhub
这将提示您输入用户名,这个用户名将成为你的公共存储库的命名空间名称。如果你的名字可用,docker会提示您输入一个密码和你的邮箱,然后会自动登录到Docker Hub,你现在可以提交和==推送镜像==到Docker Hub的你的存储库。
1 | docker login |
出现
Login Succeeded
就说明我们登录成功注:你的身份验证凭证将被存储在你本地目录的
.dockercfg
文件中
管理镜像
通过
docker images
可以看到我们所有的镜像列表
1 | docker images |
删除镜像
我们现在的
learn-docker-storage
有三个版本,现在我们把前两个有问题的版本删除,docker rmi 镜像ID
可以删除镜像
1 | docker rmi learn-docker-storage:0.0.1 learn-docker-storage:0.0.2 |
这样我们就删除了我们没有用的镜像了,可以节省内存空间
修改镜像命名
修改镜像的 repository 使之与 Docker Hub 账号匹配
Docker Hub 为了区分不同用户的同名镜像,镜像的 registry 中要包含用户名,完整格式为:[用户名]/镜像名:tag
我们通过
docker tag
命令重命名镜像
1 | docker tag learn-docker-storage:0.0.3 baiyp/learn-docker-storage:0.0.3 |
这样就将我们的镜像改名了,这个就符合我们的dockerhub的规范了
推送镜像
推送镜像
现在我们要将我们的镜像推送到
docker hub
推送镜像的规范是
docker push 注册用户名/镜像名:tag
,因为我们上面已经把镜像名字改正确了,所以可以直接推送。
1 | docker push baiyp/learn-docker-storage:0.0.3 |
这样我们就将我们的数据推送到docker hub,我们发现只有最顶层的镜像推送了,openjdk的镜像并没有推送,直接复用了仓库的,这就是分层的好处
检查镜像
我们可以到
docker hub
检查我们的镜像
可以看到我们的镜像已经推送过来了,点开详情可以看到我们镜像的内容以及tag号
仓库镜像测试
删除本地镜像
可以通过
docker rmi 镜像ID
删除本地镜像
1 | docker rmi baiyp/learn-docker-storage:0.0.3 learn-docker-storage:0.0.3 |
再次查看本地镜像,已经没有了我们的微服务的镜像
1 | docker images |
从仓库拉取镜像
这个时候可以从
docker hub
拉取镜像
1 | docker pull baiyp/learn-docker-storage:0.0.3 |
这个时候已经将镜像拉取下来了,我们可以运行镜像了
运行镜像
执行下面的命令进行创建镜像
1 | docker run -d \ |
访问测试
我们访问下,检查下是否可以正常运行
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
到这里我们就完成dockerhub仓库的发布与拉取
直接运行测试
在真实环境中,我们一般不会拉取在运行,一般都是直接运行,如果docker检查镜像不存在会自动拉取
停止服务并删除镜像
1 | docker rm -f learn-docker-storage |
我们直接运行容器
1 | docker run -d \ |
这一个run命令就解决了容器的拉取以及容器运行的问题
registry仓库管理
registry简介
官方提供了Docker Hub网站来作为一个公开的集中仓库。然而,本地访问Docker Hub速度往往很慢,并且很多时候我们需要一个本地的私有仓库只供网内使用。
Docker仓库实际上提供两方面的功能,一个是镜像管理,一个是认证。前者主要由docker-registry项目来实现,通过http服务来上传下载;后者可以通过docker-index(闭源)项目或者利用现成认证方案(如nginx)实现http请求管理。
docker registry 就是管理 docker 镜像的服务, Docker 公司维护的 registry 就是 http://hub.docker.com ,它可以让我们方便的下载预先做好的镜像。
安装registry
我们可以通过获取官方的
registry
镜像来运行。
这将使用官方提供的 registry
镜像来启动私有仓库,默认情况下,仓库会被创建在容器的 /var/lib/registry
目录下。我们可以通过 -v
参数将镜像文件存放在本地的指定路径。
1 | mkdir /tmp/data/registry |
这样我们的registry已经启动起来了
访问测试
这时我们可以通过浏览器访问
http://ip:5000/v2/_catalog
查看仓库是否启动成功。
1 | curl http://192.168.64.152:5000/v2/_catalog |
上传镜像
registry 上传镜像的命名规范是
仓库IP:5000/镜像名称:tag
修改镜像名称
将我们的镜像改成服务规范的名字
1 | docker tag chenzhijie2021/learn-docker-storage:0.0.1 124.223.105.177:5000/learn-docker-storage:0.0.1 |
推送镜像
使用命令推送镜像
1 | docker push 124.223.105.177:5000/learn-docker-storage:0.0.1 |
我们发现推送报错了,这是因为docker推送默认使用的https的方式,而我们的registry只支持http的方式
修改Docker推送配置
对于 Linux 系统,我们可以在
/etc/docker/daemon.json
(daemon.josn
文件不存在则新建该文件)
1 | vi /etc/docker/daemon.json |
添加下面的配置
1 | { "insecure-registries": ["仓库IP:5000"] } |
完整的配置如下
1 | { |
执行以下命令重启重新加载配置并生效
1 | systemctl daemon-reload |
再次进行推送
执行命令再次推送
1 | docker push 192.168.64.153:5000/learn-docker-storage:0.0.3 |
我们发现这次推送成功了
再次访问registry
访问测试检查是否已经推送
1 | curl http://192.168.64.153:5000/v2/_catalog | python -m json.tool |
我们发现我们的镜像已经推送到了registry,我们通过以下URL访问下tag列表
1 | curl http://192.168.64.153:5000/v2/learn-docker-storage/tags/list | python -m json.tool |
registry镜像测试
删除本地镜像
可以通过
docker rmi 镜像ID
删除本地镜像
1 | docker rmi baiyp/learn-docker-storage:0.0.3 192.168.64.153:5000/learn-docker-storage:0.0.3 |
运行registry中的镜像
1 | docker run -d \ |
我们发现自己的registry很快就拉取并且运行起来了
访问微服务测试
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
使用Harbor管理仓库
什么是Harbor
harbor是一个由vm公司开源的企业级容器镜像仓库,有以下功能
- 管理用户界面
- 基于角色的访问控制
- LDAP/AD 集成及日志审计等基本运维操作
harbor是构建企业级私有docker镜像的仓库的开源解决方案,它是 Docker Registry的更高级封装,它除了提供友好的Web UI界面,角色和用户权限管理,用户操作审计等功能外,它还整合了K8s的插件(Add-ons)仓 库,即Helm通过chart方式下载,管理,安装K8s插件,而chartmuseum 可以提供存储chart数据的仓库。
另外它还整合了两个开源的安全组件,一个是Notary,另一个是Clair,Notary类似 于私有CA中心,而Clair则是容器安全扫描工具,它通过各大厂商提供的 CVE漏洞库来获取最新漏洞信息,并扫描用户上传的容器是否存在已知的 漏洞信息,这两个安全功能对于企业级私有仓库来说是非常具有意义的。
Harbor的三种安装方式
这里我们使用离线安装
- 在线安装:从Docker Hub下载Harbor相关镜像,因此安装软件包非常小
- 离线安装:安装包包含部署的相关镜像,因此安装包比较大
- OVA安装程序(第三方):当用户具有vCenter环境时,使用此安装程序,在部署 OVA后启动Harbor
为什么使用私用仓库
公司的项目一般不予许我们上传到 Docker Hub 这类的公共仓库中,所有学会创建一个私有仓库也是非常必要的
虽然hub.docker.com
上可以保存镜像,但是网速相对较慢,在内部环境中搭建一个私有的公共仓库是个更好的方案。
harbor 的基本组件
组件 | 功能 |
---|---|
harbor-adminserver | 配置管理中心 |
harbor-db | 数据库 |
harbor-jobservice | 镜像复制 |
harbor-log | 日志操作 |
harbor-ui | Web管理页面和API |
nginx | 前端代理,负责前端页面和镜像上传/下载转发 |
redis | 会话 |
registry | 镜像存储 |
前置工作
下载安装包
Harbor官方地址:https://github.com/goharbor/harbor/releases 下载最新版安装包
准备环境
需要安装docker以及docker-compose的环境上面我们已提前安装了
- 安装Docker环境
- 安装docker-compose环境
离线安装
解压安装包
解压harbor的安装包
1 | tar -zxf harbor-offline-installer-v2.1.4.tgz |
进入目录 然后将
harbor.yml.tmp
复制一份并该命为harbor.yml
1 | cd harbor |
注意: 这里跟老版本不一样,没有了harbor.cfg文件,我们需要手动复制harbor.yml.tmpl在做修改即可
修改harbor.yml
harbor作为私有仓库作用在公司内网,一般都是信任关系,没多大必要做https,使用http即可! 所以 把https相关的已经注释掉
并注意配置文件的用户名密码配置,默认是 用户名是:admin,密码是:Harbor12345,如果修改需要安装前修改
加载本地镜像
使用
docker load
命令加载本地镜像,不用再从dockerhub下载了
1 | docker load -i harbor.v2.1.4.tar.gz |
这样容器镜像就被加载到了本地,我们可以通过
docker images
命令查看导入的镜像
1 | docker images |
执行安装命令
先执行预处理命令,会创建一些文件夹,初始化一些文件
1 | ./prepare |
然后开始真正的安装过程
1 | ./install.sh |
如果出现
-Harbor has been installed and started successfully
表示安装成功,并查看docker进程
1 | docker ps |
可以看到很多服务已经起来了。
启动和停止harbor
在harbor的安装目录执行以下命令就可以启动和停止了
1 | # 启动 |
harbor使用
访问harbor
输入
http://harborIP
就可以直接访问了,这里访问我们的地址http://192.168.64.153/
输入用户名密码就可以登录了 ,如果没有修改配置文件 默认是 用户名是:admin,密码是:Harbor12345
登录后就可以进行操作了
Docker登录harbor
使用docker login命令就可以登录harbor了
1 | docker login -u admin -p Harbor12345 192.168.64.153 |
我们发现登录报错了,这和registry一样,docker模式使用https方式,而我们使用的是http的方式登录
修改Docker配置
对于 Linux 系统,我们可以在
/etc/docker/daemon.json
(daemon.josn
文件不存在则新建该文件)
1 | vi /etc/docker/daemon.json |
添加下面的配置
1 | { "insecure-registries": ["harbor地址"] } |
完整的配置如下
1 | { |
执行以下命令重启重新加载配置并生效
1 | systemctl daemon-reload |
再次进行登录
1 | docker login -u admin -p Harbor12345 192.168.64.153 |
这次我们就成功登录了
到这里我们就已经登录成功了
修改镜像tag
我们推送镜像我要把我们的镜像名称改成符合规范的格式
1 | docker tag \ |
这里有一个
library
路径,是harbor默认的项目名称
推送镜像
可以通过
docker push
进行推送镜像,注意需要先登录在进行推送
1 | docker push 192.168.64.153/library/learn-docker-storage:0.0.3 |
到这里我们已经推送到了harbor,我们可以登录library页面查看
harbor 测试
删除本地镜像
可以通过
docker rmi 镜像ID
删除本地镜像
1 | docker rmi \ |
运行harbor 中的镜像
执行运行命令
1 | docker run -d \ |
访问微服务测试
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
查看harbor详情
详情里面会显示拉取次数
HarBor用户权限说明
HarBor用户角色在项目(项目-成员-新加成员)中为3类:项目管理员、开发人员、访客
- 项目管理员:增删改查
- 开发人员:上传和下载
- 访客:只允许下载
HarBor权限配置
新建用户
点击创建用户可以创建一个用户
我们创建一个itcast的用户
用户授权
创建用户后进入项目模块添加成员
选择成员后并选择权限
访客只能进行拉取不能推送和管理
用户登录测试
我们用
itcast
用户通过web端登录测试下,我们发现用户是没有修改权限的
docker登录测试
登录docker客户端
1 | docker login -u itcast -p Qwert123 192.168.64.153 |
尝试推送镜像
1 | docker push 192.168.64.153/library/learn-docker-storage:0.0.3 |
我们发现是无法进行推送镜像的
拉取镜像测试
先删除本地的容器以及镜像
1 | docker rm -f learn-docker-storage |
尝试拉取并启动本地镜像
1 | docker run -d \ |
微服务访问测试
1 | curl http://192.168.64.153:8003/storage/employe/findByID/10001 | python -m json.tool |
Harbor支持Https(扩展)
为了支持微服务推送我们需要将
HarBor
设置为https,可以让HarBor
在任何地方使用以及推送
生成SSL证书
前面说了怎么搭建harbor仓库,这里讲一讲harbor实现https访问,因为只需要内网访问,没必要去申请一个ssl证书,所以我就用
openssl
颁发自签名证书,实现https访问。
创建证书目录
1 | mkdir -p /tmp/data/cert && cd /tmp/data/cert && ll |
创建 CA 根证书
1 | openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt -subj "/C=CN/L=beijing/O=itcast/CN=harbor-registry" |
这里subj是主题的意思含义如下
1 | C=国家,S=省(市),L=区(县、市),O=组织机构,OU=组织单位,CN=通用名称 |
生成证书签名
生成一个证书签名, 设置访问域名为
itcastharbor.com
1 | openssl req -newkey rsa:4096 -nodes -sha256 -keyout itcastharbor.com.key -out server.csr -subj "/C=CN/L=beijing/O=itcast/CN=itcastharbor.com" |
生成主机证书
1 | openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out itcastharbor.com.crt |
操作步骤如下
配置harbor.yml
然后进入harbor安装目录修改
harbor.yml
,修改下面几个选项
- hostname,使用IP或域名,不要用回环地址,localhost等
- certificate,yourdomain.com.crt的路径
/tmp/data/cert/itcastharbor.com.crt
- private_key,yourdomainr.com.key的路径
/tmp/data/cert/itcastharbor.com.key
重新安装harbor服务
停止harbor
停止运行中的服务
1 | docker-compose down |
运行目录harbor下的prepare完成https的配置
1 | ./prepare |
重新安装
在harbor目录下运行安装命令
1 | ./install.sh |
修改Docker推送配置
我们需要将推送的IP改成域名
1 | vi /etc/docker/daemon.json |
上文中我们对registry已经操作了,这里需要改用harbor,需要重新配置
1 | #因为默认端口号是80 所以不需要加端口号 |
完整的配置如下
1 | { |
执行以下命令重启重新加载配置并生效
1 | systemctl daemon-reload |
修改本地host文件
为了让本机能够正常访问到harbor的web环境需要配置本地的hosts文件增加如下配置
1 | 192.168.64.153 itcastharbor.com |
windows环境下host路径在
C:\Windows\System32\drivers\etc
域名访问harbor
通过域名访问harbor,域名就是我们刚才配置的
itcastharbor.com
域名访
因为我们的证书是自签的,不是第三方认证的,素以有安全性提示,点击继续就可以访问
到这里登录后就可以访问了
微服务Docker打包
现在的微服务时代,你的代码没个微服务、分布式人家都会觉得低端,当然!对于我们开发人员来说,掌握这些技术意味着涨薪。
我们项目中用到了多个微服务,我们上一节课程打包用的是手动上传,但是很麻烦,有没有更好的方式呢,是有的,我们可以直接通过idea将我们的微服务打包成Docker镜像,并推送到Docker仓库中
这里我们采用jib-maven-plugin 来进行来构建容器化的spring boot应用程序,Jib可以让不写Dockerfile就能实现Docker打包
什么是Jib
Jib 是 Google 开发的可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库,以 Maven 和 Gradle 插件形式提供。
Jib带来的是,它允许您通过简单地将插件添加到您选择的构建工具(Maven或Gradle)来创建容器,没有额外的文件,只需几行配置,它处理将应用程序打包到容器映像的所有步骤。
Jib是来自Google的开源Java容器,它允许Java开发人员使用他们所知道的Java工具构建容器,它不需要您编写Dockerfile或安装了docker,它直接集成到Maven和Gradle中。
和传统的插件区别
Docker 构建流程
在“传统”Java到Docker映像构建流程中,我们需要安装Dockerfile和docker守护进程,在Jib构建流程中,您只需要插件项目的构建文件。
Jib构建流程
通过 Jib,Java 开发者可以使用他们熟悉的 Java 工具来构建容器。Jib 是一个快速而简单的容器镜像构建工具,它负责处理将应用程序打包到容器镜像中所需的所有步骤。它不需要你编写 Dockerfile 或安装 Docker,而且可以直接集成到 Maven 和 Gradle中 —— 只需要将插件添加到构建中,就可以立即将 Java 应用程序容器化。
准备工作
设置Horbor用户权限
我们要将idea的微服务推送到Harbor,并且用
itcast
的用户,所有我们要设置我们的itcast
用户是开发者
pom文件配置jib
对于应用程序的基本本地存储镜像,请在pom.xml以下内容中配置jib-maven-plugin
公共属性配置
在properties中配置
harbor
的共有配置
1 | <properties> |
编译配置插件配置
1 | <build> |
执行构建
然后在项目根目录执行
mvn clean compile jib:build
就可以了
我们看到已经推送成功了
harbor仓库中查看
通过域名访问harbor,我们看我们的
library
里面的镜像仓库
点进去就可以看到我们刚刚推送的镜像
以及镜像的详细信息
其他的微服务上传
微服务打包
这里我们也将其他微服务上传到仓库,步骤同上
仓库中查看镜像
在我们的仓库中查看镜像,我们看到镜像都已经上传到仓库中了
harbor 测试
删除本地镜像
可以通过
docker rmi 镜像ID
删除本地镜像
1 | docker rm -f learn-docker-storage |
运行harbor 中的镜像
我们把我们的所有微服务都上传到了仓库中,我们以一个完整的项目运行docker
运行learn-docker-storage服务
执行运行命令
1 | docker run -d \ |
因为我们是基于内部网络访问 不需要暴漏接口了
访问微服务测试
1 | curl http://192.168.64.152:8080/userinfo/10001 | python -m json.tool |
运行learn-docker-web服务
执行运行命令
1 | docker run -d \ |
该微服务也是内部服务不需要暴漏端口,并且没有配置日志输出所有不挂载日志路径
运行learn-docker-gateway服务
执行运行命令
1 | docker run -d \ |
因为网关对外需要暴漏端口,所有需要开放
8888
端口
查看nacos注册的微服务
我们发现我们的三个服务都已经注册进去了
访问测试微服务
因为我们存储服务的
8003
端口没有暴漏出来,无法访问,我们需要通过网关进行访问
1 | curl http://192.168.64.153:8888/employeapi/find/10001| python -m json.tool |
任务编排工具
我们发现我们现在管理微服务比较麻烦,现在只是三个微服务,如果更多会更加麻烦,怎么办呢,下面我们就来学习下docker编排工具
什么是任务编排
编排是一个新的词汇,经过阅读才明白编排指的是容器的集群化和调度。另一类含义指的是容器管理,负责管理容器化应用和组件任务。
docker毫无疑问是一个优秀的开源工具。但是,仅靠docker引擎和容器就不能进行复杂的应用程序部署。对于部署复杂的应用程序体系结构的容器群集,必须进行适当的配置。容器化的应用程序应该能够根据应用程序资源需求进行扩展和缩小。
需要考虑的因素
我们需要一个有效管理容器的良好框架。容器的生命周期很短,在进行容器编排时,要考虑的主要因素是
- 联网
- 高可用性
- 易于部署
- 良好的服务发现。
常见的任务编排工具
docker-compose
docker-compose是基于docker的编排工具,使容器的操作能够批量的,可视的执行,是一个管理多个容器的工具,比如可以解决容器之间的依赖关系,当在宿主机启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容器出错,这个时候推荐使用 dockerd的单机编排工具 docker-compose。
Kubernetes
Kubernetes是一个开源的,开箱即用的容器集群管理器和业务流程,它具有出色的构建 调度器 和资源管理器,用于以更有效和高度可用的方式部署容器。Kubernetes已成为许多组织事实上的容器编排工具,kubernetes项目由google与世界各地的贡献者维护,它提供了本机Docker工具不提供的许多功能。而且,使用kubernetes很容易上手。
OpenShift
Openshift建立在kubernetes之上。Openshift项目由Redhat维护。它同时具有开源(openshift orgin)和企业版(openshift容器平台)。连同核心的Kubernetes功能,它提供了用于容器管理和编排的开箱即用组件。
Docker Swarm
Docker生态系统包括从开发到生产部署框架的工具。在该列表中,docker swarm适用于集群管理。可以使用docker-compose,swarm,overlay网络和良好的服务发现工具(例如etcd或consul)的组合来管理Docker容器集群。
与其他开源容器集群管理工具相比,Docker swarm在功能方面仍日趋成熟。考虑到庞大的Docker贡献者,Docker swarm拥有其他工具拥有的所有最佳功能不会太久。Docker记录了在生产中使用docker swarm 的良好生产计划。
环境准备
我们这里面主要讲解
docker-compose
、swarm
的编排工具
搭建Horbor仓库
我们刚才讲解了本地搭建Horbor仓库,但是我们本地搭建很占用资源,我们用了一台服务器专门来做Horbor的仓库,地址是
https://manager-hongbaoyu-java.itheima.net:8443/
停止本地Harbor
因为使用了单独的Harbor服务器,本地的Harbor就可以停掉了
1 | cd /usr/local/harbor/harbor/ && docker-compose down |
清理Docker环境
清理本地环境
因为使用任务编排,本地的服务都可以删除掉了
1 | # 停止并删除所有容器 |
查看本地环境
可以查看下本地的Docker环境
1 | docker ps -a |
删除网络配置
因为我们自己配置了Docker网络,我们删除掉
1 | docker network rm learn-docker-network |
修改Docker配置
因为我们使用了独立的Horbor仓库,可以将配置到Docker中的本地仓库地址替换为新的仓库地址
修改daemon
1 | # 修改daemon文件删除本地仓库地址 |
在
daemon.json
中增加如下内容
1 | "insecure-registries": ["manager-hongbaoyu-java.itheima.net:8443"], |
查看修改
1 | # 查看daemon配置 |
新的仓库地址是
manager-hongbaoyu-java.itheima.net:8443
重启Docker
1 | systemctl daemon-reload |
初始化镜像
将服务器的需要的镜像初始化
1 | docker pull mysql:5.7.33;\ |
docker-compose容器编排
为什么使用docker-compose
我们学会了使用 dockerfile 构建 docker 镜像,看起来已经能够满足我们的日常需求了,无论需要什么环境,在 dockerfile 里逐步构建,然后 build、run,就 ok 了,也满足了我们docker 隔离性、快速部署的要求,为什么还需要docker-compose呢?
我们来看一个网站开发最常见的场景:我们要有数据库,网站应用,nginx,互相配合才是完整的环境。是的,我们完全可以以 ubuntu 为基础镜像,把这些一股脑全装进去,然后运行。但是这样有很多缺点,比如我们每次都要重新装 mysql 而不是直接利用 mysql 官方的基础镜像,升级维护不方便;如果我们的应用要扩展也很难,因为每个应用都连接的自己内部的数据库,无法共享数据;事实上,这种方式是典型的虚拟机的使用方式,不是 docker 的正确打开方式
docker 是轻量化的应用程序,docker 官方推荐每个 docker 容器中只运行一个进程,那么就是说,我们需要分别为我们的应用、数据库、nginx 创建单独的 docker 容器,然后分别启动它。想象一下,构建好 docker 之后,每次启动我们的网站,都要至少 docker run 三次,是不是很繁琐?而且此时这几个 docker 是分散独立的,很不方便管理。既然这几个 docker 都是为了同一个网站服务,是不是应该把它们放到一起?这就引出了 docker-compose 项目。
什么是docker-compose
docker-compose是 docker 官方的开源项目,使用 python 编写,实现上调用了 Docker 服务的 API 进行容器管理。其官方定义为为 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)),其实就是上面所讲的功能。
安装Docker-Compose
Docker Compose是一个用来定义和运行复杂应用的Docker工具,一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。
Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。
查找最新版的docker-compose
到 https://github.com/docker/compose/releases/ 地址查找最新的docker-compose版本
安装docker-compose
下载最新版的docker-compose文件
1 | sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose |
添加可执行权限
1 | sudo chmod +x /usr/local/bin/docker-compose |
测试安装结果
1 | docker-compose --version |
docker-compose概述
类似 docker 的Dockerfile文件,docker-compose使用 YAML 文件对容器进行管理。
相关概念
对于 docker-compose 有两个基本的概念:
- 服务(service):一个应用容器,即 docker 容器,比如之前所说的mysql 容器、nginx 容器
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,比如上面所讲的由 mysql、web app、nginx 容器组成的网站。docker-compose 面向项目进行管理。
YAML 文件格式
- 大小写敏感,缩进表示表示层级关系
- 缩进空格数不重要,相同层级左侧对齐即可。(不允许使用 tab 缩进!)
- 由冒号分隔的键值对表示对象;一组连词线开头的行,构成一个数组;字符串默认不使用引号
Compose和Docker兼容性
Docker Engine 与docker-compose version 之间的有以下关系
compose文件格式版本 | docker版本 |
---|---|
3.4 | 17.09.0+ |
3.3 | 17.06.0+ |
3.2 | 17.04.0+ |
3.1 | 1.13.1+ |
3 | 1.13.0+ |
2.3 | 17.06.0+ |
2.2 | 1.13.0+ |
2.1 | 1.12.0+ |
2 | 1.10.0+ |
1 | 1.9.1.+ |
基本使用
接下来我们使用 docker-compose 构建我们的微服务以及mysql,并逐步讲解其使用。
准备工作
在项目文件夹下创建 docker-compose.yml文件
1 | cd /usr/local/docker-learn/ && touch docker-compose.yml && ll |
编写配置文件
先在 docker-compose.yml 文件里添加如下代码,构建我们的项目
1 | version: '2' |
运行测试
在项目的文件中执行
docker-compose up -d
命令就可以启动了
1 | docker-compose up -d |
微服务访问测试
通过网关地址访问测试微服务
1 | curl http://192.168.64.153:8888/employeapi/find/10001| python -m json.tool |
参数解释(手册)
version
指定 docker-compose.yml 文件的写法格式
docker-compose.yml
的version版本号应该和docker的版本进行匹配,如果不匹配可能出现问题。
services
表示多个容器的集合
服务对象
docker-compose.yml管理是以服务为单位管理的,一个services下面可以有多个服务,mysql,app都代表一个服务
image
image是指定服务的镜像名称或镜像 ID,如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
hostname
配置容器的host名称,在容器的hosts文件中加入了映射
container_name
配置启动后的容器名称和docker的--name xxx
效果是一样的
restart
restart参数能够使我们在重启docker时,自动启动相关容器,和docker的
--restart
效果一致Docker容器的重启策略如下
- no,默认策略,在容器退出时不重启容器
- on-failure,在容器非正常退出时(退出状态非0),才会重启容器
- on-failure:3,在容器非正常退出时重启容器,最多重启3次
- always,在容器退出时总是重启容器
- unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
ports
映射端口的标签,对外暴露的端口定义,和 expose 对应,和docker的
-p
效果一致
depends_on
这个是依赖配置的选项,意思是如果 服务启动是如果有依赖于其他服务的,先启动被依赖的服务,启动完成后在启动该服务
networks
配置容器所使用的网络
volumes
挂载一个目录或者一个已存在的数据卷容器,和docker
-v
效果一致
environment
配置环境变量,和docker的
-e
效果一致
常用命令
docker-compose up
用于部署一个 Compose 应用
默认情况下该命令会读取名为 docker-compose.yml 或 docker-compose.yaml 的文件
,用户也可以使用 -f 指定其他文件名。通常情况下,会使用 -d 参数令应用在后台启动。
docker-compose stop
停止 Compose 应用相关的所有容器,但不会删除它们。
被停止的应用可以很容易地通过 docker-compose restart 命令重新启动。
如果带有服务命则停止该服务 ,否则停止所有服务
docker-compose rm
用于删除已停止的 Compose 应用。
它会删除容器和网络,但是不会删除卷和镜像。
如果带有服务命则删除该服务 ,否则删除所有服务
docker-compose restart
重启已停止的 Compose 应用。
如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中,这时需要重新部署应用使变更生效。
docker-compose ps
用于列出 Compose 应用中的各个容器。
输出内容包括当前状态、容器运行的命令以及网络端口。
docker-compose down
停止并删除运行中的 Compose 应用。
它会删除容器和网络,但是不会删除卷和镜像。
扩缩容
nacos查看集群情况
我们可以查看nacos,查看当服务器集群的一个部署情况
扩容节点
我们现在对
learn-docker-storage
节点进行扩容语法格式:
docker-compose up -d --scale 服务名=节点数
1 | docker-compose up -d --scale learn-docker-storage=2 |
启动后查看nacos节点信息
缩容节点
和扩容一样指定节点数量就可以的
1 | docker-compose up -d --scale learn-docker-storage=1 |
停止后后查看nacos节点信息
Swarm集群编排
什么是Swarm
Swarm是Docker公司自研发的容器集群管理系统,Swarm在早期是作为一个独立服务存在,在Docker Engine v1.12中集成了Swarm的集群管理,和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。
Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务,也增加了服务栈(Stack)、服务(Service)、任务(Task)概念
Swarm能干什么
Swarm是Docker 引擎内置(原生)的集群管理和编排工具。Docker Swarm是 Docker 官方三剑客项目之一,swarm是基于docker平台实现的集群技术,他可以通过几条简单的指令快速的创建一个docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。
swarm节点
swarm是一系列节点的集合,而节点可以是一台裸机或者一台虚拟机。一个节点能扮演一个或者两个角色,manager或者worker。
manager节点
Docker Swarm集群需要至少一个manager节点,节点之间使用**
Raft consensus protocol
**进行协同工作。
通常,第一个启用docker swarm的节点将成为leader,后来加入的都是follower。当前的leader如果挂掉,剩余的节点将重新选举出一个新的leader。
每一个manager都有一个完整的当前集群状态的副本,可以保证manager的高可用。
worker节点
worker节点是运行实际应用服务的容器所在的地方。理论上,一个manager节点也能同时成为worker节点,但在生产环境中,我们不建议这样做。
worker节点之间,通过control plane
进行通信,这种通信使用gossip
协议,并且是异步的。
运行机制
名词解释
集群中经常谈到的stacks, services, tasks,他们之间的关系。
下面简单解释一下这三者的含义:
task
在Docker Swarm中,task是一个部署的最小单元,task与容器是一对一的关系。
services
swarm service是一个抽象的概念,它只是一个对运行在swarm集群上的应用服务,所期望状态的描述。它就像一个描述了下面物品的清单列表一样:
- 服务名称
- 使用哪个镜像来创建容器
- 要运行多少个副本
- 服务的容器要连接到哪个网络上
- 应该映射哪些端口
stack
stack是描述一系列相关services的集合。我们通过在一个YAML文件中来定义一个stack。
工作原理
服务、任务和容器
当将服务部署到集群时,管理者将服务定义视为服务所需状态。然后将服务调度为一个或多个副本任务。这些任务在集群的节点上彼此独立运行。
例如下图有三个副本的HTTP服务,每个服务实例就是一个任务。
容器是一个独立的进程,在swarm模型中,每个任务调用一个容器。任务类似于插槽,调度器将容器放入其中。一旦容器运行,调度器认为该任务处于运行状态。如果容器出现健康监测失败或者终止,那么任务也终止。
副本和全局服务
有两种类型的服务部署:副本和全局。
对于副本服务,指定要运行的相同任务的数量,每个副本都是相同的内容。
全局服务是在每个节点上运行一个任务的服务。不需要预先指定任务数量。每当将一个节点添加到集群中,协调者将创建一个任务,并且调度器将任务分配给该新加入的节点。全局服务最好是监控代理、反病毒扫描程序等等想要在集群中每个节点上运行的容器。
下图显示三个副本服务(黄色)和全局服务(灰色):
功能特点(了解)
集成的集群管理
使用Docker Engine CLI创建一组Docker引擎,您可以在其中部署应用程序服务。您不需要其他编排软件来创建或管理群集。
节点分散式设计
Docker Engine不是在部署时处理节点角色之间的差异,而是在运行时处理角色变化。您可以使用Docker Engine部署两种类型的节点,管理节点和工作节点。这意味着您可以从单个服务器构建整个群集。
声明性服务模型
Docker Engine使用声明性方法来定义应用程序堆栈中各种服务的所需状态。例如,您可以描述由具有消息队列服务和数据库后端的Web前端服务组成的应用程序。
可扩容与缩放容器
对于每个服务,您可以声明要运行的任务数。当您向上或向下缩放时,swarm管理器通过添加或删除任务来自动适应,以保持所需的任务数量来保证集群的可靠状态。
容器容错状态协调
群集管理器节点不断监视群集状态,并协调您表示的期望状态的实际状态之间的任何差异。
例如,如果设置一个服务以运行容器的10个副本,并且托管其中两个副本的工作程序计算机崩溃,则管理器将创建两个新副本以替换崩溃的副本。 swarm管理器将新副本分配给正在运行和可用的worker节点上。
多主机网络
您可以为服务指定覆盖网络。当swarm管理器初始化或更新应用程序时,它会自动为覆盖网络上的容器分配地址。
服务发现
Swarm管理器节点为swarm中的每个服务分配唯一的DNS名称,并负载平衡运行的容器。您可以通过嵌入在swarm中的DNS服务器查询在群中运行的每个容器。
负载平衡
您可以将服务的端口公开给外部负载平衡器。在内部,swarm允许您指定如何在节点之间分发服务容器。
缺省安全
群中的每个节点强制执行TLS相互验证和加密,以保护其自身与所有其他节点之间的通信。您可以选择使用自签名根证书或来自自定义根CA的证书。
滚动更新
在已经运行期间,您可以增量地应用服务更新到节点。 swarm管理器允许您控制将服务部署到不同节点集之间的延迟。如果出现任何问题,您可以将任务回滚到服务的先前版本。
准备环境
服务器准备
我的三台测试机
IP地址 | 角色 | 主机名 |
---|---|---|
192.168.64.153 | manager | node1 |
192.168.64.154 | worker | node2 |
192.168.64.155 | worker | node3 |
服务器端口开放
在创建集群前,如果开启了防火墙,请确认三台主机的防火墙能让swarm需求的端口开放,需要打开主机之间的端口,以下端口必须可用。在某些系统上,这些端口默认为打开。
- 2377:TCP端口2377用于集群管理通信
- 7946:TCP和UDP端口7946用于节点之间的通信
- 4789:TCP和UDP端口4789用于覆盖网络流量
可以直接禁用系统防火墙来让这些端口通信不受限制,一般测试环境我们都会禁用防火墙
1 | systemctl stop firewalld(立即生效) |
搭建Swarm集群
当首次安装并使用Docker Engine时,默认情况下swarm模式是禁用的。当启用swarm模式时,可以使用docker service 服务管理命令。
有两种方式在swarm模式下运行引擎:
创建一个新的集群
加入现有集群
在生成环境中,集群模式提供具有集群管理功能的容错平台,以保证服务的可靠运行。
下面我们就来搭建一个
swarm
集群
初始化集群
1 | docker swarm init --advertise-addr 192.168.64.153(本机地址) |
生成口令
生成管理节点口令
1 | docker swarm join-token manager |
生成执行节点口令
1 | docker swarm join-token worker |
其他节点加入集群
在第一个从节点执行加入 work的指令
1 | docker swarm join --token SWMTKN-1-53p5t2rt9ud5j0owkl14boj2z8im6r60ddlzotgc4a8y93u1c2-8f6crxgyc9umayhxva1jv9t1w 192.168.64.153:2377 |
第二个节点执行加入work的命令
1 | docker swarm join --token SWMTKN-1-53p5t2rt9ud5j0owkl14boj2z8im6r60ddlzotgc4a8y93u1c2-8f6crxgyc9umayhxva1jv9t1w 192.168.64.153:2377 |
查看swarm的节点
执行
docker node ls
查看swarm节点信息
1 | docker node ls |
AVAILABILITY状态说明
- Active 意味着调度程序可以将任务分配给节点。
- Pause 意味着调度程序不会将新任务分配给节点,但现有任务仍在运行。
- Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们。
MANAGER STATUS状态说明
显示节点是属于manager或者worker
- 没有值 :表示不参与群管理的工作节点。
- Leader :意味着该节点是使得群的所有群管理和编排决策的主要管理器节点。
- Reachable: 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用,则该节点有资格被选为新领导者。
- Unavailable :意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用,您应该将新的管理器节点加入群集,或者将工作器节点升级为管理器。
修改主机名
默认
centos
的主机名是localhost
,我们看上面,节点的主机名都是localhost
,我们修改以下
查看主机名
hostnamectl status
可以查看主机名
1 | hostnamectl status |
修改主机名
修改主机名使用
hostnamectl set-hostname NAME
命令可以进行修改,我们使用 node1,node2…方式命名我们的节点
1 | #修改主机名 |
其他节点依次操作就可以
再次查看节点
再次查看swarm节点信息
1 | docker node ls |
添加节点标签
因为我们用到了节点约束,所有启动服务之前需要添加节点标签
1 | # 添加标签 |
管理节点
升降级节点
无论您升级或降级节点,您应该始终在群中维护奇数个管理器节点,
升降级节点角色只能在管理节点上运行,应先升级工作节点为被选举者,再降级领导者为工作节点,然后被选举者成为领导者完成替换;
您可以将工作程序节点提升为manager角色。这在管理器节点不可用或者您希望使管理器脱机以进行维护时很有用。 类似地,您可以将管理器节点降级为worker角色。
升级节点
要降级一个节点或一组节点,请从管理器节点运行
1 docker node promote 节点名称
1 | docker node promote pbui0rdry85e25i3bvhzmqw8h |
升级节点后不会马上生效,会进入
Reachable
状态,如果leader节点关掉,当前节点会参与主节点竞争
降级节点
要升级一个节点或一组节点,请从管理器节点运行
1 docker node demote 节点名称
1 | docker node demote r7cv7prw1h2to9h1cpwxs9jhl |
swam将节点降级后,再次查看节点命令不生效,需要到管理节点查看
节点退出swarm集群
docker swarm leave 命令可在所有节点上运行,值得注意的是,工作节点退出swarm集群后,在管理节点上依然保存着工作节点的节点信息,状态为down,要删除节点信息,可使用docker node rm 命令,当所有的节点都退出并且被删除时,在管理节点上使用docker swarm leave,然后退出整个集群;
工作节点
在工作节点执行以下命令可以退出
swarm
节点
1 | docker swarm leave |
管理节点
在管理节点查看节信息
1 | docker node ls |
根据退出节点前后查看节点信息,可以发现退出的节点是down的状态,并没有删除节点
删除节点信息
在管理节点执行删除命令
docker node rm 节点ID
1 | docker node rm r7cv7prw1h2to9h1cpwxs9jhl |
管理集群服务
管理集群服必须在manager角色的主机上
创建overlay网络
我们需要载多个服务器中运行Docker容器集群,需要使用overlay网络,overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密
1 | docker network create --driver overlay learn-docker-overlay-network |
创建服务
使用
docker service create
命令来创建服务
创建MySQL服务
1 | docker service create \ |
–replicas 1 表示在集群中创建1个服务
node.labels.role == data
表示节点需要创建在标签是data
的节点上
可以查看swarm的进程
1 | docker service ls |
创建nacos服务
nacos也是需要创建一个,但是节点是可以漂移的,不需要固定在某一台机器
1 | docker service create \ |
可以查看swarm的进程
1 | docker service ls |
我们发现nacos运行在了 node3节点上
创建learn-docker-storage服务
我们创建learn-docker-storage服务,我们将该服务部署两个节点
1 | docker service create \ |
可以查看swarm的进程
1 | docker service ls |
我们发现我们的存储服务运行在两个节点上
创建learn-docker-web服务
我们创建learn-docker-web服务,我们将该服务同样部署两个节点
1 | docker service create \ |
可以查看swarm的进程
1 | docker service ls |
创建learn-docker-gateway服务
我们创建learn-docker-gateway服务,因为是网关服务,我们只创建一个节点,因为需要对外暴漏端口,需要开放8888端口
1 | docker service create \ |
可以查看swarm的进程
1 | docker service ls |
测试访问微服务
因为在
node2
节点上,node2
节点IP是192.168.64.154
我们可以请求URL访问
1 | curl http://192.168.64.154:8888/employeapi/find/10001| python -m json.tool |
查看某个服务日志
通过
docker service logs 服务命
可以看到当前服务的日志,但是这个服务有两个容器在运行,所有能同时看到两个容器的日志
1 | docker service logs learn-docker-storage |
扩缩容服务
可以通过集群操作对集群进行扩缩容
扩容操作
我们将
learn-docker-storage
由两个容器变为三个容器
1 | docker service scale learn-docker-storage=3 |
这样我们就把存储服务变成了三台服务
缩容操作
同样,使用该命令对
learn-docker-storage
进行缩容
1 | docker service scale learn-docker-storage=2 |
删除服务
我们可以尝试把
learn-docker-gateway
删除掉,删除操作将会把整个服务的所有容器删除
1 | docker service rm learn-docker-gateway |
Docker Stack管理服务
我们上面使用
swarm
部署服务,单个服务还好,如果很多个服务怎么来解决呢,这里就用到了Docker Stack
管理服务。
在上面我们学会了如何配置一个swarm集群,并且知道如何在swarm集群上部署应用,现在,我们开始了解Docker层级关系中的最高一个层级——stack。一个stack就是一组有关联的服务的组合,可以编排在一起,一起管理。
单机模式下,我们可以使用 Docker-Compose来编排多个服务,而 Docker Swarm 只能实现对单个服务的简单部署。于是就引出了本文的主角 Docker Stack ,通过 Docker Stack 我们只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排。
集群搭建案例
应用部署情况
服务名称 | 数量 |
---|---|
mysql | 1 |
nacos | 1 |
learn-docker-gateway | 1 |
learn-docker-web | 2 |
learn-docker-storage | 2 |
创建docker-compose.yml
首先创建一个 docker-compose.yml 文件,使用 Docker Compose v3 语法
我们把我们原来单机版的
docker-compose.yml
改造以下
1 | version: '3.9' |
配置介绍
Stack文件就是Docker Compose文件。唯一的要求就是version:一项需要是3.0或者更高的值。在Docker根据某个Stack文件部署应用的时候,首先会检查并创建networks:关键字对应网络。如果网络不存在,Docker会进行创建。下面我们详细看下这几个模块。
overlay网络
这里定义了1个网络,默认情况下网络都是使用overlay驱动,新建对应的覆盖类型的网络。
1 | networks: |
部署节点副本数
接下来我们进一步了解deploy关键字新增的内容
1 | deploy: |
- replicas: 2 设置了期望服务的副本数量为2,默认为1.如果服务正在运行,需要调整副本数。可以调整stack文件中的 replicas 的数值,然后重新部署stack。重新部署stack并不会影响那些没有改动的服务。
- restart_policy: 定义了Swarm针对容器异常退出的重启策略。当前服务的重启策略是:如果某个副本以非0返回值退出,会立即重启当前副本。重启最多尝试3次,每次都是等待之多120s来检测是否成功。每次重启的间隔是5s。
节点约束
因为我们的数据库节点只能部署在数据节点,因为需要挂载本地的数据文件以及数据库文件,所有需要使用标签进行节点约束
1 | mysql: |
这里的
'node.labels.role == data
含义就是将当前mysql节点约束在标签名字是role,并且值是data的数据节点,更多操作请参考下文
部署服务
部署应用
使用docker stack deploy 命令部署
1 | docker stack deploy -c docker-compose.yml learn-docker-test |
这里我们指定了docker-compose文件,并把stack命名为 learn-docker-test。
查看部署情况
可以通过
docker stack ls
命令查看集群部署情况,会列出 Swarm 集群中的全部 Stack,包括每个 Stack 拥有多少服务
服务部署情况
查看nacos节点信息
访问nacos服务,发现我们的服务都已经注册
测试访问服务
访问服务接口测试
1 | curl http://192.168.64.153:8888/employeapi/find/10001| python -m json.tool |
集群管理
更新服务
docker service upadte
可以对swarm服务进行升级
参数详解
- –force 强制更新重启服务,无论是否配置或镜像改变都更新
- –image image:tag 制定更新的镜像
- –with-registry-auth 向 Swarm 代理发送 Registry 认证详细信息,私有仓库需要携带该参数
更新镜像
1 | #查看服务详情 |
删除应用
查看部署集群
docker stack ls
可以查看部署的服务列表
执行删除
docker stack rm stack名称
命令会删除整个stack集群,注意移除操作执行前并不会进行二次确认。
1 | docker stack rm learn-docker-test |
相关命令(手册)
docker stack 常用命令
命令 | 说明 |
---|---|
docker stack deploy | 部署新的堆栈或更新现有堆栈 |
docker stack ls | 列出现有堆栈 |
docker stack ps | 列出堆栈中的任务 |
docker stack rm | 删除堆栈 |
docker stack services | 列出堆栈中的服务 |
docker stack down | 移除某个堆栈(不会删除数据) |
docker service 常用命令
命令 | 说明 |
---|---|
docker service create | 部署服务 |
docker service inspect | 查看服务详情 |
docker service logs | 产看某个服务日志 |
docker service ls | 查看所有服务详情 |
docker service rm | 删除某个服务(-f 强制删除) |
docker service scale | 设置某个服务个数 |
docker service update | 更新某个服务 |
docker node 常用命令
命令 | 说明 |
---|---|
docker node ls | 查看所有集群节点 |
docker node rm | 删除某个节点(-f 强制删除) |
docker node inspect | 查看节点详情 |
docker node demote | 节点降级,由管理节点降级为工作节点 |
docker node promote | 节点升级,由工作节点升级为管理节点 |
docker node update | 更新节点 |
docker node ps | 查看节点中的 Task 任务 |
docker swarm 常用命令
命令 | 说明 |
---|---|
docker swarm init | 初始化集群 |
docker swarm join-token worker | 查看工作节点的 token |
docker swarm join-token manager | 查看管理节点的 token |
docker swarm join | 加入集群中 |
portainer集群管理(扩展)
Portainer介绍
Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer可以轻松构建,管理和维护Docker环境。 而且完全免费,基于容器化的安装方式,方便高效部署。
Portainer 的目的是部署和使用一样简单。它由一个可以在任何 Docker 引擎上运行的单一容器组成(可以部署为Linux容器或Windows本地容器,也支持其他平台)。Portainer允许你管理所有的Docker资源(容器、镜像、卷、网络等等)。它与独立的Docker引擎和Docker Swarm模式兼容。
swarm集群安装Portainer
使用swarm集群安装Portainer,用Portainer来管理swarm集群
1 | # 下载部署配置文件 |
注意:此方法将自动部署Portainer服务器的单个实例,并将Portainer代理作为全局服务部署到集群中的每个节点上。
portainer使用
注册用户
默认访问接口是9000端口,可以通过浏览器进行访问,首次登陆需要注册用户,给admin用户设置密码
查看管理服务
点击home节点,当前这个节点就是我们的swarm集群
点进去就可以看到我们能操作的菜单了
查看swarm节点
点击swarm菜单就可以看到swarm节点了
管理微服务
服务部署情况
我们要将我们的服务交给portainer管理
服务名称 | 数量 |
---|---|
mysql | 1 |
nacos | 1 |
learn-docker-gateway | 1 |
learn-docker-web | 2 |
learn-docker-storage | 2 |
准备工作
管理节点标签
我们MySQL需要部署在数据节点,我们添加节点标签
在swarm管理节点,点击节点信息进入下面详情页面进行配置标签
添加网络信息
因为我们的节点需要一个共有的
overlay
网络,我们需要配置下,在network节点点击添加
在添加页面选择
overlay
网络类型,名字叫做learn-docker-network
然后点击创建就可以
创建仓库配置
因为我们的微服务需要从我们自己的harbor镜像仓库拉取,需要将我们的仓库配置
在仓库节点填写我们的镜像地址就可以
https://manager-hongbaoyu-java.itheima.net:8443
创建stack任务
在stack界面点击stack菜单进行添加stck任务
在stack管理界面将我们的
docker-compose.yml
复制进我们的stack界面
点击创建节点信息就可以,等待部署就可以
稍等下节点就部署完成了
点击进去就可以单到节点详情了
查看节点部署情况
进入swarm管理界面
点击
Go to cluster visualizer
查看服务部署情况
docker 问题
1.docker image报错
1 | cannot connect to the docker daemon at unix:///var/run/docker.sock.Is the docker daemon running?、 |
重启一下就行