[关闭]
@adonia 2018-05-25T06:19:43.000000Z 字数 12663 阅读 234

Keppalived安装配置

nginx


安装

Note:

  • --prefix=/opt/nginx/keepalived指定keepalived的安装目录

  • --disable-lvs-syncd --disable-lvs表示禁用LVS功能,使用keepalived自带的vrrp协议创建和切换浮动IP

安装后的目录结构如下:

  1. /opt/nginx/keepalived
  2. |--bin
  3. \--etc
  4. |--keepalived
  5. |--keepalived.conf
  6. \--rc.d
  7. |--init.d
  8. |--keepalived
  9. \--sysconfig
  10. |--keepalived
  11. \--sbin
  12. |--keepalived

Note:

  • etc/keepalived/keepalived.conf为keepalived的默认配置文件

  • etc/rc.d/init.d/keepalived为keepalived给出的默认启动脚本

  • etc/sysconfig/keepalived为keepalived的启动参数定义,可以参照默认启动脚本

  • sbin/keepalived为keepalived的启动引导程序

配置

启动脚本

新建keepalived_ctl脚本,放置在$KEEPALIVED_HOME/bin目录下,用于控制keepalived的启停,如下:

  1. #!/bin/sh
  2. BIN=$(cd $(dirname "$0"); pwd)
  3. KEEPALIVED=$(cd $(dirname "$BIN"); pwd)
  4. PATH=$KEEPALIVED/sbin:$PATH
  5. PID_FILE=$KEEPALIVED/run/keepalived.pid
  6. VRRP_PID=$KEEPALIVED/run/vrrp.pid
  7. CHECKER_PID=$KEEPALIVED/run/checker.pid
  8. DAEMON=$(which keepalived)
  9. CONFIG=$KEEPALIVED/etc/keepalived/keepalived.conf
  10. RETVAL=0
  11. # RETVAL = 0 if running, != 0 if stopped
  12. status_keepalived() {
  13. if [ -f "${PID_FILE}" ]; then
  14. RETVAL=0
  15. for pid in $(cat "${PID_FILE}"); do
  16. kill -0 "${pid}" > /dev/null 2>&1 || RETVAL=3
  17. done
  18. kill -0 $(cat "${PID_FILE}") > /dev/null 2>&1
  19. if [ $? != 0 ]; then
  20. RETVAL=3
  21. fi
  22. else
  23. RETVAL=1
  24. fi
  25. }
  26. ensure_dir() {
  27. local dir=$KEEPALIVED/run
  28. if [ ! -d $dir ]; then
  29. mkdir -p $dir
  30. fi
  31. }
  32. start_keepalived() {
  33. status_keepalived
  34. if [ "${RETVAL}" = 0 ]; then
  35. echo "Keepalived is currently running"
  36. else
  37. RETVAL=0
  38. echo "Starting Keepalived"
  39. ensure_dir
  40. "${DAEMON}" -f "${CONFIG}" -l -D -d -S 0 -p "${PID_FILE}" -r "${VRRP_PID}" -c "${CHECKER_PID}"<&-
  41. RETVAL=$?
  42. case "${RETVAL}" in
  43. 0)
  44. echo "Finished starting Keepalived"
  45. echo "SUCCESS"
  46. ;;
  47. *)
  48. echo "Errored starting Keepalived"
  49. remove_pid
  50. echo "FAILED - check logs"
  51. RETVAL=1
  52. ;;
  53. esac
  54. fi
  55. }
  56. stop_keepalived() {
  57. status_keepalived
  58. if [ "${RETVAL}" = 0 ]; then
  59. for pid in $(cat "${PID_FILE}"); do
  60. killproc -p ${pid} -t 10 ${DAEMON} || RETVAL=$?
  61. done
  62. set -e
  63. if [ "${RETVAL}" = 0 ]; then
  64. remove_pid
  65. else
  66. echo "FAILED - check logs"
  67. fi
  68. else
  69. echo "Keepalived Manage not running"
  70. fi
  71. }
  72. remove_pid() {
  73. rm -f "${PID_FILE}"
  74. }
  75. case "$1" in
  76. start)
  77. start_keepalived
  78. ;;
  79. stop)
  80. echo "Stopping Keepalived..."
  81. stop_keepalived
  82. ;;
  83. status)
  84. status_keepalived
  85. ;;
  86. force-reload|reload|restart)
  87. echo -n "Restarting Keepalived: "
  88. restart_keepalived
  89. ;;
  90. *)
  91. echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
  92. RETVAL=1
  93. ;;
  94. esac
  95. exit "${RETVAL}"

