ROS 中使用 Chef 部署应用

资源编排ROS

是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。

了解更多

通过阿里云的资源编排服务,ROS,可以很方便的创建一组资源。但是创建资源只是第一步,接下来我们需要把应用部署上去,有两种方式供你使用,ROS 的 UserData 脚本或者集成配置管理工具,例如 Chef 或Puppet。本文将重点讲述ROS 集成 Chef 实现应用的部署与配置。关于使用 UserData 脚本的方式,大家可以参考《基于资源编排一键交付连接RDS的应用》。

通过 Chef,你可以自动实现在 ECS 上的部署配置应用而不用手动构建各种脚本。通过把 Chef 和 ROS 集成,这样能更方便的把生产资源和部署应用集成到一块,并且通过ROS的模板,可以实现随时随地无限次的搭建相同应用环境,很轻松的把搭建环境集成到 DevOps 中去。

本文将以部署 WordPress 为例,讲解如何通过 ROS 去构建一个高可用的 Web Server 环境,最后通过执行 Chef 的 Recipe 在高可用的 Web Server 基础设施环境中安装配置 WordPress 。通过最终的这个 ROS模板,你可以简洁快速的获取一个 WordPress 应用。当然你还可以通过 Git 或 SVN 管理这个 ROS 的模板,实现对自己 WordPress 应用环境的版本控制。

ROS 安装部署 WordPress 架构概览

此模板讲创建一个高可用的带有负载均衡能力的 WordPress 环境,并通过阿里云的 RDS 提供后端的数据存储。基本的架构如下图所示:

在上面的架构图里面,通过 ROS 的 ALIYUN::ECS::InstanceGroup 创建多个 ECS 节点,这样就可以保证 WordPress 有多个实例,提高 WordPress 的高可用性。在 ECS 的前面部署了一个 SLB, 来保证均衡后端 ECS 的负载,给用户暴露唯一的 WordPress 访问地址,同时能够在添加或减少后端 ECS 服务器的时候,用户无感知。SLB 通过 ALIYUN::SLB::LoadBalancer 创建。通过 ALIYUN::SLB::Listener 配置SLB监听那些端口, ALIYUN::SLB::BackendServerAttachment 把后端服务器 ECS 加入到SLB监听列表中。通过使用 RDS 提供 WordPress 的后端数据存储能力。ROS 通过 ALIYUN::RDS::DBInstance 创建 RDS 实例配置数据库。以上所有的资源都部署在一个安全组里面,通过安全组控制数据出入规则,提高安全性。

最终,当 ECS 实例启动的时候,ROS 通过利用 Chef 的本地模式安装和配置 WordPress。 Chef 的本地模式是使用本地的 Chef 仓库来管理 cookbook 而不用通过 Chef Server。

WordPress 一键部署

一键部署>>>

点击一键部署后,默认会在华北2 region 部署 WordPress。 如果你需要调整 region,请点击页面右下角的【上一步】,然后重新选择 region,接着点击【下一步】,你只需要填入如下图中必填的信息或者根据你的需求调整信息后,点击【创建】按钮就可以部署一套 WordPress 高可用环境。

模板详解

创建 VPC 网络

