建立 AWS 到 IDC 的VPN

由于我们的很多运维工具都部署在自己的 IDC 里面,比如 Puppet、YUM 源、NTP 服务器、Nginx 日志分析工具 等,如果不打通 AWS 到 IDC 的内网,这些工具都要在 AWS 搭建一份,太麻烦,so do it .

一开始我想使用 AWS 的「VPN连接」服务(文档在 这里 )来做,但是要求 IDC 端是 cisco 路由器等硬件设备,我们 IDC 没有这些设备,所以只能找机器来做了。

 

1.机器是 Centos6,改一下脚本,在两台机器上执行。

#!/bin/bash
#L_PUBLIC=$(curl -s ip.cn | grep -Po ‘\d+\.\d+\.\d+\.\d+’)
L_PUBLIC=$L_PUBLIC
R_PUBLIC=$R_PUBLIC
L_PRIVATE=$L_PRIVATE
R_PRIVATE=$R_PRIVATE
TUNL=tunl-aws
TTL=255

echo "Loading kernel modules…"
modprobe -av ipip
echo "Setting up tunnel…"
ip tunnel del $TUNL &>/dev/null || true # delete old tunnel first
ip tunnel add $TUNL mode ipip local $L_PUBLIC remote $R_PUBLIC ttl $TTL
ip link set $TUNL up
ip addr add $L_PRIVATE peer $R_PRIVATE dev $TUNL
ip route add $R_PRIVATE dev $TUNL
echo "Testing tunnel: pinging from $L_PRIVATE to $R_PRIVATE …"
ping -c1 $R_PRIVATE
[[ $? = 0 ]] && echo "Tunnel is set up successfully."

L_PUBLIC 是 本地机器公网IP,R_PUBLIC 是对方机器公网IP,L_PRIVATE 是 本地私有IP,R_PRIVATE 是对方私有IP,L_PRIVATE 和 R_PRIVATE 在一个网段(两个 PRIVATE IP 用于两端通信,因为是两个IP,所以划一个 /30 的网段就行了)。

要注意两点:

1). AWS 端机器的 L_PUBLIC 要写内网IP,而不是弹性IP(这点应该和 AWS 的网络结构有关),否则执行脚本之后也无法 ping 对方的 PRIVATE IP.

2). 两台机器 net.ipv4.ip_forward 要设置为 1 .

 

2.配置好隧道之后,还要在 两台机器上添加路由,比如我在 IDC 机器上增加:

route add -net 172.30.0.0/16 gw 10.0.20.34

在 AWS 机器上增加:

route add -net 10.0.0.0/8 gw 10.0.20.33

172.30.0.0/16 是 AWS 的网段,10.0.0.0/8 是 IDC 的网段。

 

3.需要在两端所有的机器上增加路由表,在 IDC 可以通过 Puppet 增加,更好的方式是通过 ospf 发布路由,还可以向公司的网络工程师帮忙。

在 AWS 可以修改 「VPC 的路由表」,增加一条到 IDC 网段的路由,我这里是把 10.0.0.0/8 网段的路由指向 AWS 机器 内网的接口上,如图:

