Back

Chef自动化EC2部署

使用Chef和AWS实现个人服务器的弹性部署

这篇博客主要是记录一下我在ec2上实现Serverless-Chef的过程,供以后做参考 基本的框架是使用Chef进行各种软件的安装与配置 由于是使用Chef,所以准备过程都会比较繁琐,利用Serverless-chef的方法肯定是没有用Ansible来的直接,不过我对Chef是更熟悉一些 这篇文章用的是codecommit而不是其它git remote,主要是想要用私人的git repo,同时让ec2可以直接clone到repo,而不用把密钥放到ec2中

General Goal

启动任意一个EC2 instance时,它能自动联系Route53拿到我自己的域名服务,并且配置所有我想要的服务

Objectives

  1. Serverless-Chef的实现
  2. Caddy对Route53域名的交互

Serverless-Chef

Serverless-Chef 本身不是个现成的软件,而是一个概念。Chef本身是需要一个Host Server来实现其功能的,Host Server的作用是提供Chef-client运行时所需要的安装信息以及数据。不过只提供数据的话,抛开Host Server也可以进行。

基础架构

AWS Codecommit: 储存Cookbook AWS EC2: 启动时用user-data clone下来cookbook,并且自动安装chef-client,剩下的交给chef

“就这么简单?” “就这么简单!"

工作流程

我的Mac: 对Cookbook进行编辑,使用“berks vendor”创建本地cookbooks依赖,然后push到Codecommit EC2: 从Codecommit中clone下来,并且将berks vendor

实现

架构简单,不代表实现起来简单

I. 正确配置Codecommit

  1. 在AWS IAM中创建一个新的user,并且给予相应的权限,我为了图省事,直接用了管理员账户
  2. 在管理员账户下添加ssh key
  3. 在本地电脑的ssh config中设置(最后两行没有在CodeCommit官方文档中说明,至于为什么写,参考这个回答):
#~/.ssh/config
Host git-codecommit.*.amazonaws.com
   User <Your Key ID>
   IdentityFile <path_to_your_key_file>
   PubkeyAcceptedAlgorithms +ssh-rsa
   HostkeyAlgorithms +ssh-rsa 
  1. git remote add … (在本地git repo中添加CodeCommit为remote,由于Chef的Cookbook自身就是repo,所以不需要init的过程) 至此,Codecommit设置完毕

II. 配置ec2能够连接CodeCommit

  1. 首先在AWS IAM下创建一个role,供ec2使用(记得在创建ec2的时候把role给ec2实例)
  2. ssh到ec2中,设置git所需的credential
git config --global credential.helper "!aws codecommit credential-helper $@"
git config --global credential.UseHttpPath true

之后就可以使用ec2 clone Codecommit的repo了

本地Mac用的是ssh连接,而ec2用的是https

III. EC2 User Data

在这里贴上我的EC2 User Data供参考

#!/bin/bash
yum update -y #yum update,没什么好说的

curl -L https://omnitruck.chef.io/install.sh | bash #安装chef-client,注意这个不是workstation,所以不能使用ChefDK,也不能直接用berks

yum install git -y #ec2 amazon-linux2系统出厂没有git
#设置git credential,上一个步骤的代码
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

git clone https://git-codecommit.com/your/repo/link /tmp/ec2_setup/ #从CodeCommit上clone到ec2
cp -R /tmp/ec2_setup/berks-cookbooks/* /cookbooks/ #把berks vendor生成的cookbooks提取出来

export CHEF_LICENSE=accept #设置环境变量让chef自动同意所有协议,这个也可以用--chef-license flag在运行时候指定
cd /cookbooks
chef-client -zr "recipe[ec2_setup]" #运行我的cookbook

IV. 每次更新cookbook的流程(本地Mac上)

  1. 更新所需的文件
  2. berks vendor
  3. git commit
  4. git push

V. 每次运行最新cookbook的流程(ec2上)

为了省事,我在cookbook中添加了一个template Resource,第一次执行的时候会在/root下生成一个bash script

#Cookbook Recipe
template '/root/chef-cron.sh' do
  source 'chef-cron.erb'
  mode '0777' #我还没学明白linux的文件权限,索性777
  action :create
end

chef-cron.erb, 里面没有任何变量,其实就是实际放在/root下的文件,跟第一次运行时候的脚本以后

#!/bin/bash
rm -rf /tmp/ec2_setup
git clone https://git-codecommit.ca-central-1.amazonaws.com/v1/repos/ec2-cookbook /tmp/ec2_setup/
rm -rf /cookbooks
mkdir /cookbooks
cp -R /tmp/ec2_setup/berks-cookbooks/* /cookbooks/
export CHEF_LICENSE=accept
cd /cookbooks
chef-client -zr "recipe[ec2_setup]"

这样以后每次想要运行最新版cookbook时只需要sudo bash /root/chef-cron.sh

我的脚本名字叫chef-cron,所以你应该也能看出来我想把它做成cronjob,定时运行 不过暂时这个功能不是刚需,因为你随时可以开启一个新的ec2实例,而且我就这一个ec2实例,进来手动执行一遍反倒是更方便 暂且标注为TODO

Auto Caddy DNS

没干出来呢,等做出来再补上 Caddy的正常安装版不包括Route53插件,想用的话只能自己compile,或者用binary,自己配置systemd service

暂时开放80和443端口,caddy要使用80端口测试域名,让caddy帮我处理证书的事情(开摆)

我本可以把ec2放到Auto Scaling Group中,配合Health Check永远保证有一个工作正常的节点,不过我没有Load Balancer,而我也想知道是什么导致我ec2上搭建的服务中断。因此最后还是没搞这个。

Licensed under CC BY-NC-SA 4.0
Last updated on Sep 17, 2022 17:06 EDT
Built with Hugo
Theme Stack designed by Jimmy