在本例中,所有资源的都处于VPC网络下,保证网络的隔离性和安全性。为了保证 ECS 能够访问外网,获取到 Chef 的安装包,下载到 WordPress 的 cookbook,我们配置了 VPC 的 SNAT 网关。请参考《新玩法,ROS帮你一键搭建NatGateway让VPC与Internet的互访》,了解如何详细的配置你的 VPC 网络。

   "SNatEntry": {
      "Type": "ALIYUN::ECS::SNatEntry",
      "DependsOn": "WPLoadBalancer",
      "Properties": {
        "SNatIp": {
          "Fn::Select": [
            "0",
            {
              "Fn::GetAtt": [
                "NatGateway",
                "BandwidthPackageIps"
              ]
            }
          ]
        },
        "SourceVSwitchId": {
          "Fn::GetAtt": [
            "VSwitch",
            "VSwitchId"
          ]
        },
        "SNatTableId": {
          "Fn::GetAtt": [
            "NatGateway",
            "SNatTableId"
          ]
        }
      }
    },
   "NatGateway": {
      "Type": "ALIYUN::ECS::NatGateway",
      "Properties": {
        "Spec": "Small",
        "NatGatewayName": "NatGateway",
        "BandwidthPackage": [
          {
            "IpCount": 1,
            "Bandwidth": 5
          }
        ],
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "VpcId": {
          "Fn::GetAtt": [
            "Vpc",
            "VpcId"
          ]
        }
      }
    },
    "Vpc": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "CidrBlock": "192.168.0.0/16"
      }
    },
   "VSwitch": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "CidrBlock": "192.168.33.0/24",
        "ZoneId": {
          "Fn::Select": [
            "0",
            {
              "Fn::GetAZs": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "VpcId": {
          "Fn::GetAtt": [
            "Vpc",
            "VpcId"
          ]
        }
      }
    }

创建安全组

在本例中,所有的ECS都加入到一个默认安全组。同时,给安全组资源配置允许外部用户可通过80和22端口访问 WordPress 部署环境。

  "DefaultSecurityGroup": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "Description": "DDC default security group",
        "SecurityGroupIngress": [
          {
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp",
            "NicType": "intranet",
            "PortRange": "22/22"
          },
          {
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp",
            "NicType": "intranet",
            "PortRange": "443/443"
          },
          {
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp",
            "NicType": "intranet",
            "PortRange": "80/80"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "all",
            "DestCidrIp": "0.0.0.0/0",
            "NicType": "intranet",
            "PortRange": "-1/-1",
            "Priority": 1
          }
        ],
        "VpcId": {
          "Ref": "Vpc"
        }
      }
   }

创建 ECS 实例

本例中,创建了两种 ECS 实例,一种是用 ALIYUN::ECS::InstanceGroup 创建用来部署 WordPress 的 ECS实例,这个资源可以通过 MaxAmount 来指定一次创建多少台 ECS 实例。一个是用 ALIYUN::ECS::Instance 创建一台运维使用的跳板机。跳板机也部署在相同的 VPC 网络中,但是给跳板机分配了公网 IP。


