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的你的存储库。
docker login
出现 Login Succeeded 就说明我们登录成功 注:你的身份验证凭证将被存储在你本地目录的 .dockercfg 文件中
管理镜像
通过 docker images 可以看到我们所有的镜像列表
docker images
删除镜像 我们现在的 learn-docker-storage 有三个版本,现在我们把前两个有问题的版本删除, docker rmi 镜像ID 可以删除镜像
docker rmi learn-docker-storage:0.0.1 learn-docker-storage:0.0.2
这样我们就删除了我们没有用的镜像了,可以节省内存空间 修改镜像命名 修改镜像的 repository 使之与 Docker Hub 账号匹配。 Docker Hub 为了区分不同用户的同名镜像,镜像的 registry 中要包含用户名,完整格式为: [用户 名]/镜像名:tag
我们通过 docker tag 命令重命名镜像
docker tag learn-docker-storage:0.0.3 liggdocker/learn-docker-storage:0.0.3
这样就将我们的镜像改名了,这个就符合我们的dockerhub的规范了
推送镜像
推送镜像 现在我们要将我们的镜像推送到 docker hub 推送镜像的规范是 docker push 注册用户名/镜像名:tag ,因为我们上面已经把镜像名字改正确了,所以可以直接推送。
docker push liggdocker/learn-docker-storage:0.0.3
这样我们就将我们的数据推送到docker hub,我们发现只有最顶层的镜像推送了,openjdk的镜像并没有推送,直接复用了仓库的,这就是分层的好处 检查镜像 我们可以到 docker hub 检查我们的镜像 可以看到我们的镜像已经推送过来了,点开详情可以看到我们镜像的内容以及tag号
仓库镜像测试
删除本地镜像 可以通过 docker rmi 镜像ID 删除本地镜像
docker rmi liggdocker/learn-docker-storage:0.0.3 learn-docker-storage:0.0.3
再次查看本地镜像,已经没有了我们的微服务的镜像
docker images
从仓库拉取镜像 这个时候可以从 docker hub 拉取镜像
docker pull liggdocker/learn-docker-storage:0.0.3
这个时候已经将镜像拉取下来了,我们可以运行镜像了 运行镜像 执行下面的命令进行创建镜像
docker run -d \
-v /opt/docker/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
liggdocker/learn-docker-storage:0.0.3
访问测试 我们访问下,检查下是否可以正常运行
curl http://192.168.10.30:8003/storage/employe/findByID/10001 | python -m json.tool
到这里我们就完成dockerhub仓库的发布与拉取 直接运行测试 在真实环境中,我们一般不会拉取再运行,一般都是直接运行,如果docker检查镜像不存在会自动拉取 停止服务并删除镜像
docker rm -f learn-docker-storage
docker rmi liggdocker/learn-docker-storage:0.0.3
我们直接运行容器
docker run -d \
-v /opt/docker/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
liggdocker/learn-docker-storage:0.0.3
这一个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 参数将镜像文件存放在本地的指定路径。
docker run -d \
-p 5000:5000 \
-v /opt/docker/data/registry:/var/lib/registry \
--restart=always \
registry
这样我们的registry已经启动起来了
访问测试 这时我们可以通过浏览器访问 http://ip:5000/v2/_catalog 查看仓库是否启动成功。
curl http://192.168.10.30:5000/v2/_catalog
上传镜像
registry 上传镜像的命名规范是 仓库IP:5000/镜像名称:tag 修改镜像名称 将我们的镜像改成服务规范的名字
docker tag liggdocker/learn-docker-storage:0.0.3 192.168.10.30:5000/learn- docker-storage:0.0.3
推送镜像 使用命令推送镜像
docker push 192.168.10.30:5000/learn-docker-storage:0.0.3
我们发现推送报错了,这是因为docker推送默认使用的https的方式,而我们的registry只支持http的方式 修改Docker推送配置 对于 Linux 系统,我们可以在 /etc/docker/daemon.json ( daemon.josn 文件不存在则新建该文件)
vi /etc/docker/daemon.json
添加下面的配置
{ "insecure-registries": ["仓库IP:5000"] }
完整的配置如下
{
"insecure-registries": ["192.168.10.30:5000"],
"registry-mirrors": ["https://ffunzkst.mirror.aliyuncs.com"]
}
执行以下命令重启重新加载配置并生效
systemctl daemon-reload
service docker restart
再次进行推送 执行命令再次推送
docker push 192.168.10.30:5000/learn-docker-storage:0.0.3
我们发现这次推送成功了 再次访问registry 访问测试检查是否已经推送
curl http://192.168.10.30:5000/v2/_catalog | python -m json.tool
我们发现我们的镜像已经推送到了registry,我们通过以下URL访问下tag列表
curl http://192.168.10.30:5000/v2/learn-docker-storage/tags/list | python -m json.tool
registry镜像测试 删除本地镜像 可以通过 docker rmi 镜像ID 删除本地镜像
docker rmi liggdocker/learn-docker-storage:0.0.3 192.168.10.30:5000/learn- docker-storage:0.0.3
运行registry中的镜像
docker run -d \
-v /opt/docker/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.10.30:5000/learn-docker-storage:0.0.3
curl http://192.168.10.30: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官方地址:https://github.com/goharbor/harbor/releases 下载最新版安装包 准备环境 需要安装docker以及docker-compose的环境上面我们已提前安装了
- 安装Docker环境
- 安装docker-compose环境
离线安装
解压harbor的安装包
[root@linux30 docker]
https://github.com/goharbor/harbor/releases/download/v2.3.3/harbor-offline-
installer-v2.3.3.tgz
[root@linux30 docker]
进入目录 然后将 harbor.yml.tmp 复制一份并该命为 harbor.yml
cd harbor
cp harbor.yml.tmpl harbor.yml
注意: 这里跟老版本不一样,没有了harbor.cfg文件,我们需要手动复制harbor.yml.tmpl再做修改即可 修改harbor.yml harbor作为私有仓库作用在公司内网,一般都是信任关系,没多大必要做https,使用http即可! 所以 把https相关的已经注释掉 并注意配置文件的用户名密码配置,默认是 用户名是:admin,密码是:Harbor12345,如果修改需要安装前修改 加载本地镜像 使用 docker load 命令加载本地镜像,不用再从dockerhub下载了
[root@linux30 harbor]
这样容器镜像就被加载到了本地,我们可以通过 docker images 命令查看导入的镜像
docker images
执行安装命令 先执行预处理命令,会创建一些文件夹,初始化一些文件
./prepare
然后开始真正的安装过程
./install.sh
如果出现 -Harbor has been installed and started successfully 表示安装成功,并查看docker进程
docker ps
可以看到很多服务已经起来了。
启动和停止harbor
在harbor的安装目录执行以下命令就可以启动和停止了
docker-compose up -d
docker-compose stop
docker-compose restart
harbor使用 访问harbor 输入 http://harborIP 就可以直接访问了,这里访问我们的地址 http://192.168.10.30/ 输入用户名密码就可以登录了 ,如果没有修改配置文件 默认是 用户名是:admin,密码是: Harbor12345 登录后就可以进行操作了 Docker登录harbor 使用docker login命令就可以登录harbor了
docker login -u admin -p Harbor12345 192.168.10.30
我们发现登录报错了,这和registry一样,docker模式使用https方式,而我们使用的是http的方 式登录 修改Docker配置 对于 Linux 系统,我们可以在 /etc/docker/daemon.json ( daemon.json 文件不存在则新建 该文件)
vi /etc/docker/daemon.json
添加下面的配置
{ "insecure-registries": ["harbor地址"] }
完整的配置如下
{
"insecure-registries": ["192.168.10.30"],
"registry-mirrors": ["https://ffunzkst.mirror.aliyuncs.com"]
}
执行以下命令重启重新加载配置并生效
systemctl daemon-reload
service docker restart
[root@linux30 harbor]
再次进行登录
docker login -u admin -p Harbor12345 192.168.10.30
这次我们就成功登录了 到这里我们就已经登录成功了 修改镜像tag 我们推送镜像我要把我们的镜像名称改成符合规范的格式
docker tag \
192.168.10.30:5000/learn-docker-storage:0.0.3 \
192.168.10.30/library/learn-docker-storage:0.0.3
这里有一个 library 路径,是harbor默认的项目名称 推送镜像 可以通过 docker push 进行推送镜像,注意需要先登录再进行推送
docker push 192.168.10.30/library/learn-docker-storage:0.0.3
到这里我们已经推送到了harbor,我们可以登录library页面查看
harbor 测试
删除本地镜像 可以通过 docker rmi 镜像ID 删除本地镜像
docker rmi \
192.168.10.30:5000/learn-docker-storage:0.0.3 \
192.168.10.30/library/learn-docker-storage:0.0.3
运行harbor 中的镜像 执行运行命令
docker run -d \
-v /opt/docker/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.10.30/library/learn-docker-storage:0.0.3
访问微服务测试
curl http://192.168.10.30:8003/storage/employe/findByID/10001 | python -m json.tool
HarBor用户权限说明
HarBor用户角色在项目(项目-成员-新加成员)中为3类:项目管理员、开发人员、访客
- 项目管理员:增删改查
- 开发人员:上传和下载
- 访客:只允许下载
HarBor权限配置
新建用户 点击创建用户可以创建一个用户 我们创建一个itcast的用户,密码是:itcastITCAST1 用户授权 创建用户后进入项目模块添加成员 选择成员后并选择权限 访客只能进行拉取不能推送和管理 用户登录测试 我们用 itcast 用户通过web端登录测试下,我们发现用户是没有修改权限的 docker登录测试 登录docker客户端
docker login -u itcast -p itcastITCAST1 192.168.10.30
尝试推送镜像
docker push 192.168.10.30/library/learn-docker-storage:0.0.3
我们发现是无法进行推送镜像的 拉取镜像测试 先删除本地的容器以及镜像
docker rm -f learn-docker-storage
docker rmi 192.168.10.30/library/learn-docker-storage:0.0.3
尝试拉取并启动本地镜像
docker run -d \
-v /opt/docker/logs:/logs \
-p 8003:8003 \
--name learn-docker-storage \
--network=learn-docker-network \
192.168.10.30/library/learn-docker-storage:0.0.3
微服务访问测试
curl http://192.168.10.30:8003/storage/employe/findByID/10001 | python -m json.tool
Harbor支持Https(扩展)
为了支持微服务推送我们需要将 HarBor 设置为https,可以让 HarBor 在任何地方使用以及推送
生成SSL证书 前面说了怎么搭建harbor仓库,这里讲一讲harbor实现https访问,因为只需要内网访问,没必要去申请一个ssl证书,所以我就用 openssl 颁发自签名证书,实现https访问。 创建证书目录
[root@linux30 docker]
[root@linux30 docker]
创建 CA 根证书
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是主题的意思含义如下
C=国家,S=省(市),L=区(县、市),O=组织机构,OU=组织单位,CN=通用名称
生成证书签名 生成一个证书签名, 设置访问域名为 itcastharbor.com
openssl req -newkey rsa:4096 -nodes -sha256 -keyout itcastharbor.com.key -out server.csr -subj "/C=CN/L=beijing/O=itcast/CN=itcastharbor.com"
生成主机证书
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等;itcastharbor.com
- certificate,yourdomain.com.crt的路径 /opt/docker/data/cert/itcastharbor.com.crt
- private_key,yourdomainr.com.key的路径/opt/docker/data/cert/itcastharbor.com.key
重新安装harbor服务 停止harbor 停止运行中的服务
docker-compose down
运行目录harbor下的prepare完成https的配置
./prepare
重新安装 在harbor目录下运行安装命令
./install.sh
修改Docker推送配置 我们需要将推送的IP改成域名
vi /etc/docker/daemon.json
上文中我们对registry已经操作了,这里需要改用harbor,需要重新配置
{ "insecure-registries": ["仓库IP或域名"] }
完整的配置如下
{
"insecure-registries": ["itcastharbor.com"],
"registry-mirrors": ["https://ffunzkst.mirror.aliyuncs.com"]
}
执行以下命令重启重新加载配置并生效
systemctl daemon-reload
service docker restart
[root@linux30 harbor]
修改本地host文件 为了让本机能够正常访问到harbor的web环境需要配置本地的hosts文件增加如下配置
192.168.10.30 itcastharbor.com
windows环境下host路径在 C:\Windows\System32\drivers\etc 域名访问harbor 通过域名访问harbor,域名就是我们刚才配置的 itcastharbor.com 域名访问 因为我们的证书是自签的,不是第三方认证的,所以有安全性提示,点击继续就可以访问 到这里登录后就可以访问了,用户名:admin,密码Harbor12345
微服务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 的共有配置
<docker.registry.url>itcastharbor.com</docker.registry.url>
<docker.registry.name>library</docker.registry.name>
<docker.registry.username>itcast</docker.registry.username>
<docker.registry.password>itcastITCAST1</docker.registry.password>
编译配置插件配置
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>2.8.0</version>
<configuration>
<allowInsecureRegistries>true</allowInsecureRegistries>
<from>
<image>openjdk:8-jdk-alpine</image>
</from>
<to>
<image>${docker.registry.url}/${docker.registry.name}/${project.artifactId}:${project.version}
</image>
<tags>
<tag>${project.version}</tag>
</tags>
<auth>
<username>${docker.registry.username}</username>
<password>${docker.registry.password}</password>
</auth>
</to>
<container>
<jvmFlags>
<jvmFlag>-Djava.security.edg=file:/dev/./urandom</jvmFlag>
</jvmFlags>
<volumes>
<volume>/tmp</volume>
<volume>/logs</volume>
</volumes>
<ports>
<port>${project.server.port}</port>
</ports>
<format>OCI</format>
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
</container>
</configuration>
<executions>
<execution>
<id>jib-maven-plugin</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行构建
然后在项目根目录执行 mvn clean compile jib:build 就可以了 我们看到已经推送成功了 harbor仓库中查看 通过域名访问harbor,查看 library 里面的镜像仓库 点进去就可以看到我们刚刚推送的镜像 以及镜像的详细信息
其他的微服务上传
微服务打包 这里我们也将其他微服务上传到仓库,步骤同上 仓库中查看镜像 在我们的仓库中查看镜像,我们看到镜像都已经上传到仓库中了
harbor 测试
删除本地镜像 可以通过 docker rmi 镜像ID 删除本地镜像
docker rm -f learn-docker-storage
docker rmi 192.168.10.30/library/learn-docker-storage:0.0.3
运行harbor 中的镜像 我们把所有微服务都上传到了仓库中,我们以一个完整的项目运行docker 运行learn-docker-storage服务 执行运行命令
docker run -d \
-v /opt/docker/logs:/logs \
--name learn-docker-storage \
--network=learn-docker-network \
itcastharbor.com/library/learn-docker-storage:1.0-SNAPSHOT
运行learn-docker-web服务 执行运行命令
docker run -d \
--name learn-docker-web \
--network=learn-docker-network \
itcastharbor.com/library/learn-docker-web:1.0-SNAPSHOT
该微服务也是内部服务不需要暴漏端口,并且没有配置日志输出,所以不挂载日志路径 运行learn-docker-gateway服务 执行运行命令
docker run -d \
-p 8888:8888 \
--name learn-docker-gateway \
--network=learn-docker-network \
itcastharbor.com/library/learn-docker-gateway:1.0-SNAPSHOT
因为网关对外需要暴漏端口,所有需要开放 8888 端口 查看nacos注册的微服务 我们发现我们的三个服务都已经注册进去了,http://192.168.10.30:8848/nacos 访问测试微服务 因为我们存储服务的 8003 端口没有暴漏出来,无法访问,我们需要通过网关进行访问
curl http://192.168.10.30:8888/employeapi/find/10001| python -m json.tool
任务编排工具
现在管理微服务比较麻烦,现在只是三个微服务,如果更多会更加麻烦,怎么办呢,下面我们就来学习下docker编排工具
什么是任务编排
编排是一个新的词汇,经过阅读才明白编排指的是容器的集群化和调度。另一类含义指的是容器管理,负责管理容器化应用和组件任务。 docker毫无疑问是一个优秀的开源工具。但是,仅靠docker引擎和容器就不能进行复杂的应用程序部署。对于部署复杂的应用程序体系结构的容器群集,必须进行适当的配置。容器化的应用程序应该能够根据应用程序资源需求进行扩展和缩小
需要考虑的因素 我们需要一个有效管理容器的良好框架。容器的生命周期很短,在进行容器编排时,要考虑的主要因素是
- 联网
- 高可用性
- 易于部署
- 良好的服务发现。
常见的任务编排工具
docker-compose docker-compose是基于docker的编排工具,使容器的操作能够批量的,可视的执行,是一个管理多个容器的工具,比如可以解决容器之间的依赖关系,当在宿主机启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容易出错,这个时候推荐使用 docker的单机编排工具 docker-compose。
KubernetesKubernetes是一个开源的,开箱即用的容器集群管理器和业务流程。它具有出色的构建 调度器 和资源管理器,用于以更有效和高度可用的方式部署容器。Kubernetes已成为许多组织事实上的容器编排工具。kubernetes项目由google与世界各地的贡献者维护。它提供了本机Docker工具不提供的许多功能。而且,使用kubernetes很容易上手。
OpenShift Openshift建立在kubernetes之上。Openshift项目由Redhat维护。它同时具有开源(openshiftorgin)和企业版(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仓库 我们刚才讲解了本地搭建Harbor仓库,地址是 https://itcastharbor.com/ 清理Docker环境 清理本地环境 因为使用任务编排,本地的服务都可以删除掉了
docker rm -f $(sudo docker ps -a -q)
docker rmi $(docker images -q)
查看本地环境 可以查看下本地的Docker环境
docker ps -a
docker images
删除网络配置 因为我们自己配置了Docker网络,我们删除掉
docker network rm learn-docker-network
初始化镜像 将服务器需要的镜像初始化
docker pull mysql:5.7.35;\
docker pull nacos/nacos-server;\
docker pull itcastharbor.com/library/learn-docker-web:1.0-SNAPSHOT;\
docker pull itcastharbor.com/library/learn-docker-gateway:1.0-SNAPSHOT;\
docker pull itcastharbor.com/library/learn-docker-storage:1.0-SNAPSHOT
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 multicontainer 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文件
sudo curl -L "https://github.com/docker/compose/releases/download/v2.0.1/docker-
compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
测试安装结果
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 之间有以下关系
基本使用
接下来我们使用 docker-compose 构建我们的微服务以及mysql,并逐步讲解其使用。 准备工作 在项目文件夹下创建 docker-compose.yml文件
[root@linux30 harbor]
[root@linux30 docker-learn]
总用量 43160
-rw-r--r--. 1 root root 187 10月 13 14:35 Dockerfile
-rw-r--r--. 1 root root 44188571 10月 13 15:45 learn-docker-storage-1.0-
SNAPSHOT.jar
[root@linux30 docker-learn]
[root@linux30 docker-learn]
总用量 43160
-rw-r--r--. 1 root root 0 10月 13 18:50 docker-compose.yml
-rw-r--r--. 1 root root 187 10月 13 14:35 Dockerfile
-rw-r--r--. 1 root root 44188571 10月 13 15:45 learn-docker-storage-1.0-
SNAPSHOT.jar
[root@linux30 docker-learn]
编写配置文件 先在 docker-compose.yml 文件里添加如下代码,构建我们的项目
version: '2'
services:
mysql:
image: mysql:5.7.35
hostname: mysql
container_name: mysql
restart: always
networks:
- learn-docker-network
volumes:
- "/opt/docker/etc/mysql:/etc/mysql/mysql.conf.d/"
- "/opt/docker/data/mysql:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: '123456'
nacos:
image: nacos/nacos-server
hostname: nacos
container_name: nacos
restart: always
ports:
- "8848:8848"
networks:
- learn-docker-network
environment:
MODE: 'standalone'
JVM_XMS: '128m'
JVM_XMX: '128m'
learn-docker-web:
image: itcastharbor.com/library/learn-docker-web:1.0-SNAPSHOT
restart: always
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
volumes:
- "/opt/docker/logs:/logs"
learn-docker-storage:
image: itcastharbor.com/library/learn-docker-storage:1.0-SNAPSHOT
restart: always
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
volumes:
- "/opt/docker/logs:/logs"
learn-docker-gateway:
image: itcastharbor.com/library/learn-docker-gateway:1.0-SNAPSHOT
restart: always
ports:
- "8888:8888"
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
volumes:
- "/opt/docker/logs:/logs"
networks:
learn-docker-network:
driver: bridge
运行测试 在项目的文件中执行 docker-compose up -d 命令就可以启动了
docker-compose up -d
微服务访问测试 通过网关地址访问测试微服务
curl http://192.168.10.30: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 服务名=节点数
docker-compose up -d --scale learn-docker-storage=2
启动后查看nacos节点信息 缩容节点 和扩容一样指定节点数量就可以的
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管理器允许您控制将服务部署到不同节点集之间的延迟。如果出现任何问题,您可以将任务回滚到服务的先前版本。
准备环境
服务器准备 我的三台测试机 服务器端口开放 在创建集群前,如果开启了防火墙,请确认三台主机的防火墙能让swarm需求的端口开放,需要打开主机之间的端口,以下端口必须可用。在某些系统上,这些端口默认为打开。
- 2377:TCP端口2377用于集群管理通信
- 7946:TCP和UDP端口7946用于节点之间的通信
- 4789:TCP和UDP端口4789用于覆盖网络流量
可以直接禁用系统防火墙来让这些端口通信不受限制,一般测试环境我们都会禁用防火墙
systemctl stop firewalld(立即生效)
systemctl disable firewalld(重启生效)
搭建Swarm集群 当首次安装并使用Docker Engine时,默认情况下swarm模式是禁用的。当启用swarm模式时,可以使用docker service 服务管理命令。 有两种方式在swarm模式下运行引擎:
- 创建一个新的集群
- 加入现有集群 在生产环境中,集群模式提供具有集群管理功能的容错平台,以保证服务的可靠运行。
下面我们就来搭建一个 swarm 集群 初始化集群
docker swarm init --advertise-addr 192.168.10.30
生成口令 生成管理节点口令
docker swarm join-token manager
生成执行节点口令
docker swarm join-token worker
其他节点加入集群 在第一个从节点执行加入 work的指令
docker swarm join --token SWMTKN-1-
1hc71tzcposay6zuefdci2xh1vqzztdjgfqkgflqraiqvy8ewk-84l9jw4woggtodf7xj9zc5l2u
192.168.10.30:2377
第二个节点执行加入work的命令
docker swarm join --token SWMTKN-1-
1hc71tzcposay6zuefdci2xh1vqzztdjgfqkgflqraiqvy8ewk-84l9jw4woggtodf7xj9zc5l2u
192.168.10.30:2377
查看swarm的节点 执行 docker node ls 查看swarm节点信息
docker node ls
AVAILABILITY状态说明
- Active 意味着调度程序可以将任务分配给节点。
- Pause 意味着调度程序不会将新任务分配给节点,但现有任务仍在运行。
- Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们。
MANAGER STATUS状态说明 显示节点是属于manager或者worker 没有值 :表示不参与集群管理的工作节点。 - Leader :意味着该节点是使集群的所有集群管理和编排决策的主要管理器节点。
- Reachable: 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用,则该节点有资格 被选为新领导者。
- Unavailable :意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用,您应该将新的管理器节点加入群集,或者将工作器节点升级为管理器。
修改主机名 默认 centos 的主机名是 localhost ,我们看上面,节点的主机名都是 localhost ,我们修改一下 查看主机名 hostnamectl status 可以查看主机名
hostnamectl status
修改主机名 修改主机名使用 hostnamectl set-hostname NAME 命令可以进行修改,我们使用 linux30,linux31…方式命名我们的节点
hostnamectl set-hostname linux30
hostnamectl status
其他节点依次操作就可以 再次查看节点 再次查看swarm节点信息
docker node ls
添加节点标签 因为我们用到了节点约束,所以启动服务之前需要添加节点标签
docker node update --label-add role=data linux30
docker node inspect linux30|grep role
管理节点
升降级节点 无论您升级或降级节点,您应该始终在集群中维护奇数个管理器节点, 升降级节点角色只能在管理节点上运行,应先升级工作节点为被选举者,再降级领导者为工作节点,然后被选举者成为领导者完成替换;
您可以将工作程序节点提升为manager角色。这在管理器节点不可用或者您希望使管理器脱机以进行维护时很有用。 类似地,您可以将管理器节点降级为worker角色。 升级节点 要升级一个节点或一组节点,请从管理器节点运行 docker node promote 节点名称
docker node promote linux31
升级节点后不会马上生效,会进入 Reachable 状态,如果leader节点关掉,当前节点会参与主节点竞争 降级节点 要降级一个节点或一组节点,请从管理器节点运行 docker node demote 节点名称
docker node demote linux30
swam将节点降级后,再次查看节点命令不生效,需要到管理节点查看 节点退出swarm集群 docker swarm leave 命令可在所有节点上运行,值得注意的是,工作节点退出swarm集群后,在管理节点上依然保存着工作节点的节点信息,状态为down,要删除节点信息,可使用docker node rm命令,当所有的节点都退出并且被删除时,在管理节点上使用docker swarm leave,然后退出整个集群; 工作节点 在工作节点执行以下命令可以退出 swarm 节点
docker swarm leave
管理节点 在管理节点查看节点信息
docker node ls
根据退出节点前后查看节点信息,可以发现退出的节点是down的状态,并没有删除节点 删除节点信息 在管理节点执行删除命令 docker node rm 节点ID
[root@linux31 ~]
管理集群服务
docker swarm init --advertise-addr 192.168.10.30
管理集群服务必须在manager角色的主机上 创建overlay网络 我们需要在多个服务器中运行Docker容器集群,需要使用overlay网络,overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密
docker network create --driver overlay learn-docker-overlay-network
创建服务 使用 docker service create 命令来创建服务 创建MySQL服务
docker service create \
-e MYSQL_ROOT_PASSWORD=123456 \
--mount
type=bind,source=/opt/docker/etc/mysql,destination=/etc/mysql/mysql.conf.d/ \
--mount type=bind,source=/opt/docker/data/mysql,destination=/var/lib/mysql \
--replicas 1 \
--constraint 'node.labels.role == data' \
--name mysql \
--network learn-docker-overlay-network \
mysql:5.7.35
–replicas 1 表示在集群中创建1个服务 node.labels.role == data 表示节点需要创建在标签是 data 的节点上
docker node update --label-add role=data linux30
可以查看swarm的进程
docker service ls
docker service ps mysql
创建nacos服务 nacos也是需要创建一个,但是节点是可以漂移的,不需要固定在某一台机器
docker service create \
-e MODE=standalone \
--replicas 1 \
--name nacos \
--network learn-docker-overlay-network \
nacos/nacos-server
可以查看swarm的进程
docker service ls
docker service ps nacos
我们发现nacos运行在了 linux31节点上 创建learn-docker-storage服务 我们创建learn-docker-storage服务,我们将该服务部署两个节点
docker service create \
--name learn-docker-storage \
--replicas 2 \
--network learn-docker-overlay-network \
itcastharbor.com/library/learn-docker-storage:1.0-SNAPSHOT
可以查看swarm的进程
docker service ls
docker service ps learn-docker-storage
我们发现我们的存储服务运行在两个节点上 创建learn-docker-web服务 我们创建learn-docker-web服务,我们将该服务同样部署两个节点
docker service create \
--name learn-docker-web \
--replicas 2 \
--network learn-docker-overlay-network \
itcastharbor.com/library/learn-docker-web:1.0-SNAPSHOT
可以查看swarm的进程
docker service ls
docker service ps learn-docker-web
创建learn-docker-gateway服务 我们创建learn-docker-gateway服务,因为是网关服务,我们只创建一个节点,因为需要对外暴漏端口,需要开放8888端口
docker service create \
-p 8888:8888 \
--name learn-docker-gateway \
--replicas 1 \
--network learn-docker-overlay-network \
itcastharbor.com/library/learn-docker-gateway:1.0-SNAPSHOT
可以查看swarm的进程
docker service ls
docker service ps learn-docker-gateway
测试访问微服务 因为在 linux32 节点上, linux32 节点IP是 192.168.10.32 我们可以请求URL访问
curl http://192.168.10.32:8888/employeapi/find/10001| python -m json.tool
查看某个服务日志 通过 docker service logs 服务名 可以看到当前服务的日志,但是这个服务有两个容器在运 行,所有能同时看到两个容器的日志
docker service logs learn-docker-storage
扩缩容服务 可以通过集群操作对集群进行扩缩容 扩容操作 我们将 learn-docker-storage 由两个容器变为三个容器
docker service scale learn-docker-storage=3
这样我们就把存储服务变成了三台服务 缩容操作 同样,使用该命令对 learn-docker-storage 进行缩容
docker service scale learn-docker-storage=2
删除服务 我们可以尝试把 learn-docker-gateway 删除掉,删除操作将会把整个服务的所有容器删除
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 集群环境下的多服务编排。
集群搭建案例 应用部署情况 创建docker-compose.yml 首先创建一个 docker-compose.yml 文件,使用 Docker Compose v3 语法 我们把我们原来单机版的 docker-compose.yml 改造一下
version: '2'
services:
mysql:
image: mysql:5.7.35
hostname: mysql
container_name: mysql
restart: always
networks:
- learn-docker-network
volumes:
- "/opt/docker/etc/mysql:/etc/mysql/mysql.conf.d/"
- "/opt/docker/data/mysql:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: '123456'
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- 'node.labels.role ==data'
restart_policy:
condition: on-failure
delay: 5s
nacos:
image: nacos/nacos-server
hostname: nacos
container_name: nacos
restart: always
ports:
- "8848:8848"
networks:
- learn-docker-network
environment:
MODE: 'standalone'
JVM_XMS: '128m'
JVM_XMX: '128m'
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
learn-docker-web:
image: itcastharbor.com/library/learn-docker-web:1.0-SNAPSHOT
restart: always
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
deploy:
mode: replicated
replicas: 2
restart_policy:
condition: on-failure
delay: 5s
learn-docker-storage:
image: itcastharbor.com/library/learn-docker-storage:1.0-SNAPSHOT
restart: always
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
deploy:
mode: replicated
replicas: 2
restart_policy:
condition: on-failure
delay: 5s
learn-docker-gateway:
image: itcastharbor.com/library/learn-docker-gateway:1.0-SNAPSHOT
restart: always
ports:
- "8888:8888"
networks:
- learn-docker-network
depends_on:
- nacos
- mysql
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
visualizer:
image: dockersamples/visualizer
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
networks:
learn-docker-network:
driver: bridge
配置介绍 Stack文件就是Docker Compose文件。唯一的要求就是version:一项需要是3.0或者更高的值。在Docker根据某个Stack文件部署应用的时候,首先会检查并创建networks:关键字对应网络。如果网络不存在,Docker会进行创建。下面我们详细看下这几个模块。
overlay网络 这里定义了1个网络,默认情况下网络都是使用overlay驱动,新建对应的覆盖类型的网络。
networks:
learn-docker-network:
driver: overlay
部署节点副本数 接下来我们进一步了解deploy关键字新增的内容
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
- replicas: 2 设置了期望服务的副本数量为2,默认为1.如果服务正在运行,需要调整副本数。可以调整stack文件中的replicas 的数值,然后重新部署stack。重新部署stack并不会影响那些没有改动的服务。
- restart_policy:定义了Swarm针对容器异常退出的重启策略。当前服务的重启策略是:如果某个副本以非0返回值退出,会立即重启当前副本。重启最多尝试3次,每次都是等待至多120s来检测是否成功。每次重启的间隔是5s。
节点约束 因为我们的数据库节点只能部署在数据节点,因为需要挂载本地的数据文件以及数据库文件,所以需要使用标签进行节点约束
mysql:
image: mysql:5.7.35
hostname: mysql
container_name: mysql
restart: always
networks:
- learn-docker-network
volumes:
- "/opt/docker/etc/mysql:/etc/mysql/mysql.conf.d/"
- "/opt/docker/data/mysql:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: '123456'
deploy:
mode: replicated
replicas: 1
placement:
constraints:
- 'node.labels.role ==data'
restart_policy:
condition: on-failure
delay: 5s
这里的 'node.labels.role == data 含义就是将当前mysql节点约束在标签名字是role,并且值是data的数据节点,更多操作请参考下文
部署服务 部署应用 使用docker stack deploy 命令部署
docker stack deploy -c docker-compose.yml learn-docker-test
这里我们指定了docker-compose文件,并把stack命名为 learn-docker-test。 查看部署情况 可以通过 docker stack ls 命令查看集群部署情况,会列出 Swarm 集群中的全部 Stack,包括每个 Stack 拥有多少服务 服务部署情况 查看nacos节点信息 访问nacos服务,发现我们的服务都已经注册 测试访问服务 访问服务接口测试
[root@linux30 docker-learn]
集群管理
更新服务 docker service upadte 可以对swarm服务进行升级 参数详解
- –force 强制更新重启服务,无论是否配置或镜像改变都更新
- –image image:tag 指定更新的镜像
- –with-registry-auth 向 Swarm 代理发送 Registry 认证详细信息,私有仓库需要携带该参数
更新镜像
docker service ls
docker service update --image itcastharbor.com/library/learn-docker-storage:1.0-
SNAPSHOT learn-docker-test_learn-docker-storage
删除应用 查看部署集群 docker stack ls 可以查看部署的服务列表 执行删除 docker stack rm stack名称 命令会删除整个stack集群,注意移除操作执行前并不会进行二次确认。
docker stack rm learn-docker-test
相关命令(手册) docker stack 常用命令 docker service 常用命令 docker node 常用命令 docker swarm 常用命令
portainer集群管理(扩展)
Portainer介绍 Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer可以轻松构建,管理和维护Docker环境。 而且完全免费,基于容器化的安装方式,方便高效部署。 Portainer 的目的是部署和使用一样简单。它由一个可以在任何 Docker 引擎上运行的单一容器组成(可以部署为Linux容器或Windows本地容器,也支持其他平台)。Portainer允许你管理所有的Docker资源(容器、镜像、卷、网络等)。它与独立的Docker引擎和Docker Swarm模式兼容。 swarm集群安装Portainer 使用swarm集群安装Portainer,用Portainer来管理swarm集群
curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-
agent-stack.yml
docker stack deploy -c portainer-agent-stack.yml portainer
注意:此方法将自动部署Portainer服务器的单个实例,并将Portainer代理作为全局服务部署到集群中的每个节点上。
portainer使用
注册用户 默认访问接口是9000端口,可以通过浏览器进行访问,首次登陆需要注册用户,给admin用户设置密码12345678 查看管理服务 点击home节点,当前这个节点就是我们的swarm集群 点进去就可以看到我们能操作的菜单了 查看swarm节点 点击swarm菜单就可以看到swarm节点了
管理微服务
服务部署情况 我们要将服务交给portainer管理 准备工作 管理节点标签 我们MySQL需要部署在数据节点,我们添加节点标签 在swarm管理节点,点击节点信息进入下面详情页面进行配置标签 添加网络信息 因为我们的节点需要一个共有的 overlay 网络,我们需要配置下,在network节点点击添加 在添加页面选择 overlay 网络类型,名字叫做 learn-docker-network 然后点击创建就可以 创建仓库配置 因为我们的微服务需要从我们自己的harbor镜像仓库拉取,需要将我们的仓库配置 在仓库节点填写我们的镜像地址就可以 https://itcastharbor.com/ 创建stack任务 在stack界面点击stack菜单进行添加stack任务 在stack管理界面将我们的 docker-compose.yml 复制进我们的stack界面;docker-learn-test 点击创建节点信息就可以,等待部署就可以 稍等下节点就部署完成了 点击进去就可以看到节点详情了
查看节点部署情况
进入swarm管理界面 点击 Go to cluster visualizer 查看服务部署情况
|