Tag Archives: 规范化

配置管理 vs provisioning 及配置管理工具的几点随想

关于“怎么构建一个确定的运行环境”这件事,有多个流派,其中一个是配置管理,另一个是provision流。 配置管理流派,适合于物理服务器、虚拟机等等,有机会长期存活的环境。因为它们有机会长期存活,在其生命周期里需要使用技术手段去维持一个有序可控的状态,排除软件运行时累计的旧日志和临时数据、手工操作带来的计划外变更等等影响。 而provision流派,直接从模版构建一个(容器或虚拟机)实例起来运行,用完就扔,基本上没有重新调整的价值。这种东西往往依赖于服务注册与发现机制,因为在它真正起来运行之前,网络通信方面的参数无法被外界预知,外界不知道如何跟它通信;对于日志和数据,也提倡使用显式远程的方式去访问。   再说说配置管理工具的几点随想: 我最近一年在给下属的一个公司做一些产品运维工作,其中遇到把设备投放到客户的网络环境去运行这种情况。考虑到网络通信的问题,我只好选择了“反向连接”的saltstack软件。在通信的角度来考虑,配置管理工具可以分为:master主动连接minion(ansible等)、minion主动连接master(puppet、saltstack等) 今天听师兄说他的一个同事因为认知问题,把一批机器glibc给删掉了。尝试恢复的时候,他发现ansible无法正常运行(我猜想sshd启动python的时候因为缺glibc而失败了),只好改用saltstack。因为saltstack的salt-minion是长期运行的,一旦启动之后,外部依赖较少,才能在glibc被删除这么极端的条件下苟活。在“有没有agent”的角度考虑,配置管理工具可以分为:有agent(saltstack、puppet、cfengine等)和无agent(ansible等) 另外,其实还有一个分类角度,就是主动和被动。saltstack和ansible是主动式的,运维工程师可有更多的主动权,可以用手工指定minion,或者指定批次规模分批执行等手段,控制变更的节奏;cfengine、puppet等是agent定时刷新式的(虽然听说也可以主动?不过我经验较少还没用过),得按定时器来,这种情况下就得运维工程师多看监控了,一不小心,死都不知道怎么死的。

Posted in 默认分类 | Tagged | Leave a comment

为什么有些系统是动作式的而非描述式的?

接手一个旧系统,上线发布是“拷贝文件过去,替换掉,重启服务”这样的,而不是“把编译好的东西打包,发上去安装,包的scripts部分带有重启动作”。 是否打包、包里包含什么,很有讲究: 查询当前版本号:XXX -v vs rpm -qi XXX 重启服务:killall XXX && sleep 30 && XXX vs /sbin/service XXX restart 删除软件:rm -fr XXX vs rpm -e XXX 安装依赖: ldd XXX |xargs -n1 yum provides |xargs yum -y install vs rpm -i XXX … Continue reading

Posted in 默认分类 | Tagged | Leave a comment

Sentry整理杂记

本讨论均基于Sentry 7.7版本 插件机制 自带插件 src/sentry/plugins/ 每插件一个目录 自带插件loader:src/sentry/conf/server.py 里的 INSTALLED_APPS tuple 外装插件loader:utils/runner.py 里的 install_plugins()函数,对iter_entry_points()遍历并将其加入 INSTALLED_APPS tuple 中 外装插件注册:插件的 setup.py 里执行注册 entry_points 的过程: 例:https://github.com/getsentry/sentry-groveio/blob/master/setup.py 参考资料:https://pythonhosted.org/setuptools/pkg_resources.html #!/usr/bin/env python import pkg_resources for ep in pkg_resources.iter_entry_points(‘sentry.apps’): print str(ep) for ep in pkg_resources.iter_entry_points(‘sentry.plugins’): print str(ep) sentry-jira … Continue reading

Posted in 默认分类 | Tagged , | Leave a comment

Python import语句一处文档和行为不一致的问题

话说,我团运维组曾一度极为昌盛,可惜后来公司里有人搞政治,好好的一个组被拆成了好几个,后来竟分属不同大部门,工作关系也开始形同陌路。考虑到丰富经验,换换方向,今年7月,我转岗到了运维开发组,开始真正把Python作为职业。 无奈,基础差,还得学,8月18日,这么吉利的一天,我第n次在看Python的文档,看着看着,注意到一些标准库的名字是带点的,比如os.path,再比如logging.config等。然后就开始help各个模块,发现os.path的名字居然不叫path而是posixpath!!再看,logging是个package,但os居然是个module!! 于是,问题就来了: Python语言里对 import A.B.C 这种形式是这么规定的: when using syntax like import item.subitem.subsubitem, each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function … Continue reading

Posted in 默认分类 | Tagged , , | Leave a comment

墨菲定律之多处保存必然会出现不一致——谈Linux上的时区问题

技术部的工作日报,原本是早晨9点发,脚本换了一台服务器运行之后变成17点了。算算时差也知道是时区问题。 检查了一下, /etc/timezone 内容误为 Etc/UTC,而 /etc/localtime 是从 /usr/share/zoneinfo/Asia/Shanghai 复制过来的,二者不一致。date命令使用 /etc/localtime 而 cron 按 /etc/timezone 文件执行,于是造成了执行时间不对的问题 另外需要注意的是,cron 只在开始运行时读取一次该文件,而每分钟唤醒时不再读取,所以改过文件之后还得重启该服务;又得注意的是,service cron stop 似乎并不会终止cron进程,所以……你懂的 以上就是墨菲定律之:多处保存,必然会出现不一致

Posted in 默认分类 | Tagged , | Leave a comment

MySQL 备份、版本兼容性二三事