"WPEcsInstance": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "DependsOn": "SNatEntry",
      "Properties": {
        "IoOptimized": {
          "Ref": "WPEcsIoOptimized"
        },
        "ImageId": {
          "Ref": "WPEcsImageId"
        },
        "SecurityGroupId": {
          "Fn::GetAtt": [
            "DefaultSecurityGroup",
            "SecurityGroupId"
          ]
        },
        "Password": {
          "Ref": "WPEcsInstancePassword"
        },
        "MinAmount": {
          "Ref": "WPEcsMaxAmount"
        },
        "AllocatePublicIP": "false",
        "SystemDiskCategory": {
          "Ref": "WPEcsSystemDiskCategory"
        },
        "UserData": {
          "Fn::Replace": [
            {
              "ros-notify": {
                "Fn::GetAtt": [
                  "WPEcsConditionHandle",
                  "CurlCli"
                ]
              }
            },
            {
              "Fn::Join": [
                "",
                [
                  "#!/bin/sh\n",
                  "apt-get update\n",
                  "apt-get install -y rails\n",
                  "apt-get install -y unzip\n",
                  "\n",
                  "wget -P /tmp http://ros-om-dependence.oss-cn-shanghai.aliyuncs.com/chef-ubuntu-64/chef_12.18.31-1_amd64.deb\n",
                  "dpkg -i /tmp/chef_12.18.31-1_amd64.deb\n",
                  "wget -P /tmp http://ros-om-dependence.oss-cn-shanghai.aliyuncs.com/chef-ubuntu-64/chefdk_1.2.22-1_amd64.deb\n",
                  "dpkg -i /tmp/chefdk_1.2.22-1_amd64.deb\n",
                  "\n",
                  "mkdir -p /var/chef/chef-repo/.chef\n",
                  "# chef local repo setting\n",
                  "# wget -P /tmp http://github.com/opscode/chef-repo/tarball/master/chef-boneyard-chef-repo-605eeda.tar.gz\n",
                  "wget -P /tmp http://ros-om-dependence.oss-cn-shanghai.aliyuncs.com/chef-ubuntu-64/chef-boneyard-chef-repo-605eeda.tar.gz\n",
                  "tar -xzf /tmp/chef-boneyard-chef-repo-605eeda.tar.gz -C /var/chef/chef-repo\n",
                  "cp -rf /var/chef/chef-repo/chef-boneyard-chef-repo-605eeda/* /var/chef/chef-repo\n",
                  "rm -rf /var/chef/chef-repo/chef-boneyard-chef-repo-605eeda\n",
                  "echo install chef > /tmp/log\n",
                  "# set default knife.rb\n",
                  "echo \"cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\" > /var/chef/chef-repo/.chef/knife.rb\n",
                  "echo \"node_path [ '/var/chef/chef-repo/nodes' ]\" >> /var/chef/chef-repo/.chef/knife.rb\n",
                  "\n",
                  "# set default client.rb\n",
                  "echo \"cookbook_path [ '/var/chef/chef-repo/cookbooks' ]\" > /var/chef/chef-repo/.chef/client.rb\n",
                  "echo \"node_path [ '/var/chef/chef-repo/nodes' ]\" >> /var/chef/chef-repo/.chef/client.rb\n",
                  "\n",
                  "# set init chef conf\n",
                  "orig_home=$HOME\n",
                  "export HOME='/var/chef'\n",
                  "\n",
                  "# create node list\n",
                  "cd /var/chef/chef-repo\n",
                  "chef-client -z -c /var/chef/chef-repo/.chef/client.rb\n",
                  "echo config chef repo >> /tmp/log\n",
                  "\n",
                  "\n",
                  "# download wordpress cookbook\n",
                  "wget -P /tmp http://ros-om-dependence.oss-cn-shanghai.aliyuncs.com/chef-ubuntu-64/wordpress.tar.gz\n",
                  "tar -xzf /tmp/wordpress.tar.gz -C /var/chef/chef-repo/cookbooks\n",
                  "\n",
                  "# set default knife.rb\n",
                  "echo \"cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\" > /var/chef/chef-repo/.chef/knife.rb\n",
                  "echo \"node_path [ '/var/chef/chef-repo/nodes' ]\" >> /var/chef/chef-repo/.chef/knife.rb\n",
                  "\n",
                  "# set default client.rb\n",
                  "echo \"cookbook_path [ '/var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks' ]\" > /var/chef/chef-repo/.chef/client.rb\n",
                  "echo \"node_path [ '/var/chef/chef-repo/nodes' ]\" >> /var/chef/chef-repo/.chef/client.rb\n",
                  "echo config wordpress cookbook >> /tmp/log\n",
                  "\n",
                  "\n",
                  "# set wordpress datebase conf\n",
                  "echo \"normal['wordpress']['db']['pass'] = '",
                  {
                    "Ref": "WPDBPassword"
                  },
                  "'\" > /var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks/wordpress/attributes/aliyun_rds_config.rb\n",
                  "echo \"normal['wordpress']['db']['user'] = '",
                  {
                    "Ref": "WPDBUser"
                  },
                  "'\" >> /var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks/wordpress/attributes/aliyun_rds_config.rb\n",
                  "echo \"normal['wordpress']['db']['host'] = '",
                  {
                    "Fn::GetAtt": [
                      "WPDBDatabase",
                      "InnerConnectionString"
                    ]
                  },
                  "'\" >> /var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks/wordpress/attributes/aliyun_rds_config.rb\n",
                  "echo \"normal['wordpress']['db']['name'] = '",
                  {
                    "Ref": "WPDBName"
                  },
                  "'\" >> /var/chef/chef-repo/cookbooks/wordpress/berks-cookbooks/wordpress/attributes/aliyun_rds_config.rb\n",
                  "\n",
                  "\n",
                  "echo run install wordpress cookbook >> /tmp/log\n",
                  "knife node run_list add -z `knife node list -z` recipe[wordpress]\n",
                  "\n",
                  "chef-client -z -c /var/chef/chef-repo/.chef/client.rb | tee -a /tmp/chef_runing_log\n",
                  "ros-notify\n"
                ]
              ]
            }
          ]
        },
        "MaxAmount": {
          "Ref": "WPEcsMaxAmount"
        },
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "VpcId": {
          "Ref": "Vpc"
        },
        "InstanceType": {
          "Ref": "WPEcsInstanceType"
        }
      }
    },
 "JumpHost": {
      "Type": "ALIYUN::ECS::Instance",
      "Properties": {
        "IoOptimized": "optimized",
        "ImageId": {
          "Ref": "WPEcsImageId"
        },
        "SecurityGroupId": {
          "Fn::GetAtt": [
            "DefaultSecurityGroup",
            "SecurityGroupId"
          ]
        },
        "Password": {
          "Ref": "WPEcsInstancePassword"
        },
        "AllocatePublicIP": "true",
        "SystemDiskCategory": "cloud_efficiency",
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "VpcId": {
          "Ref": "Vpc"
        },
        "InstanceType": {
          "Ref": "WPEcsInstanceType"
        }
      }
    },

