如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(四)

在这篇文章中,我们将讨论如何用Rancher实现consul的服务发现。

如果你还没有准备好,推荐你阅读本系列中先前的文章:

第一篇:CI /CD和Docker入门

第二篇:使部署逻辑向使用Docker Compose更进一步

第三篇:借力Rancher完成容器编排

在这构建部署流水线系列的最后一篇文章中,我们将探讨在转换到Rancher进行集群调度时面临的一些挑战。在之前的文章中,我们通过使用Rancher执行调度,让运维人员无须再负责选择每一次容器运行的位置。要使用这个新方案,我们必须让环境的其他部分知道调度程序放置这些服务的位置,以及如何访问它们。我们还将讨论如何使用标签来操作调度程序,以调整容器放置位置,并避免端口绑定冲突。最后,我们将通过利用Rancher的回滚功能优化我们的升级过程。

在引入Rancher之前,我们的环境是一个相当静态的环境。我们总是将容器部署到相同的主机上,而部署到不同的主机则意味着我们需要更新一些配置文件以反映新位置。例如,如果我们要添加‘java-service-1‘应用程序的一个附加实例,我们还需要更新load balancer以指向附加实例的IP。使用调度器让我们无法预测容器部署的位置,并且我们需要动态配置环境,使其能自动适应变化。为此,我们需要使用服务注册和服务发现。

服务注册表为我们提供了应用程序在环境中的位置的单一来源。和硬编码服务位置不同,我们的应用程序可以通过API查询服务注册表,并在我们的环境发生变化时自动重新配置。Rancher使用Rancher的DNS和元数据服务提供了开箱即用的服务发现。然而,混合使用Docker和非Docker应用程序时,我们不能完全依赖Rancher来处理服务发现。我们需要一个独立的工具来跟踪我们所有服务的位置,consul就符合这个要求。

我们不会详细说明如何在您的环境中设置Consul,但是,我们将简要描述我们在ABC公司使用Consul的方式。在每个环境中,我们都有一个部署为容器的Consul集群。我们在环境中的每个主机上都部署一个Consul代理,如果主机正在运行Docker,我们还会部署一个注册器容器。注册器监视每个守护进程的Docker事件API,并在生命周期事件期间自动更新Consul。例如,在新容器被部署后,注册器会自动在Consul中注册该服务。当容器被删除时,注册器撤销它的注册。

Consul服务列表

在Consul中注册所有服务后,我们可以在负载均衡器中运行consul-template,根据Consul中存储的服务数据动态填充上游列表。对于我们的NGINX负载均衡器,我们可以创建一个模板来填充’java-service-1’应用程序的后端:

# upstreams.conf
upstream java-service-1 { 
{{range _, $element := service "java-service-1"}}    
       server {{.Address}}:{{.Port}}; 
{{else}}     
       server 127.0.0.1:65535; # force a 502{{end}} }

此模板在Consul中查找注册为“java-service-1”的服务的列表。然后它将循环该列表,添加具有该特定应用程序实例的IP地址和端口的服务线。如果在Consul中没有注册任何“java-service-1”应用程序,我们默认抛出502以避免NGINX中的错误。

我们可以在守护进程模式下运行consul-template,使其监控Consul的更改,在发生更改时重新渲染模板,然后重新加载NGINX以应用新配置。

TEMPLATE_FILE=/etc/nginx/upstreams.conf.tmpl
RELOAD_CMD=/usr/sbin/nginx -s reload 
consul-template -consul consul.stage.abc.net:8500 \     
       -template "${TEMPLATE_FILE}:${TEMPLATE_FILE//.tmpl/}:${RELOAD_CMD}"

通过使用我们的负载均衡器设置来动态地改变其余的环境变化,我们可以完全依赖Rancher调度器来做出我们的服务应该在哪里运行的复杂的决定。但是,我们的“java-service-1”应用程序在Docker主机上绑定TCP端口8080,如果在同一主机上调度了多个应用程序容器,则会导致端口绑定冲突并最终失败。为了避免这种情况,我们可以通过调度规则来操作调度器。

通过在docker-compose.yml文件中使用容器标签来提出条件,是Rancher给我们的一种操作调度器的方法。条件可以包括亲和规则、否定、至“软”强制(意味着尽可能地避免)。在我们使用‘java-service-1‘应用程序的情况下,我们知道在给定时间只有一个容器可以在主机上运行,因此我们可以基于容器名称设置反关联性规则。这将使调度程序查找一个未运行名称为“java-service-1”的容器的Docker主机。我们的docker-compose.yml文件看起来像下面这样:

java-service-1:   
   image: registry.abc.net/java-service-1:${VERSION}   
   container_name: java-service-1   
   ports:    
         - 8080:8080   
    labels:     
         io.rancher.scheduler.affinity:container_label_ne: io.rancher.stack_service.name=java-service-1

注意“标签”键的引入。所有调度规则都作为标签被添加。标签可以被添加到Docker主机和容器。当我们在Rancher注册我们的主机时,我们可以将它们与标签关联,以后就可以切断调度部署。例如,如果我们有一组使用SSD驱动器进行存储优化的Docker主机,我们可以添加主机标签storage=ssd。

Rancher主机标签

需要利用优化存储主机的容器可以添加标签来强制调度程序仅在匹配的主机上部署它们。我们将更新我们的“java-service-1”应用程序,以便只部署在存储优化的主机上:

java-service-1:   
    image: registry.abc.net/java-service-1:${VERSION}   
    container_name: java-service-1   
    ports:    
         - 8080:8080   
    labels:     
         io.rancher.scheduler.affinity:container_label_ne: io.rancher.stack_service.name=java-service-1     
         io.rancher.scheduler.affinity:host_label: storage=ssd

通过使用标签,我们可以根据所需的容量,而不是个别主机运行特定的容器集,来精细地调整我们的应用程序部署。切换到Rancher进行集群调度,即使您仍然有必须在特定主机上运行的应用程序。

最后,我们可以利用Rancher的回滚功能优化我们的服务升级。在我们的部署工作流中,通过调用rancher-compose来指示Rancher在该服务堆栈上执行升级以部署服务。升级过程大致如下:

  1. 通过拉取一个新的镜像来启动升级
  2. 逐一地,现有容器被停止并且新容器被启动
  3. 部署程序登录到UI并选择“完成升级”时,升级完成,
  4. 已停止的旧服务容器被删除

Rancher升级

当给定服务的部署非常少时,此工作流就好了。但是,当某个服务处于“升级”状态(在部署者选择“完成升级”之前)时,在执行“完成升级”或是“回滚”操作之前,你都不能对它进行任何新的升级”。rancher-compose实用程序让我们可以选择以编程方式选择要执行的操作,以部署程序者的身份执行操作。例如,如果您对服务进行自动测试,则可以在rancher-compose升级返回后调用此类测试。根据这些测试的状态,rancher-compose可以被再次调用,这次我们告诉堆栈“完成升级”或“回滚”。我们部署Jenkins作业的一个原始示例可能如下:

# for the full job, see part 3 of this series
/usr/local/bin/rancher-compose --verbose \   
    -f ${docker_dir}/docker-compose.yml \   
    -r ${docker_dir}/rancher-compose.yml \   
    up -d --upgrade 
JAVA_SERVICE_1_URL=http://java-service-1.stage.abc.net:8080/api/v1/status 
if curl -s ${JAVA_SERVICE_1_URL} | grep -q "OK"; then   
   
# looks good, confirm or "finish" the upgrade   
    /usr/local/bin/rancher-compose --verbose \    
         -f ${docker_dir}/docker-compose.yml \     
         -r ${docker_dir}/rancher-compose.yml \     
         up --confirm-upgrade 
else   
     # looks like there‘s an error, rollback the containers   
     # to the previously deployed version   
     /usr/local/bin/rancher-compose --verbose \     
        -f ${docker_dir}/docker-compose.yml \     
        -r ${docker_dir}/rancher-compose.yml \     
        up --rollback 
fi

这个逻辑将调用我们的应用程序端点来执行简单的状态检查。如果输出显示的是‘OK’,那么我们完成升级,否则我们需要回滚到以前部署的版本。如果您没有自动测试,另一个选择是简单地总是完成或“确认”升级。

# for the full job, see part 3 of this series
/usr/local/bin/rancher-compose --verbose \   
    -f ${docker_dir}/docker-compose.yml \   
    -r ${docker_dir}/rancher-compose.yml \   
    up -d --upgrade --confirm-upgrade

如果不久以后,您确定需要回滚,就使用相同的部署作业简单地重新部署以前的版本。这确实不像Rancher的升级和回滚功能那么友好,但它通过使堆栈不处于“升级”的状态来解锁将来的升级。

当服务在Rancher中回滚时,容器将被重新部署到以前的版本。当使用通用标记如“latest”或“master”部署服务时,可能会出现意外的后果。例如,让我们假设‘java-service-1‘应用程序以前被部署了标签‘latest‘。对图像进行更改,推送到注册表,Docker标签“latest”被更新为指向此新映像我们使用标签“latest”继续升级,在测试后决定应用程序需要回滚。使用Rancher滚动堆栈仍然会重新部署最新的映像,因为标签“latest”尚未被更新为指向上一个映像。回滚可以在纯技术术语中实现,但是部署最近的工作副本的预期效果完全无法实现。在ABC公司,我们通过始终使用与应用程序版本相关的特定标记来避免这种情况。因此,不要使用标记latest”部署我们的“java-service-1”应用程序,我们可以使用版本标签“1.0.1-22-7e56158”。这保证回滚将始终指向我们的应用程序在环境中的最新工作部署。

我们希望我们分享的经验对你们有所帮助。这有助于我们有条不紊地采用Docker,稳步改进我们的流程,并让我们的团队能熟悉这些概念。对更自动化的部署工作流进行增量更改,使组织能够更快地实现自动化的优势,部署团队可以更加务实地决定他们在流水线中需要什么。我们的经历证明Rancher在可行性、自动化、甚至团队协作方面都是成功的。我们希望分享这些我们在Docker应用过程中获得的经验教训将有助于您自己的应用过程。

欢迎关注Rancher官方微信公众号(RancherLabs),获取第一手技术干货推送;欢迎添加客服微信(RancherLabsChina)为好友,加入Rancher官方技术交流群,获取免费技术支持,与数千Docker/Rancher使用者互动。

原文来源:Rancher Labs

时间: 2024-10-06 07:08:01

如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(四)的相关文章

学习使用Docker、Docker-Compose和Rancher搭建部署Pipeline(一)

这篇文章是一系列文章的第一篇,在这一系列文章中,我们想要分享我们如何使用Docker.Docker-Compose和Rancher完成容器部署工作流的故事.我们想带你从头开始走过pipeline的革命历程,重点指出我们这一路上遇到的痛点和做出的决定,而不只是单纯的回顾.幸好有很多优秀的资源可以帮助你使用Docker设置持续集成和部署工作流.这篇文章并不属于这些资源之一.一个简单的部署工作流相对比较容易设置.但是我们的经验表明,构建一个部署系统的复杂性主要在于原本容易的部分需要在拥有很多依赖的遗留

如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(二)

在这一系列文章的第一篇中,我们分享了只用Docker时我们开发的初步的工作流,如何创建一个基础的构建和部署流水线.容器的部署方式不再是在登陆server的时候从内存中输入Docker命令.我们已经通过Jenkins server实现了镜像的自动化构建.我们使用脚本将Docker命令进行封装,将其存储到GitHub中并且设置版本.目前我们正采取措施,通过逐步改善现有过程来实现持续部署.然而,仍有一些痛点需要我们去解决.在这篇文章中,我们将看看如何使用Docker Compose 和 Ansible

docker swarm集群及其UI部署

一.规划 ①swarm01作为manager节点,swarm02和swarm03作为worker节点. # cat /etc/hosts 127.0.0.1   localhost 192.168.139.175  swarm01  192.168.139.176  swarm02  192.168.139.177  swarm03 ②配置SSH免密登陆 # ssh-keygen -t rsa -P '' # ssh-copy-id -i .ssh/id_rsa.pub [email prote

K8S主机安装docker环境和rancher搭建

实验环境: 利用rancher搭建kubernetes集群,及搭建和关联harbor私有镜像库. rancher:http://10.10.10.10:8888 kubernetes:10.10.10.10 harbor:10.10.10.100 images:10.10.10.100/test_nginx:latest app:nginx 实验目的: 一.实践docker:search pull.run.tag.build.push功能.了解参数含义 #docker search *image

docker微服务部署之:六、Rancher管理部署微服务

docker微服务部署之:五.利用DockerMaven插件自动构建镜像 一. 什么是Rancher Rancher是一个开源的企业级容器管理平台.通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台.Rancher提供了生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台. Rancher官网:https://rancher.com 二.Docker中下载Rancher镜像并运行 #Rancher镜像下载 $ sudo docker pul

[转]Docker学习笔记之一,搭建一个JAVA Tomcat运行环境

本文转自:http://www.blogjava.net/yongboy/archive/2013/12/12/407498.html 前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续

基于Docker的TensorFlow机器学习框架搭建和实例源码解读

概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的机器学习开发环境,探索人工智能的奥秘,容器随开随用方便快捷.源码解析TensorFlow容器创建和示例程序运行,为热爱机器学者降低学习难度. 默认机器已经装好了Docker(Docker安装和使用可以看我另一篇博文:Ubuntu16.04安装Docker1.12+开发实例+hello world+w

Docker学习笔记之一,搭建一个JAVA Tomcat运行环境

前言 Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过配置文件可以轻松实现应用程序的自动化安装.部署和升级,非常方便.因为使用了容器,所以可以很方便的把生产环境和开发环境分开,互不影响,这是 docker 最普遍的一个玩法.更多的玩法还有大规模 web 应用.数据库部署.持续部署.集群.测试环境.面向服务的云计算.虚拟桌面 VDI 等等. 主观的印象:Docker 使用 Go 语言编写,用 cgroup 实现

Docker之Compose服务编排

Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Compose是Fig的升级版,Fig已经不再维护.Compose向下兼容Fig,所有fig.yml只需要更名为docker-compose.yml即可被Compose使用. 服务编排工具使得Docker应用管理更为方便快捷. Compose网站:https://docs.docker.com/compos