配置文件

上述脚本中,指定了keepalived引用的配置文件为${ALIVED_HOME}/etc/keepalived/keepalived.conf
http://3ms.huawei.com/hi/group/1503825/wiki_2984117.html

Syslog

keepalived是使用的syslog-ng作为日志记录载体,Linux中常见的系统日志像/var/log/messages/var/log/localmessages等都是通过syslog控制的。

关于Suse Linux上的日志控制,有三个版本的实现---syslogrsyslogsyslog-ng,参考之间的区别

启动

Suse Linux系统上syslog的启动可以通过service syslog start的方式,但是需注意下,这里的syslog可能是上述三种的任一种。服务的控制脚本如下(部分):

  1. . /etc/sysconfig/syslog
  2. BINDIR=/sbin
  3. # update $SYSLOG_DAEMON if not up-to-date
  4. test -n "$SYSLOG_DAEMON" && \
  5. test -x "${BINDIR}/$SYSLOG_DAEMON" || {
  6. for SYSLOG_DAEMON in rsyslogd syslog-ng syslogd ; do
  7. test -x "${BINDIR}/$SYSLOG_DAEMON" && break
  8. done
  9. }
  10. # set daemon dependent variables
  11. rsocks=""
  12. start_klogd=yes
  13. case "$SYSLOG_DAEMON" in
  14. rsyslogd)
  15. syslog=rsyslogd
  16. mkdir -p -m 0750 /var/run/rsyslog
  17. if test "$2" = "early" ; then
  18. config=/etc/rsyslog.early.conf
  19. else
  20. config=/etc/rsyslog.conf
  21. fi
  22. compat=${RSYSLOGD_COMPAT_VERSION:-${RSYSLOGD_NATIVE_VERSION}}
  23. params="-c ${compat:-3} -f $config $RSYSLOGD_PARAMS"
  24. rsocks="/var/run/rsyslog/additional-log-sockets.conf"
  25. test -r "$config" && \
  26. while read one two rest ; do
  27. test "x$one" = 'x$ModLoad' && \
  28. test "x$two" = 'ximklog.so' && {
  29. start_klogd=no
  30. break
  31. }
  32. done < $config
  33. ;;
  34. syslog-ng)
  35. syslog=syslog-ng
  36. config=/etc/syslog-ng/syslog-ng.conf
  37. params="$SYSLOG_NG_PARAMS"
  38. ;;
  39. *)
  40. syslog=syslogd
  41. config=/etc/syslog.conf
  42. params="$SYSLOGD_PARAMS"
  43. ;;
  44. esac

Note:

  • 从第8行可以看出,服务的选取方式是依次检测sbin目录下,是否包含rsyslogdsyslog-ng或者syslogd(三种日志服务的daemon程序),检测到的第一个即为所使用的系统日志服务。

  • 测试所用的Suse Linux(Linux version 3.0.76-0.11-default),其上使用的syslog-ng,从39行可以看出其配置文件为/etc/syslog-ng/syslog-ng.conf

  • 具体脚本见/etc/init.d/syslog

配置