ROS 通过 UserData 集成了 Chef, 首先安装 Chef 所依赖的 ruby 环境。由于网络原因,我们把 Chef 的安装包,本地仓库和相应的 cookbook 都做了镜像,方便大家在国内访问。然后配置 Chef 的 knife.rb 和 client.rb 文件指向本地仓库中的 cookbook。调用 chef-client -z 指定本地模式生成 node list。然后添加RDS实例中的数据库名称,用户名,密码和机器名称到 WordPress cookbook 的 attributes 中,保证 Chef 能正确配置 WordPress 数据库属性。最后调用下面的 Chef 命令,在本机上安装配置 WordPress 实例。

knife node run_list add -z `knife node list -z` recipe[wordpress]
chef-client -z -c /var/chef/chef-repo/.chef/client.rb

SLB

要高可用的环境,SLB 是必不可少的一个资源。通过 SLB 即可均衡分配请求到后端服务,更可以做用户无感知地增加,减少或者替换有问题的后端 ECS 实例。同时,通过 SLB 可以给用户提供一个唯一的WordPress 访问地址。本例中,创建 SLB 后,配置了 SLB 监听后端的 ECS 的80端口。

  "WPLoadBalancerListener80": {
      "Type": "ALIYUN::SLB::Listener",
      "DependsOn": "WPLoadBalancer",
      "Properties": {
        "Persistence": {
          "StickySession": "on",
          "PersistenceTimeout": 600
        },
        "HealthCheck": {
          "Timeout": "2",
          "Port": "80",
          "Interval": "5",
          "HealthyThreshold": "2",
          "UnhealthyThreshold": "4"
        },
        "LoadBalancerId": {
          "Ref": "WPLoadBalancer"
        },
        "BackendServerPort": "80",
        "Protocol": "tcp",
        "Bandwidth": -1,
        "ListenerPort": "80"
      }
    },
   "WPSLBAttachment": {
      "Type": "ALIYUN::SLB::BackendServerAttachment",
      "Properties": {
        "BackendServerList": {
          "Fn::GetAtt": [
            "WPEcsInstance",
            "InstanceIds"
          ]
        },
        "LoadBalancerId": {
          "Ref": "WPLoadBalancer"
        }
      }
    },
   "WPLoadBalancer": {
      "Type": "ALIYUN::SLB::LoadBalancer",
      "Properties": {
        "LoadBalancerName": "WordPressLoadBalancer",
        "AddressType": "internet"
      }
    },

RDS