S488C0Q)5W$QUW0@E[E`SNY

另外要注意的是,增加路由表之后,在 ec2 机器上 用 route -n 是看不到增加的路由的,但是确实已经生效;当 ec2 机器重启之后,此时用 route -n 可以看到增加的路由。

 

理论上说,完成上面的步骤之后,VPN 就已经 OK 了,但是这里是 AWS,不是自己的网络架构,所以我又遇到了坑。。。。

上面说了要把两方的机器的 net.ipv4.ip_forward 打开,但是在 ec2 机器上打开之后,还需要关闭 ec2 的 「源/目标检查」,如图:

bbbb

源/目标检查 的解释如下:

Changing the Source/Destination Checking of a Network Interface The Source/Destination Check attribute controls whether source/destination checking is enabled on the instance. Disabling this attribute enables an instance to handle network traffic that isn’t specifically destined for the instance. For example, instances running services such as network address translation, routing, or a firewall should set this value to disabled. The default value is enabled.

最后放张图,看下成果。。。。

aaaa

 

搭建 Puppet dashboard 来监测 Puppet 更新失败的问题

最近花了几天搞了一下 Puppet 更新失败的问题,总结了一下遇到的问题,问题还挺多的,这就是开发有登陆机器权限的恶果,问题列表:

1.crontab 任务被注释(我们使用 crontab 来更新 Puppet);

2.证书问题,基本上都是证书已经存在,证书申请失败,此时需要到 Puppet ca 删掉原有证书,并清空本机证书,重新申请;

这种情况 Puppet Master 是拿不到更新信息的,所以 Puppet Dashboard 看不到这种机器。

一般是由改主机名引起,可以通过修改改名脚本彻底解决:

1). 改名之前去 Puppet ca 删除原主机名的证书;

2). 删除本机的证书文件;

3). 查看 Puppet ca 中是否已经存在新主机名的证书;

4). 如果存在,删除 Puppet ca 中的新主机名证书;

5). 真正改名。

3.Puppet 依赖的 ruby 环境被损坏;

4.升级 Python 导致 yum 不可用;

5.普通用户进程数达到上限导致 lighttpd(Nginx 七层检测用) 起不来;

6.升级 Python 导致 supervisor 启动不了;

7.一些自定义 rpm 包不支持 Centos7,启动失败;

8.mysql-libs 和 Percona-Server-server 冲突;

解决方法:
安装 Percona-Server-shared-compat 代替 mysql-libs 。

9.Puppet 忽略此节点,返回400;

通过修改 puppet_node_classifer.py 解决,忽略的节点也返回执行 Puppet 主任务的 crontab配置。

10.机器死机。

 

 

问题多多,所以安装 Puppet Dashboard 来观察哪些机器更新失败。

1.安装:

yum install rubygem-rake ruby-mysql mysql-server puppet-dashboard

2.修改 /etc/my.conf,在 [mysqld] 内加入
max_allowed_packet = 32M

然后 在 [mysqld] 和 [client ]内加入
defalut-character-set = utf8

3.创建mysql数据库和用户

create database dashboard;
grant all on dashboard.* to puppet@’10.%’ identified by ‘puppetdashboard’;
flush privileges;

4.修改 /usr/share/puppet-dashboard/config/database.yml

production:
database: dashboard
username: puppet
password: dashboard
encoding: utf8
adapter: mysql

5.导入表结构

cd /usr/share/puppet-dashboard
rake gems:refresh_specs
rake RAILS_ENV=production db:migrate

6.测试 puppet-dashboard 能否工作,端口起在 3000

/usr/share/puppet-dashboard/script/server -e production

7.启动

/usr/share/puppet-dashboard/script/server -e production -d
env RAILS_ENV=production /usr/share/puppet-dashboard/script/delayed_job -p dashboard -n 4 -m start
/etc/init.d/mysql.server start

8.访问。

通过 http://puppetdashboard:3000

 

额外要注意的几点:

1.Puppet client 更新 Puppet 的时候需要指定 report 参数,比如:
/usr/bin/puppet agent –onetime –no-daemonize –server=puppetlb.corp.nosa.me –ca_server=puppetca.corp.nosa.me report

2.要在 Puppet master 的 [main] 下面增加两行:
reports = http,store
reporturl = http://puppetdashboard:3000/reports/upload

3.默认是 UTC 时区,修改成北京时间,编辑文件 /usr/share/puppet-dashboard/config/settings.yml,修改 time_zone:

time_zone: ‘Beijing’

4.dashboard 的数据库文件增加很快,如果不清理,很快就会占满硬盘,最好每天清理一次,清理脚本可如下(保留一天):

cd /usr/share/puppet-dashboard
env RAILS_ENV=production rake reports:prune upto=1 unit=day
env rake RAILS_ENV=production db:raw:optimize

 

 

最后,要通过 api 获取更新失败的机器列表 和 通过 api 查询、删除 证书 可以参考 这里,查询和删除证书要认证,如果怕麻烦 可以修改 Puppet ca 的 /etc/puppet/auth.conf ,增加 allow *,只是不太安全。