看下/etc/syslog-ng/syslog-ng.conf中的配置,大体如下:

  1. #
  2. # Global options.
  3. #
  4. options { long_hostnames(off); sync(0); perm(0640); stats(3600); };
  5. #
  6. # 'src' is our main source definition. you can add
  7. # more sources driver definitions to it, or define
  8. # your own sources, i.e.:
  9. #
  10. #source my_src { .... };
  11. #
  12. source src {
  13. #
  14. # include internal syslog-ng messages
  15. # note: the internal() soure is required!
  16. #
  17. internal();
  18. #
  19. # the default log socket for local logging:
  20. #
  21. unix-dgram("/dev/log");
  22. #
  23. # uncomment to process log messages from network:
  24. #
  25. #udp(ip("0.0.0.0") port(514));
  26. };
  27. #
  28. # Filter definitions
  29. #
  30. filter f_local { facility(local0, local1, local2, local3,
  31. local4, local5, local6, local7); };
  32. #
  33. # Some boot scripts use/require local[1-7]:
  34. #
  35. destination localmessages { file("/var/log/localmessages"); };
  36. log { source(src); filter(f_local); destination(localmessages); };

分为五个模块---optionssourcefilterdestinationlog

  1. options { long_hostnames(off); sync(0); perm(0640); stats(3600); };
  2. 更多选项如下
  3. chain_hostnames(yes|no) # 是否打开主机名链功能,打开后可在多网络段转发日志时有效
  4. long_hostnames(yes|no) # 是chain_hostnames的别名,已不建议使用
  5. keep_hostname(yes|no) # 是否保留日志消息中保存的主机名称
  6. use_dns(yes|no) # 是否打开DNS查询功能,
  7. use_fqdn(yes|no) # 是否使用完整的域名
  8. check_hostname(yes|no) # 是否检查主机名有没有包含不合法的字符
  9. bad_hostname(regexp) # 可通过正规表达式指定某主机的信息不被接受
  10. dns_cache(yes|no) # 是否打开DNS缓存功能
  11. dns_cache_expire(n) # DNS缓存功能打开时,一个成功缓存的过期时间
  12. dns_cache_expire_failed(n) # DNS缓存功能打开时,一个失败缓存的过期时间
  13. dns_cache_size(n) # DNS缓存保留的主机名数量
  14. create_dirs(yes|no) # 当指定的目标目录不存在时,是否创建该目录
  15. dir_owner(uid) # 目录的UID
  16. dir_group(gid) # 目录的GID
  17. dir_perm(perm) # 目录的权限,使用八进制方式标注,例如0644
  18. owner(uid) # 文件的UID
  19. group(gid) # 文件的GID
  20. perm(perm) # 文件的权限,同样,使用八进制方式标注
  21. gc_busy_threshold(n) # 当syslog-ng忙时,其进入垃圾信息收集状态的时间一旦分派的对象达到这个数字,syslog-ng就启动垃圾信息收集状态。默认值是:3000。
  22. gc_idle_threshold(n) # 当syslog-ng空闲时,其进入垃圾信息收集状态的时间一旦被分派的对象到达这个数字,syslog-ng就会启动垃圾信息收集状态,默认值是:100
  23. log_fifo_size(n) # 输出队列的行数
  24. log_msg_size(n) # 消息日志的最大值(bytes)
  25. mark(n) # 多少时间(秒)写入两行MARK信息供参考,目前没有实现
  26. stats(n) # 多少时间(秒)写入两行STATUS信息,默认值是:600
  27. sync(n) # 缓存多少行的信息再写入文件中,0为不缓存,局部参数可以覆盖该值。
  28. time_reap(n) # 在没有消息前,到达多少秒,即关闭该文件的连接
  29. time_reopen(n) # 对于死连接,到达多少秒,会重新连接
  30. use_time_recvd(yes|no) # 宏产生的时间是使用接受到的时间,还是日志中记录的时间;建议使用R_的宏代替接收时间,S_的宏代替日志记录的时间,而不要依靠该值定义。
  1. source s_name { internal(); unix-dgram("/dev/log"); udp(ip("0.0.0.0") port(514)); };
  2. file (filename) # 从指定的文件读取日志信息
  3. unix-dgram (filename) # 打开指定的SOCK_DGRAM模式的unix套接字,接收日志消息
  4. unix-stream (filename) # 打开指定的SOCK_STREAM模式的unix套接字,接收日志消息
  5. udp ( (ip),(port) ) # 在指定的UDP端口接收日志消息
  6. tcp ( (ip),(port) ) # 在指定的TCP端口接收日志消息
  7. sun-streams (filename) # 在solaris系统中,打开一个(多个)指定的STREAM设备,从其中读取日志消息
  8. internal() # syslog-ng内部产生的消息
  9. pipe(filename),fifo(filename) # 从指定的管道或者FIFO设备,读取日志信息
  1. filter f_name { not facility(news, mail) and not filter(f_iptables); };
  2. 更多规则函数如下
  3. facility(..) # 根据facility(设备)选择日志消息,使用逗号分割多个facility
  4. level(..) # 根据level(优先级)选择日志消息,使用逗号分割多个level,或使用“..”表示一个范围
  5. program(表达式) # 日志消息的程序名是否匹配一个正则表达式
  6. host(表达式) # 日志消息的主机名是否和一个正则表达式匹配
  7. match(表达式) # 对日志消息的内容进行正则匹配
  8. filter() # 调用另一条过滤规则并判断它的值
  9. 定义规则的时候也可以使用逻辑运算符and or not