WordPress 需要存储用户的博文和评论,后端数据库是必不可少的一个组件。阿里云 RDS 资源是一个很好的选择。通过 ROS 可以简便的把创建 RDS 实例和配置数据库一步搞定。

   "WPDBDatabase": {
      "Type": "ALIYUN::RDS::DBInstance",
      "DependsOn": "SNatEntry",
      "Properties": {
        "DBInstanceClass": {
          "Ref": "WPDBInstanceClass"
        },
        "DBMappings": [
          {
            "DBName": {
              "Ref": "WPDBName"
            },
            "CharacterSetName": "utf8"
          }
        ],
        "ZoneId": {
          "Fn::Select": [
            "0",
            {
              "Fn::GetAZs": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "DBInstanceStorage": {
          "Ref": "WPDBInstanceStorage"
        },
        "VSwitchId": {
          "Ref": "VSwitch"
        },
        "Engine": {
          "Ref": "WPDBEngine"
        },
        "MasterUserPassword": {
          "Ref": "WPDBPassword"
        },
        "MasterUsername": {
          "Ref": "WPDBUser"
        },
        "PreferredBackupPeriod": [
          "Monday",
          "Wednesday"
        ],
        "VPCId": {
          "Ref": "Vpc"
        },
        "EngineVersion": {
          "Ref": "WPDBEngineVersion"
        },
        "PreferredBackupTime": "23:00Z-24:00Z",
        "SecurityIPList": "0.0.0.0/0"
      }
    },

总结

从本例来看,不仅通过 ROS 能安装配置应用,也可以通过集成第三方的官配工具实现相同的目的。本例以Chef 为例相大家展示了 ROS 如何通过集成 第三方配管工具。希望通过这个例子,大家通过 Chef 不光能部署 WordPress ,更能部署自己的应用。关于 ROS 的详细指导请参考这里。

资源编排ROS

是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。

了解更多

时间: 2024-07-28 16:25:48

ROS 中使用 Chef 部署应用的相关文章

MyCollege.Net中数据库服务器安装部署

服务器|数据|数据库 MyCollege.Net中数据库服务器安装部署 目录 一. 前言----------------------------1 二. 应用意义--------------------------1 三. 相关技术--------------------------2 四. 系统配置--------------------------6 五. 系统特点--------------------------8 六. 小结----------------------------9 摘

拓扑中负载均衡部署在冗余网络结构下,服务器双网卡的切换问题

今天讨论拓扑中负载均衡部署在冗余网络结构下,服务器双网卡的切换问题. 图一 图一拓扑中四台服务器与负载均衡直接相连,每台服务器双网卡各连接一台负载均衡,负载均衡热备模式部署,服务器双网卡也绑定为主备模式.当负载均衡发生主备切换时,服务器的主备网卡也跟随切换.其实这样的应用需求非常的普遍,但实际网络拓扑更常见是的如图二所示结构.服务器不直接与负载均衡连接,服务器数量也不必受到负载均衡物理接口数量的限制,这样的网络架构,一对负载均衡设备可以为几百台服务器提供应用交付. 图二

图片-求教大神在myeclipse中java项目部署不到tomcat是什么原因

问题描述 求教大神在myeclipse中java项目部署不到tomcat是什么原因 解决方案 MyEclipse中的java项目,部署到tomcat失败MyEclipse中无法部署tomcat的原因MyEclipse中无法部署tomcat的原因 解决方案二: 你这个tomcat安装配置的有问题啊, 在本地先单独起一下服务器看行不 之后如果行,就是myeclipse里的配置问题 如果不行,你就重装吧 解决方案三: 你建的项目是web项目吗 解决方案四: 不是我建的是java项目,web项目是可以部

web项目在eclipse中运行正常 部署到tomcat中运行报spring context错误

问题描述 web项目在eclipse中运行正常 部署到tomcat中运行报spring context错误 20C 解决方案 quatrz配置有问题参考:http://blog.csdn.net/kingzuo/article/details/12572881http://www.cnblogs.com/kay/archive/2007/11/02/947372.html

apache-tomcat在myeclipse中一直是部署不起来,报错信息如下

问题描述 tomcat在myeclipse中一直是部署不起来,报错信息如下 Dec 19, 2015 7:45:47 PM org.apache.coyote.AbstractProtocol init SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-bio-8080"] java.net.BindException: Address already in use :8080 a

在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序

原文 在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序 在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序 Jim Nakashima.Hani Atassi 和 Danny Thorpe 将应用程序或服务部署到 Microsoft 云服务平台 Windows Azure 的原因有很多.例如,只为使用的内容付费从而可降低操作和硬件成本.构建几乎能无限缩放的应用程序.巨大的存储容量.地理位置等等,不胜枚举. 只有

J2EE1.4中的Servlet部署

j2ee|servlet 第一步:我们要编写一个Servlet的代码,我编写一个记录访问网站次数的Servlet,代码如下: import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import java.util.*;public class hitcountServlet extends HttpServlet{public void init(ServletConfig config)throws Servle

DNS全局查询阻止列表对TMG中的WPAD部署的影响

Windows Server 2008 中的 DNS 服务器角色引入了一个全局查询阻止列表,可减少与 DNS 动态更新协议相关的漏洞.这可能会影响 WPAD 部署? 之前在测试TMG单网卡模式下,使用自动检测功能时发现无法ping通wpad.testdomain.com,且客户端自动检测无法查询到此别名记录,但是实际上该配置已经生效,想了好久没有找到问题的原因,后来经查询原因为DNS全局查询阻止列表搞的鬼, 如何取消DNS全局查询阻止列表呢?其实也不是太难,只要在DNS服务器上运行 dnscmd

Windows Azure-在Visual Studio 2010中开发和部署云应用程序

将应用程序或服务部署到 Microsoft 云服务平台 Windows Azure 的原因有很多.例如,只为使用的内容付费从而可降低操作和硬件成本.构建几乎能无限缩放的应用程序.巨大的存储容量.地理位置等等,不胜枚举. 只有当开发人员实际使用平台时,平台才会引起业界的广泛关注.开发人员是任何平台版本的核心和灵魂 – 一版平台真正的成功就是有大量开发人员在该平台上部署应用程序和服务.Microsoft 始终致力于通过 Visual Studio 为各种各样的平台(无论是旧有的还是新兴的)提供最佳的