最近几天在筹备多做一个 slave 数据库,所以就用 InnoDB Hot Backup 工具把原来的 slave 库备份了一份,拷贝过来,执行了一段 binlog 之后卡住了,然后发现上述工具对 ARCHIVE 存储引擎的表没有考虑,没把数据文件复制过来。于是改用 Percona 出品的 xtrabackup 工具,其 innobackupex 脚本考虑的比较周全。这样总算搞到一份相对完整的备份。 搞到备份数据之后,我又想尝鲜,于是装了 Percona Server (即 MySQL 的一个增强 fork)的 5.5 版本,结果发现无法操作上述 ARCHIVE 存储引擎的表。查了查 MySQL 5.1 的文档,说从 5.0 到 5.1 之间,ARCHIVE存储引擎变了存储格式,不可能兼容,要求 dump/restore 操作。服了…… 考虑到 … Continue reading

Posted in 默认分类 | Tagged , , , , , , | Leave a comment

不能念叨啊,一念叨就出事——兼谈xen的network-bridge脚本问题

昨晚还说呢,如果今天一天没事,这周就算安全过去了,@sgub 和@chifeng 都告诫我说不能念叨这事,今天果然! 下午,同事远程关闭错了机器。重新开机之后,发现 xenbr0 网桥没有了。看了一下,是 /etc/xen/scripts/network-bridge 没成功运行造成的。这个脚本用默认路由所在的网卡做一个网桥,然后把虚拟机接在这个网桥上,以便使虚拟机能直接上网。但我们的服务器却有俩公网IP和俩默认路由,就把那个脚本搞糊涂了。 其实这俩默认路由是路由器上的同一个接口的两个 IP 地址,连 MAC 都一样的。我删除掉其中一个默认路由,再运行network-bridge 脚本,就成功了。

Posted in 默认分类 | Tagged , , , | Leave a comment

有人忘记在 ifcfg 里写 NETMASK 了,结果……

我的好兄弟、大学同学谢某人,在虚拟机里玩 RHEL+Oracle 的时候,遇到一个诡异的事情,就是 RHEL 开机后 IP 地址会自动变化。我原以为是他装 Oracle 的时候某个开机自动执行的命令更改了地址,所以就在开机的各 rc 脚本之间夹带执行一次 ifconfig 命令,发现在开机过程中 IP 地址始终都是没有变化的。持续 ping 该机器,发现在出现登录提示符后才 ping 不通,并且提示符后还出现了 iscsi-initiator 关于断开和 target 的网络连接的错误提示信息。 没办法,看日志吧。/var/log/messages 日志明明白白的写着:NetworkManger 认为长度为零的 IP prefix 是无效的,因此接管了该网卡,并按 Auto eth0 设置了该网卡。看了看 ifcfg 文件,里面果然是没写掩码。此时谢同学不服气的嚷嚷,说另一个虚拟机也是这么写的,就不会自动变 IP。过去看了一下,发现那边没启动 NetworkManager 服务。哈哈…… 不过有个问题,ifconfig 命令对于不带掩码的 IP … Continue reading

Posted in 默认分类 | Tagged , , , , | Leave a comment

yum的$releasever真是太反动了

来看这篇文章的人,大都应该同意《Unix编程艺术》中提到的那些观点吧。今天就给大家看一个反例:yum 的 $releasever 变量 在 /etc/yum.repos.d/ 目录下的软件库定义文件中,常常会在 baseurl 的路径中提到 $releasever 这个变量,表示当前发行版的大版本号,但大家知道这个变量是在哪设置的吗?我 grep 了整个 etc 目录都没找到,还是看了 yum.conf 才知道的,是在 yum.conf 文件里 distroverpkg 选项定义的。但这个选项就很有问题: distroverpkg 和 releasever 名字不同,且看不出什么联系 distroverpkg 的值,并不是明文,而是“redhat-release”。不知道大家看到这个会有什么想法,反正我是首先想到了 /etc/redhat-release 文件,但我错了。实际上指的是 redhat-release 这个RPM包。所谓“distroverpkg=redhat-release”的意思,其实是将 $releasever 设置为 redhat-release 这个RPM包的版本号 够变态吧?别人都是直接赋值,或者 include 一个各种变量定义的文件进来,而yum竟然用某个包的属性作为值,违反了“everything is file”的原则。烂!用属性实现,则相关软件必须能读取属性。这个功能对于yum来说无所谓,但是对于别的软件呢?还得特地加入rpm相关的代码才能实现,加入了平台相关特性,降低了可移植性,麻烦。正确的方法是以文件内容作为表示形式。当然了,这样的话用属性就没意义了,yum还能减点肥。 … Continue reading

Posted in 默认分类 | Tagged , , , | 14 Comments

这几天玩了一下kexec

kexec 是一个快速重启动 Linux 系统的工具,其快速主要体现在是从内核开始启动而不是从硬件初始化开始,在当今硬件越来越复杂,开机自检越来越慢的条件下,kexec 可算是提高生产力的一大发明。 kexec 的操作分为两步: 加载内核到内存 运行刚才加载的内核 第一步的语法为 kexec -l  内核文件名 –initrd=initrd文件名 –append=内核参数。注意等号必不可少,否则,虽然 kexec 不报错,但是内核启动时会失败;第二部用 kexec -e 即可。通过查看 /sys/kernel/kexec_loaded 的内容可以判断是否已经加载内核。 目前遇到的问题有这几个: cciss HP SmartArray驱动在重启内核时会失败,导致无法正常进行下去 没搞明白如何用 kexec 加载 xen hypervisor 相信很快就会搞明白的。 同时提一下,发行版提供的 kexec 软件包带有 /etc/init.d/ 脚本,可以把正常的 reboot 操作转变成 kexec … Continue reading

Posted in 默认分类 | Tagged , , , , | 3 Comments