Tips: filter中支持正则表达式进行匹配,支持逻辑运算符---notorand

  1. destination d_name { file("/var/log/messages"); };
  2. 更多动作如下
  3. file (filename) # 把日志消息写入指定的文件
  4. unix-dgram (filename) # 把日志消息写入指定的SOCK_DGRAM模式的unix套接字
  5. unix-stream (filename) # 把日志消息写入指定的SOCK_STREAM模式的unix套接字
  6. udp (ip),(port) # 把日志消息发送到指定的UDP端口
  7. tcp (ip),(port) # 把日志消息发送到指定的TCP端口
  8. usertty(username) # 把日志消息发送到已经登陆的指定用户终端窗口
  9. pipe(filename),fifo(filename) # 把日志消息发送到指定的管道或者FIFO设备
  10. program(parm) # 启动指定的程序,并把日志消息发送到该进程的标准输入

可以看出,日志的输出目标可以是文件系统,也可以是远程服务。

  1. log { source(s_name); filter(f_name); destination(d_name);};

Tips: filter可选。


实例

既然keepalived中是使用syslog来记录日志的,那就可以看下如何输出keepalived的日志。

再看下keepalived的日志脚本(keepalived_ctl),第46行,内容如下:

  1. "${DAEMON}" -f "${CONFIG}" -l -D -d -S 0 -p "${PID_FILE}" -r "${VRRP_PID}" -c "${CHECKER_PID}"<&-

查看下keepalived的启动帮助:

  1. Usage: ./keepalived [OPTION...]
  2. -f, --use-file=FILE Use the specified configuration file
  3. -P, --vrrp Only run with VRRP subsystem
  4. -C, --check Only run with Health-checker subsystem
  5. -l, --log-console Log messages to local console
  6. -D, --log-detail Detailed log messages
  7. -S, --log-facility=[0-7] Set syslog facility to LOG_LOCAL[0-7]
  8. -X, --release-vips Drop VIP on transition from signal.
  9. -V, --dont-release-vrrp Don't remove VRRP VIPs and VROUTEs on daemon stop
  10. -I, --dont-release-ipvs Don't remove IPVS topology on daemon stop
  11. -R, --dont-respawn Don't respawn child processes
  12. -n, --dont-fork Don't fork the daemon process
  13. -d, --dump-conf Dump the configuration data
  14. -p, --pid=FILE Use specified pidfile for parent process
  15. -r, --vrrp_pid=FILE Use specified pidfile for VRRP child process
  16. -c, --checkers_pid=FILE Use specified pidfile for checkers child process
  17. -v, --version Display the version number
  18. -h, --help Display this help message

可以看出启动参数中的-S 0即指明了输出到syslog日志管道的路径入口---local0

Note:

local0-local7syslog提供给用户自定义的日志输出管道,用于记录本地进程的日志信息。也就是你可以在启动脚本中,随意指定0~7中的任一个。但是为了精确得到keepalived的日志,还是要规划好。

按照上述keepalived的启动脚本定义来看,只需要在syslog中,将local0中的日志输出到指定的文件即可了。

/etc/syslog-ng/syslog-ng.conf中增加如下配置:

  1. # 指定keepalived的日志过滤
  2. filter f_keepalived { facility(local0); };
  3. # 指定keepalived的日志输出至'/opt/nginx/log/keepalived.log'
  4. destination d_keepalived { file("/opt/nginx/log/keepalived.log"); };
  5. log { source(src); filter(f_keepalived); destination(d_keepalived); };

Note: 注意格式,尤其是;

重启syslog---service syslog restart

使用root用户执行keepalived_ctl start,启动keepalived服务。查看/opt/nginx/log目录,发现其下没有定义的keepalived.log日志文件。再查看下/var/log/localmessages,日志内容如下:

  1. un 6 11:13:17 NKG1000009441 Keepalived[95840]: Starting Keepalived v1.2.20 (05/19,2016)
  2. Jun 6 11:13:17 NKG1000009441 Keepalived[95841]: Starting VRRP child process, pid=95842
  3. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Registering Kernel netlink reflector
  4. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Registering Kernel netlink command channel
  5. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Registering gratuitous ARP shared channel
  6. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Opening file '/opt/nginx/keepalived/etc/keepalived/keepalived.conf'.
  7. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: VRRP_Instance(NGINX_1) removing protocol VIPs.
  8. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: ------< Global definitions >------
  9. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Router ID = LVS_DEVEL
  10. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: VRRP IPv4 mcast group = 224.0.0.18
  11. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: VRRP IPv6 mcast group = ff02::12
  12. Jun 6 11:13:17 NKG1000009441 Keepalived_vrrp[95842]: Gratuitous ARP delay = 5
  13. ......

可以看出keepalived已经启动成功,日志输出也是输出到了local0中(注: localmessages中收集了local0-local7的日志信息)。但是,为什么在/opt/nginx/log目录下却没有keepalived的日志呢?

那换个角度试试,观察可以发现,syslog的日志一般是存储在/var/log目录下的,那把keepalived的日志路径修改为/var/log/keepalived.log。修改/etc/syslog-ng/syslog-ng.conf配置,将d_keepalived的路径修改为/var/log/keepalived.log

重启syslogkeepalived,查看日志正常。

那么,使用-S 0的方式来收集keepalived的日志是可行的,现在就要看下怎样来更改日志存储的路径,最好是放置在keepalived进程运行的目录下,而不是系统的默认路径,方便用户定位。

AppArmor

AppArmor是一款与SeLinux类似的安全框架/工具,其主要作用是控制应用程序的各种权限,例如对某个目录/文件的读/写,对网络端口的打开/读/写等等。

AppArmor通过配置文件(profile)来指定应用程序的权限,相关的配置放置在/etc/apparmor.d目录下:

  1. drwxr-xr-x 2 root root 4096 Mar 27 2014 abstractions
  2. -rw-r--r-- 1 root root 732 Jan 17 2013 bin.ping
  3. drwxr-xr-x 2 root root 4096 Mar 27 2014 program-chunks
  4. -rw-r--r-- 1 root root 809 Jan 17 2013 sbin.klogd
  5. -rw-r--r-- 1 root root 1350 Jun 6 11:05 sbin.syslog-ng
  6. -rw-r--r-- 1 root root 1087 Jan 17 2013 sbin.syslogd
  7. drwxr-xr-x 2 root root 4096 Mar 27 2014 tunables
  8. -rw-r--r-- 1 root root 231 Sep 26 2011 usr.lib.PolicyKit.polkit-explicit-grant-helper
  9. -rw-r--r-- 1 root root 588 Oct 17 2012 usr.lib.PolicyKit.polkit-grant-helper
  10. -rw-r--r-- 1 root root 255 Sep 26 2011 usr.lib.PolicyKit.polkit-grant-helper-pam
  11. -rw-r--r-- 1 root root 534 Oct 17 2012 usr.lib.PolicyKit.polkit-read-auth-helper
  12. -rw-r--r-- 1 root root 177 Sep 26 2011 usr.lib.PolicyKit.polkit-resolve-exe-helper
  13. -rw-r--r-- 1 root root 476 Sep 26 2011 usr.lib.PolicyKit.polkit-revoke-helper
  14. -rw-r--r-- 1 root root 424 Sep 26 2011 usr.lib.PolicyKit.polkitd
  15. -rw-r--r-- 1 root root 696 Jan 17 2013 usr.sbin.avahi-daemon
  16. -rw-r--r-- 1 root root 842 Jan 17 2013 usr.sbin.identd
  17. -rw-r--r-- 1 root root 853 Jan 17 2013 usr.sbin.mdnsd
  18. -rw-r--r-- 1 root root 1246 Jan 17 2013 usr.sbin.nscd
  19. -rw-r--r-- 1 root root 1880 Jan 17 2013 usr.sbin.ntpd
  20. -rw-r--r-- 1 root root 745 Jan 17 2013 usr.sbin.traceroute

可以看到syslog的配置为/etc/apparmor.d/sbin.syslog-ng,如下:

  1. #include <tunables/global>
  2. #define this to be where syslog-ng is chrooted
  3. @{CHROOT_BASE}=""
  4. /sbin/syslog-ng {
  5. #include <abstractions/base>
  6. #include <abstractions/consoles>
  7. #include <abstractions/nameservice>
  8. #include <abstractions/mysql>
  9. capability chown,
  10. capability dac_override,
  11. capability fsetid,
  12. capability fowner,
  13. capability sys_tty_config,
  14. capability sys_resource,
  15. /dev/log w,
  16. /dev/syslog w,
  17. /dev/tty10 rw,
  18. /dev/xconsole rw,
  19. /etc/syslog-ng/* r,
  20. @{PROC}/kmsg r,
  21. /etc/hosts.deny r,
  22. /etc/hosts.allow r,
  23. /sbin/syslog-ng mr,
  24. /usr/share/syslog-ng/** r,
  25. # chrooted applications
  26. @{CHROOT_BASE}/var/lib/*/dev/log w,
  27. @{CHROOT_BASE}/var/lib/syslog-ng/syslog-ng.persist* rw,
  28. @{CHROOT_BASE}/var/log/** w,
  29. @{CHROOT_BASE}/var/run/syslog-ng.pid krw,
  30. @{CHROOT_BASE}/var/run/syslog-ng.ctl rw,
  31. /var/run/syslog-ng/additional-log-sockets.conf r,
  32. }

上述配置定义了syslog可以对目录和文件的访问权限,如:

由此可见,如果想要通过syslog将keepalived的日志输出到/opt/nginx/log/keepalived.log下,syslog服务必须对/opt/nginx/log目录具有写权限,或者对/opt/nginx/log/keepalived.log文件具有写权限(注:文件可以不存在,但是目录需要存在)。

/etc/apparmor.d/sbin.syslog-ng中增加如下配置:

  1. /opt/nginx/log/keepalived.log rw,

重启AppArmor---/etc/init.d/boot.apparmor restart
重启syslogkeepalived,在/opt/nginx/log/keepalived.log中应该就可以看到日志内容了。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注