Python模块之psutil

[TOC] 用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。 在Python中获取系统信息的另一个好办法是使用psutil这个第三方模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。 安装psutil 如果安装了Anaconda,psutil就已经可用了。否则,需要在命令行下通过pip安装: $ pip install psutil 获取CPU信息 我们先来获取CPU的信息: >>> import psutil >>> psutil.cpu_count() # CPU逻辑数量 4 >>> psutil.cpu_count(logical=False) # CPU物理核心 2 # 2说明是双核超线程, 4则是4核非超线程 统计CPU的用户/系统/空闲时间: >>> psutil.cpu_times() scputimes(user=10963.31, nice=0.0, system=5138.67, idle=356102.45) 再实现类似top命令的CPU使用率,每秒刷新一次,累计10次: >>> for x in range(10): ... psutil.cpu_percent(interval=1, percpu=True) ... [14.0, 4.0, 4.0, 4.0] [12.0, 3.0, 4.0, 3.0] [8.0, 4.0, 3.0, 4.0] [12.0, 3.0, 3.0, 3.0] [18.8, 5.1, 5.9, 5.0] [10.9, 5.0, 4.0, 3.0] [12.0, 5.0, 4.0, 5.0] [15.0, 5.0, 4.0, 4.0] [19.0, 5.0, 5.0, 4.0] [9.0, 3.0, 2.0, 3.0] 获取内存信息 使用psutil获取物理内存和交换内存信息,分别使用: ...

June 26, 2016

Linux网页缓存之varnish

[TOC] 程序的运行具有局部性特征: 时间局部性:一个数据被访问过之后,可能很快会被再次访问 空间局部性:一个数据被访问时,其周边的数据也有可能被访问到 cache:命中 热区:局部性; 时效性: 缓存空间耗尽:LRU 过期:缓存清理 缓存命中率:hit/(hit+miss) (0,1) 页面命中率:基于页面数量进行衡量 字节命中率:基于页面的体积进行衡量 缓存与否: 私有数据:private,private cache; 公共数据:public, public or private cache; Cache-related Headers Fields The most important caching header fields are: Expires:过期时间; Expires:Thu, 22 Oct 2026 06:34:30 GMT Cache-Control Etag If-None-Match Last-Modified If-Modified-Since Vary Age 缓存有效性判断机制: 过期时间:Expires HTTP/1.0 Expires HTTP/1.1 Cache-Control: maxage= Cache-Control: s-maxage= 条件式请求: Last-Modified/If-Modified-Since Etag/If-None-Match Expires:Thu, 13 Aug 2026 02:05:12 GMT Cache-Control:max-age=315360000 ETag:"1ec5-502264e2ae4c0" Last-Modified:Wed, 03 Sep 2014 10:00:27 GMT 缓存层级: 私有缓存:用户代理附带的本地缓存机制; 公共缓存:反向代理服务器的缓存功能; User-Agent <--> private cache <--> public cache <--> public cache 2 <--> Original Server 请求报文用于通知缓存服务如何使用缓存响应请求: cache-request-directive = "no-cache", | "no-store" | "max-age" "=" delta-seconds | "max-stale" [ "=" delta-seconds ] | "min-fresh" "=" delta-seconds | "no-transform" | "only-if-cached" | cache-extension 响应报文用于通知缓存服务器如何存储上级服务器响应的内容: cache-response-directive = "public" | "private" [ "=" <"> 1#field-name <"> ] | "no-cache" [ "=" <"> 1#field-name <"> ],可缓存,但响应给客户端之前需要revalidation; | "no-store" ,不允许存储响应内容于缓存中; | "no-transform" | "must-revalidate" | "proxy-revalidate" | "max-age" "=" delta-seconds | "s-maxage" "=" delta-seconds | cache-extension 开源解决方案: squid: varnish: varnish官方站点: http://www.varnish-cache.org/ Community Enterprise This is Varnish Cache, a high-performance HTTP accelerator. 程序架构: Manager进程 Cacher进程,包含多种类型的线程: accept, worker, expiry, ... shared memory log: 统计数据:计数器; 日志区域:日志记录; varnishlog, varnishncsa, varnishstat... 配置接口:VCL Varnish Configuration Language, vcl complier --> c complier --> shared object varnish的程序环境: /etc/varnish/varnish.params: 配置varnish服务进程的工作特性,例如监听的地址和端口,缓存机制; /etc/varnish/default.vcl:配置各Child/Cache线程的缓存工作属性; 主程序: /usr/sbin/varnishd CLI interface: /usr/bin/varnishadm Shared Memory Log交互工具: /usr/bin/varnishhist /usr/bin/varnishlog /usr/bin/varnishncsa /usr/bin/varnishstat /usr/bin/varnishtop 测试工具程序: /usr/bin/varnishtest VCL配置文件重载程序: /usr/sbin/varnish_reload_vcl Systemd Unit File: /usr/lib/systemd/system/varnish.service varnish服务 /usr/lib/systemd/system/varnishlog.service /usr/lib/systemd/system/varnishncsa.service 日志持久的服务; varnish的缓存存储机制( Storage Types): -s [name=]type[,options] ・ malloc[,size] 内存存储,[,size]用于定义空间大小;重启后所有缓存项失效; ・ file[,path[,size[,granularity]]] 文件存储,黑盒;重启后所有缓存项失效; ・ persistent,path,size 文件存储,黑盒;重启后所有缓存项有效;实验; varnish程序的选项: 程序选项:/etc/varnish/varnish.params文件 -a address[:port][,address[:port][...],默认为6081端口; -T address[:port],默认为6082端口; -s [name=]type[,options],定义缓存存储机制; -u user -g group -f config:VCL配置文件; -F:运行于前台; ... 运行时参数:/etc/varnish/varnish.params文件, DEAMON_OPTS DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" -p param=value:设定运行参数及其值; 可重复使用多次; -r param[,param...]: 设定指定的参数为只读状态; 重载vcl配置文件: ~ ]# varnish_reload_vcl varnishadm -S /etc/varnish/secret -T [ADDRESS:]PORT help [<command>] ping [<timestamp>] auth <response> quit banner status start stop vcl.load <configname> <filename> vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> vcl.discard <configname> vcl.list param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list vcl.show [-v] <configname> backend.list [<backend_expression>] backend.set_health <backend_expression> <state> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list 配置文件相关: vcl.list vcl.load:装载,加载并编译; vcl.use:激活; vcl.discard:删除; vcl.show [-v] <configname>:查看指定的配置文件的详细信息; 运行时参数: param.show -l:显示列表; param.show <PARAM> param.set <PARAM> <VALUE> 缓存存储: storage.list 后端服务器: backend.list VCL: ”域“专有类型的配置语言; state engine:状态引擎; VCL有多个状态引擎,状态之间存在相关性,但状态引擎彼此间互相隔离;每个状态引擎可使用return(x)指明关联至哪个下一级引擎;每个状态引擎对应于vcl文件中的一个配置段,即为subroutine vcl_hash --> return(hit) --> vcl_hit Client Side: vcl_recv, vcl_pass, vcl_hit, vcl_miss, vcl_pipe, vcl_purge, vcl_synth, vcl_deliver vcl_recv: hash:vcl_hash pass: vcl_pass pipe: vcl_pipe synth: vcl_synth purge: vcl_hash --> vcl_purge vcl_hash: lookup: hit: vcl_hit miss: vcl_miss pass, hit_for_pass: vcl_pass purge: vcl_purge Backend Side: vcl_backend_fetch, vcl_backend_response, vcl_backend_error 两个特殊的引擎: vcl_init:在处理任何请求之前要执行的vcl代码:主要用于初始化VMODs; vcl_fini:所有的请求都已经结束,在vcl配置被丢弃时调用;主要用于清理VMODs; vcl的语法格式: (1) VCL files start with vcl 4.0; (2) //, # and /* foo */ for comments; (3) Subroutines are declared with the sub keyword; 例如sub vcl_recv { ...}; (4) No loops, state-limited variables(受限于引擎的内建变量); (5) Terminating statements with a keyword for next action as argument of the return() function, i.e.: return(action);用于实现状态引擎转换; (6) Domain-specific; The VCL Finite State Machine (1) Each request is processed separately; (2) Each request is independent from others at any given time; (3) States are related, but isolated; (4) return(action); exits one state and instructs Varnish to proceed to the next state; (5) Built-in VCL code is always present and appended below your own VCL; 三类主要语法: sub subroutine { ... } if CONDITION { ... } else { ... } return(), hash_data() VCL Built-in Functions and Keywords 函数: regsub(str, regex, sub) regsuball(str, regex, sub) ban(boolean expression) hash_data(input) synthetic(str) Keywords: call subroutine, return(action),new,set,unset 操作符: ==, !=, ~, >, >=, <, <= 逻辑操作符:&&, ||, ! 变量赋值:= 举例:obj.hits if (obj.hits>0) { set resp.http.X-Cache = "HIT via " + server.ip; } else { set resp.http.X-Cache = "MISS via " + server.ip; } 变量类型: 内建变量: req.*:request,表示由客户端发来的请求报文相关; req.http.* req.http.User-Agent, req.http.Referer, ... bereq.*:由varnish发往BE主机的httpd请求相关; bereq.http.* beresp.*:由BE主机响应给varnish的响应报文相关; beresp.http.* resp.*:由varnish响应给client相关; obj.*:存储在缓存空间中的缓存对象的属性;只读; 常用变量: bereq.*, req.*: bereq.http.HEADERS bereq.request:请求方法; bereq.url:请求的url; bereq.proto:请求的协议版本; bereq.backend:指明要调用的后端主机; req.http.Cookie:客户端的请求报文中Cookie首部的值; req.http.User-Agent ~ "chrome" beresp.*, resp.*: beresp.http.HEADERS beresp.status:响应的状态码; reresp.proto:协议版本; beresp.backend.name:BE主机的主机名; beresp.ttl:BE主机响应的内容的余下的可缓存时长; obj.* obj.hits:此对象从缓存中命中的次数; obj.ttl:对象的ttl值 server.* server.ip server.hostname client.* client.ip 用户自定义: set unset 示例1:强制对某类资源的请求不检查缓存: vcl_recv { if (req.url ~ "(?i)^/(login|admin)") { return(pass); } } 示例2:对于特定类型的资源,例如公开的图片等,取消其私有标识,并强行设定其可以由varnish缓存的时长; if (beresp.http.cache-control !~ "s-maxage") { if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") { unset beresp.http.Set-Cookie; set beresp.ttl = 3600s; } } 缓存对象的修剪:purge, ban (1) 能执行purge操作 sub vcl_purge { return (synth(200,"Purged")); } (2) 何时执行purge操作 sub vcl_recv { if (req.method == "PURGE") { return(purge); } ... } 添加此类请求的访问控制法则: acl purgers { "127.0.0.0"/8; "10.1.0.0"/16; } sub vcl_recv { if (req.method == "PURGE") { if (!client.ip ~ purgers) { return(synth(405,"Purging not allowed for " + client.ip)); } return(purge); } ... } 如何设定使用多个后端主机: backend default { .host = "172.16.100.6"; .port = "80"; } backend appsrv { .host = "172.16.100.7"; .port = "80"; } sub vcl_recv { if (req.url ~ "(?i)\.php$") { set req.backend_hint = appsrv; } else { set req.backend_hint = default; } ... } Director: varnish module; 使用前需要导入: import director; 示例: import directors; # load the directors backend server1 { .host = .port = } backend server2 { .host = .port = } sub vcl_init { new GROUP_NAME = directors.round_robin(); GROUP_NAME.add_backend(server1); GROUP_NAME.add_backend(server2); } sub vcl_recv { # send all traffic to the bar director: set req.backend_hint = GROUP_NAME.backend(); } BE Health Check: backend BE_NAME { .host = .port = .probe = { .url= .timeout= .interval= .window= .threshhold= } } .probe:定义健康状态检测方法; .url:检测时请求的URL,默认为”/"; .request:发出的具体请求; .request = "GET /.healthtest.html HTTP/1.1" "Host: www.magedu.com" "Connection: close" .window:基于最近的多少次检查来判断其健康状态; .threshhold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的; .interval:检测频度; .timeout:超时时长; .expected_response:期望的响应码,默认为200; 健康状态检测的配置方式: (1) probe PB_NAME = { } backend NAME = { .probe = PB_NAME; ... } (2) backend NAME { .probe = { ... } } 示例: probe check { .url = "/.healthcheck.html"; .window = 5; .threshold = 4; .interval = 2s; .timeout = 1s; } backend default { .host = "10.1.0.68"; .port = "80"; .probe = check; } backend appsrv { .host = "10.1.0.69"; .port = "80"; .probe = check; } varnish的运行时参数: 线程模型: cache-worker cache-main ban lurker acceptor: epoll/kqueue: ... 线程相关的参数: 在线程池内部,其每一个请求由一个线程来处理; 其worker线程的最大数决定了varnish的并发响应能力; thread_pools:Number of worker thread pools. 最好小于或等于CPU核心数量; thread_pool_max:The maximum number of worker threads in each pool. 每线程池的最大线程数; thread_pool_min:The minimum number of worker threads in each pool. 额外意义为“最大空闲线程数”; 最大并发连接数=thread_pools * thread_pool_max thread_pool_timeout:Thread idle threshold. Threads in excess of thread_pool_min, which have been idle for at least this long, will be destroyed. thread_pool_add_delay:Wait at least this long after creating a thread. thread_pool_destroy_delay:Wait this long after destroying a thread. 设置方式: vcl.param param.set 永久有效的方法: varnish.params DEAMON_OPTS="-p PARAM1=VALUE -p PARAM2=VALUE" varnish日志区域: shared memory log 计数器 日志信息 1、varnishstat - Varnish Cache statistics -1 -1 -f FILED_NAME -l:可用于-f选项指定的字段名称列表; MAIN.cache_hit MAIN.cache_miss # varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss 2、varnishtop - Varnish log entry ranking -1 Instead of a continously updated display, print the statistics once and exit. -i taglist,可以同时使用多个-i选项,也可以一个选项跟上多个标签; -I <[taglist:]regex> -x taglist:排除列表 -X <[taglist:]regex> 3、varnishlog - Display Varnish logs 4、 varnishncsa - Display Varnish logs in Apache / NCSA combined log format 内建函数: hash_data():指明哈希计算的数据;减少差异,以提升命中率; regsub(str,regex,sub):把str中被regex第一次匹配到字符串替换为sub;主要用于URL Rewrite regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替换为sub; return(): ban(expression) ban_url(regex):Bans所有的其URL可以被此处的regex匹配到的缓存对象; synth(status,"STRING"):purge操作; 总结: varnish: state engine, vcl varnish 4.0: vcl_init vcl_recv vcl_hash vcl_hit vcl_pass vcl_miss vcl_pipe vcl_waiting vcl_purge vcl_purge vcl_deliver vcl_synth vcl_fini vcl_backend_fetch vcl_backend_response vcl_backend_error sub VCL_STATE_ENGINE backend BE_NAME {} probe PB_NAME {} acl ACL_NAME {} 博客作业:以上所有内容; 课外实践:(1) zabbix监控varnish业务指标; (2) ansible实现varnish快速部署; (3) 两个lamp部署wordpress,用Nginx反代,做压测;nginx后部署varnish缓存,调整vcl,多次压测; ab, http_load, webbench, seige, jmeter, loadrunner,...

November 13, 2015

Linux系统高可用之HA-Cluster

[TOC] HA Cluster: 集群类型:LB(lvs/nginx(http/upstream, stream/upstream))、HA、HP SPoF: Single Point of Failure 系统可用性的公式:A=MTBF/(MTBF+MTTR) (0,1), 95% 几个9(指标): 99%, ..., 99.999%,99.9999%; 99%: %1, 99.9%, 0.1% 系统故障: 硬件故障:设计缺陷、wear out、自然灾害、…… 软件故障:设计缺陷、 提升系统高用性的解决方案之降低MTTR: 手段:冗余(redundant) active/passive(主备),active/active(双主) active --> HEARTBEAT --> passive active <--> HEARTBEAT <--> active 高可用的是“服务”: HA nginx service: vip/nginx process[/shared storage] 资源:组成一个高可用服务的“组件”; (1) passive node的数量? (2) 资源切换? shared storage: NAS:文件共享服务器; SAN:存储区域网络,块级别的共享; Network partition:网络分区 隔离设备: node:STONITH = Shooting The Other Node In The Head 资源:fence quorum: with quorum: > total/2 without quorum: <= total/2 TWO nodes Cluster? 辅助设备:ping node, quorum disk; Failover:故障切换,即某资源的主节点故障时,将资源转移至其它节点的操作; Failback:故障移回,即某资源的主节点故障后重新修改上线后,将转移至其它节点的资源重新切回的过程; HA Cluster实现方案: vrrp协议的实现 keepalived ais:完备HA集群 RHCS(cman) heartbeat corosync keepalived: vrrp协议:Virtual Redundant Routing Protocol 术语: 虚拟路由器:Virtual Router 虚拟路由器标识:VRID(0-255) 物理路由器: master:主设备 backup:备用设备 priority:优先级 VIP:Virtual IP VMAC:Virutal MAC (00-00-5e-00-01-VRID) 通告:心跳,优先级等;周期性; 抢占式,非抢占式; 安全工作: 认证: 无认证 简单字符认证 MD5 工作模式: 主/备:单虚拟路径器; 主/主:主/备(虚拟路径器1),备/主(虚拟路径器2) keepalived: vrrp协议的软件实现,原生设计的目的为了高可用ipvs服务: vrrp协议完成地址流动; 为vip地址所在的节点生成ipvs规则(在配置文件中预先定义); 为ipvs集群的各RS做健康状态检测; 基于脚本调用接口通过执行脚本完成脚本中定义的功能,进而影响集群事务; 组件: 核心组件: vrrp stack ipvs wrapper checkers 控制组件:配置文件分析器 IO复用器 内存管理组件 HA Cluster的配置前提: (1) 各节点时间必须同步; ntp, chrony (2) 确保iptables及selinux不会成为阻碍; (3) 各节点之间可通过主机名互相通信(对KA并非必须); 建议使用/etc/hosts文件实现; (4) 各节点之间的root用户可以基于密钥认证的ssh服务完成互相通信;(并非必须) keepalived安装配置: CentOS 6.4+ 程序环境: 主配置文件:/etc/keepalived/keepalived.conf 主程序文件:/usr/sbin/keepalived Unit File:keepalived.service Unit File的环境配置文件:/etc/sysconfig/keepalived 配置文件组件部分: TOP HIERACHY GLOBAL CONFIGURATION Global definitions Static routes/addresses VRRPD CONFIGURATION VRRP synchronization group(s):vrrp同步组; VRRP instance(s):每个vrrp instance即一个vrrp路由器; LVS CONFIGURATION Virtual server group(s) Virtual server(s):ipvs集群的vs和rs; 单主配置示例: ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state BACKUP interface eno16777736 virtual_router_id 14 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } 配置语法: 配置虚拟路由器: vrrp_instance <STRING> { .... } 专用参数: state MASTER|BACKUP:当前节点在此虚拟路由器上的初始状态;只能有一个是MASTER,余下的都应该为BACKUP; interface IFACE_NAME:绑定为当前虚拟路由器使用的物理接口; virtual_router_id VRID:当前虚拟路由器的惟一标识,范围是0-255; priority 100:当前主机在此虚拟路径器中的优先级;范围1-254; advert_int 1:vrrp通告的时间间隔; authentication { auth_type AH|PASS auth_pass <PASSWORD> } virtual_ipaddress { <IPADDR>/<MASK> brd <IPADDR> dev <STRING> scope <SCOPE> label <LABEL> 192.168.200.17/24 dev eth1 192.168.200.18/24 dev eth2 label eth2:1 } track_interface { eth0 eth1 ... } 配置要监控的网络接口,一旦接口出现故障,则转为FAULT状态; nopreempt:定义工作模式为非抢占模式; preempt_delay 300:抢占式模式下,节点上线后触发新选举操作的延迟时长; 定义通知脚本: notify_master <STRING>|<QUOTED-STRING>:当前节点成为主节点时触发的脚本; notify_backup <STRING>|<QUOTED-STRING>:当前节点转为备节点时触发的脚本; notify_fault <STRING>|<QUOTED-STRING>:当前节点转为“失败”状态时触发的脚本; notify <STRING>|<QUOTED-STRING>:通用格式的通知触发机制,一个脚本可完成以上三种状态的转换时的通知; 双主模型示例: ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.91/16 dev eno16777736 } } vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 15 priority 98 advert_int 1 authentication { auth_type PASS auth_pass 578f07b2 } virtual_ipaddress { 10.1.0.92/16 dev eno16777736 } } 示例通知脚本: #!/bin/bash # contact='root@localhost' notify() { mailsubject="$(hostname) to be $1, vip floating" mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1" echo "$mailbody" | mail -s "$mailsubject" $contact } case $1 in master) notify master ;; backup) notify backup ;; fault) notify fault ;; *) echo "Usage: $(basename $0) {master|backup|fault}" exit 1 ;; esac 脚本的调用方法: notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" 虚拟服务器: 配置参数: virtual_server IP port | virtual_server fwmark int { ... real_server { ... } ... } 常用参数: delay_loop <INT>:服务轮询的时间间隔; lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定义调度方法; lb_kind NAT|DR|TUN:集群的类型; persistence_timeout <INT>:持久连接时长; protocol TCP:服务协议,仅支持TCP; sorry_server <IPADDR> <PORT>:备用服务器地址; real_server <IPADDR> <PORT> { weight <INT> notify_up <STRING>|<QUOTED-STRING> notify_down <STRING>|<QUOTED-STRING> HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK { ... }:定义当前主机的健康状态检测方法; } HTTP_GET|SSL_GET:应用层检测 HTTP_GET|SSL_GET { url { path <URL_PATH>:定义要监控的URL; status_code <INT>:判断上述检测机制为健康状态的响应码; digest <STRING>:判断上述检测机制为健康状态的响应的内容的校验码; } nb_get_retry <INT>:重试次数; delay_before_retry <INT>:重试之前的延迟时长; connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求 connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址; bind_port <PORT>:发出健康状态检测请求时使用的源端口; connect_timeout <INTEGER>:连接请求的超时时长; } TCP_CHECK { connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求 connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求 bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址; bind_port <PORT>:发出健康状态检测请求时使用的源端口; connect_timeout <INTEGER>:连接请求的超时时长; } 高可用的ipvs集群示例: ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.93/16 dev eno16777736 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } virtual_server 10.1.0.93 80 { delay_loop 3 lb_algo rr lb_kind DR protocol TCP sorry_server 127.0.0.1 80 real_server 10.1.0.69 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 1 nb_get_retry 3 delay_before_retry 1 } } real_server 10.1.0.71 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 1 nb_get_retry 3 delay_before_retry 1 } } } 博客作业:第一部分 双主模式的lvs集群,拓扑、实现过程; 配置示例(一个节点): ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from kaadmin@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.67 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 44 priority 100 advert_int 1 authentication { auth_type PASS auth_pass f1bf7fde } virtual_ipaddress { 172.16.0.80/16 dev eno16777736 label eno16777736:0 } track_interface { eno16777736 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } vrrp_instance VI_2 { state BACKUP interface eno16777736 virtual_router_id 45 priority 98 advert_int 1 authentication { auth_type PASS auth_pass f2bf7ade } virtual_ipaddress { 172.16.0.90/16 dev eno16777736 label eno16777736:1 } track_interface { eno16777736 } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } virtual_server fwmark 3 { delay_loop 2 lb_algo rr lb_kind DR nat_mask 255.255.0.0 protocol TCP sorry_server 127.0.0.1 80 real_server 172.16.0.69 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.0.6 80 { weight 1 HTTP_GET { url { path / status_code 200 } connect_timeout 2 nb_get_retry 3 delay_before_retry 3 } } } keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整; 分两步:(1) 先定义一个脚本;(2) 调用此脚本; vrrp_script <SCRIPT_NAME> { script "" interval INT weight -INT } track_script { SCRIPT_NAME_1 SCRIPT_NAME_2 ... } 示例:高可用nginx服务 ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id node1 vrrp_mcast_group4 224.0.100.19 } vrrp_script chk_down { script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0" interval 1 weight -5 } vrrp_script chk_nginx { script "killall -0 nginx && exit 0 || exit 1" interval 1 weight -5 } vrrp_instance VI_1 { state MASTER interface eno16777736 virtual_router_id 14 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 571f97b2 } virtual_ipaddress { 10.1.0.93/16 dev eno16777736 } track_script { chk_down chk_nginx } notify_master "/etc/keepalived/notify.sh master" notify_backup "/etc/keepalived/notify.sh backup" notify_fault "/etc/keepalived/notify.sh fault" } 博客作业:以上所有内容;

November 3, 2015

Linux安全策略之tcp_wrapper

[TOC] tcp_wrapper: 库文件:libwrap.so,tcp包装器; 判断一个服务程序是否能够由tcp_wrapper进行访问控制的方法: (1) 动态链接至libwrap.so库; ldd /PATH/TO/PROGRAM libwrap.so (2) 静态编译libwrap.so库文件至程序中: strings /PATH/TO/PGRGRAM hosts_access 配置文件:/etc/hosts.allow, /etc/hosts.deny See 'man 5 hosts_options' and 'man 5 hosts_access' for information on rule syntax. 配置文件语法: daemon_list : client_list[ : option : option ...] daemon_list:程序文件名称列表 (1) 单个应用程序文件名; (2) 程序文件名列表,以逗号分隔; (3) ALL:所有受tcp_wrapper控制的应用程序文件; client_list: (1) 单个IP地址或主机名; (2) 网络地址:n.n.n.n/m.m.m.m,n.n.n.; (3) 内建的ACL: ALL:所有客户端主机; LOCAL:Matches any host whose name does not contain a dot character. UNKNOWN KNOWN PARANOID OPERATORS: EXCEPT list1 EXCEPT list2 EXCEPT list3 sshd: 172.16. EXCEPT 172.16.100. EXCEPT 172.16.100.68 [ : option : option ...] deny:拒绝,主要用于hosts.allow文件中定义“拒绝”规则; allow:允许,主要用于hosts.deny文件中定义”允许“规则; spawn:生成,发起,触发执行用户指定的任意命令,此处通常用于记录日志; vsftpd: 172.16. : spawn /bin/echo $(date) login attempt from %c to %s >> /var/log/tcp_wrapper.log 练习:仅开放本机的sshd服务给172.16.0.0/16网络中除了172.16.0.0/24网络中的主机之外的所有主机,但允许172.16.0.200访问; 每次的用户访问都要记录于日志文件中;

November 1, 2015

CentOS 7 PXE 无盘系统配置说明

PXE无盘工作站系统是指由一台或多台“系统服务器”和多台“PXE客户端(无盘工作站)”通过 交换机 相连组成的局域网系统。 系统服务器:通过DHCP+TFTP+NFS服务向无盘工作站提供系统支持 · DHCP服务:向PXE客户端分发IP地址、子网掩码、网关等,并指定启动引导文件所在服务器(TFTP服务器)的地址和PXE启动文件(pxelinux.0) · TFTP服务:向PXE客户端传输PXE启动文件、PXE引导配置文件、linux内核vmlinuz,以及系统启动文件initrd.img · NFS服务:向PXE客户端发布工作站的系统(整个根目录“/”的克隆);为了避免磁盘IO资源的冲突,建议将克隆的系统部署在存储服务器上 PXE客户端:PXE客户端无需硬盘,只需要一块支持PXE启动的网卡,将“网卡启动”设置为首选 操作系统 CentOS 7.2 软件环境 tftp-server-5.2-12.el7.x86_64 向无盘工作站传输系统启动文件等 nfs-utils-1.3.0-0.21.el7.x86_64 共享发布工作站系统 syslinux-4.05-12.el7.x86_64 提供引导程序"pxelinux.0" dhcp-4.2.5-42.el7.centos.x86_64 提供DHCP 服务;指定TFTP 地址及PXE 启动文件 dracut-033-359.el7.x86_64 用来制作启动initrd 镜像 dracut-network-033-359.el7.x86_64 依赖包,否则将导致PXE无法启动 首先,克隆好工作站的系统模板 配置之前关掉防火墙和selinux systemctl stop firewalld #我还是比较习惯用iptables 所以关掉了 firewalld systemctl disable firewalld iptables -F #清空防火墙策略,如果之前有布置防火墙策略的需要查看下是否真要清空 iptables -vnL #查看filter防火墙策略 setenforce 0 #临时关闭selinux,重启后失效 vim /etc/sysconfig/selinux SELINUX=disabled #关闭selinux,重启后生效 \1. 创建工作站系统模板的存放目录(/nodiskos/workstation)和启动引导文件存放目录(/nodiskos/tftpboot) mkdir /nodiskos # 系统模板+启动文件存放目录 mkdir /nodiskos/tftpboot # 工作站系统启动文件存放目录 mkdir /nodiskos/workstation # 工作站系统模板存放目录 \2. 使用rsync 工具将整个"/“目录拷贝到/nodiskos/workstation 目录下,去除不需要的文件目录 ...

October 13, 2015

Linux负载均衡之lvs

[TOC] 单台主机的处理能力是有限的,一台主机同时处理500个动态网页请求已经是极限了。这里有两种方法提升处理性能,一,定制高性能的计算机(Scale UP),众所周知计算机硬件设计成本极其高,性能每提高10%成本就要增加一倍,这也是intel被称为挤牙膏公司的原因,不是其研发能力不行而是计算机硬件性能提升的难度太大,这个方法貌似不可行。二,使用两台主机处理业务,这就会引来一个问题怎么把请求分发到多个主机(Scale Out),这里我们引入了负载均衡器。 使用负载均衡有两个方法,一是采用商用负载均衡硬件的,这个方法是最好的方法,能上硬件一定不要使用软件,又是硬件同样的问题也是价格,只要是涉及到基础设施的服务一定要使用。一方面是硬件的稳定性,比软件好很多,虽然软件可维护性和拓展性比较好,但是对于一些金融公司,他们玩的就是公信力和大众信心,每个故障都是竞争对手拆台的理由,一旦故障硬件背锅,理赔。常用的硬件F5的Big-IP,Citrix的Netscaler,A10的A10 另一种是采用软件负载均衡,只要考虑成本使用负载均衡软件就对了,它的性能比硬件也不会差别太大,并且灵活。 在做负载均衡的时候,我们在7层模型的哪一层做负载均衡,ip层基于主机做负载均衡粒度太大可用性太差基本不使用,更低的层基本上没有价值了,tcp层的话我们就可以把不同服务的请求采取不同的方式负载均衡,应用层的话我们可以根据具体协议拆包分析后负载均衡,既然涉及到拆开数据包,那处理的数据量就会大大增加,那么对计算机性能要求也越高,性能就越差,并且负载均衡器的通用性也越差。 传输层:lvs,nginx:(stream),haproxy:(mode tcp) 应用层: http:nginx, httpd, haproxy(mode http) fastcgi:nginx, httpd mysql:mysql-proxy Linux Cluster: Cluster:计算机集合,为解决某个特定问题组合起来形成的单个系统; Linux Cluster类型: LB:Load Balancing,负载均衡; HA:High Availiablity,高可用; A=MTBF/(MTBF+MTTR),MTBF:mean time bettween failure,平均工作时长或者平均故障间隔时间。MTTR:mean time to restoration/repair,平局修复时长 (0,1):90%, 95%, 99%, 99.5%, 99.9%, 99.99%, 99.999%, 99.9999% HP:High Performance,高性能; 分布式系统: 分布式存储 分布式计算 系统扩展方式: Scale UP:向上扩展 Scale Out:向外扩展,增加计算机数量,也就形成了集群 LB Cluster: LB Cluster的实现: 硬件: F5 Big-IP Citrix Netscaler A10 A10 软件: lvs:Linux Virtual Server nginx haproxy ats:apache traffic server perlbal pound 基于工作的协议层次划分: 传输层(通用):(DPORT) lvs: nginx:(stream) haproxy:(mode tcp) 应用层(专用):(自定义的请求模型分类) proxy sferver: http:nginx, httpd, haproxy(mode http), ... fastcgi:nginx, httpd, ... mysql:mysql-proxy, ... ... 站点指标: PV:Page View UV:Unique Vistor IP: 会话保持: (1) session sticky Source IP Cookie (2) session replication; session cluster (3) session server lvs:Linux Virtual Server 作者:章文嵩;alibaba --> didi VS: Virtual Server RS: Real Server lvs: ipvsadm/ipvs 类似于 iptables/netfilter ipvsadm:用户空间的命令行工具,规则管理器,用于管理集群服务及RealServer; ipvs:工作于内核空间的netfilter的INPUT钩子之上的框架; lvs集群类型中的术语: vs:Virtual Server, Director, Dispatcher, Balancer rs:Real Server, upstream server, backend server CIP:Client IP, VIP: Virtual serve IP, RIP: Real server IP, DIP: Director IP CIP <--> VIP == DIP <--> RIP lvs集群的类型: lvs-nat:修改请求报文的目标IP;多目标IP的DNAT; lvs-dr:操纵封装新的MAC地址; lvs-tun:在原请求IP报文之外新加一个IP首部; lvs-fullnat:修改请求报文的源和目标IP; lvs-nat: 多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发; (1)RIP和DIP必须在同一个IP网络,且应该使用私网地址;RS的网关要指向DIP; (2)请求报文和响应报文都必须经由Director转发;Director易于成为系统瓶颈; (3)支持端口映射,可修改请求报文的目标PORT; (4)vs必须是Linux系统,rs可以是任意系统; lvs-dr: Direct Routing,直接路由; 通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变; Director和各RS都得配置使用VIP; (1) 确保前端路由器将目标IP为VIP的请求报文发往Director: (a) 在前端网关做静态绑定; (b) 在RS上使用arptables; (c) 在RS上修改内核参数以限制arp通告及应答级别; arp_announce arp_ignore (2) RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director; (3) RS跟Director要在同一个物理网络; (4) 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client; (5) 不支持端口映射; lvs-tun: 转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP); (1) DIP, VIP, RIP都应该是公网地址; (2) RS的网关不能,也不可能指向DIP; (3) 请求报文要经由Director,但响应不能经由Director; (4) 不支持端口映射; (5) RS的OS得支持隧道功能; lvs-fullnat: 通过同时修改请求报文的源IP地址和目标IP地址进行转发; CIP --> DIP VIP --> RIP (1) VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP; (2) RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client; (3) 请求和响应报文都经由Director; (4) 支持端口映射; 注意:此类型默认不支持; 总结: lvs-nat, lvs-fullnat:请求和响应报文都经由Director; lvs-nat:RIP的网关要指向DIP; lvs-fullnat:RIP和DIP未必在同一IP网络,但要能通信; lvs-dr, lvs-tun:请求报文要经由Director,但响应报文由RS直接发往Client; lvs-dr:通过封装新的MAC首部实现,通过MAC网络转发; lvs-tun:通过在原IP报文之外封装新的IP报文实现转发,支持远距离通信; ipvs scheduler: 根据其调度时是否考虑各RS当前的负载状态,可分为静态方法和动态方法两种: 静态方法:仅根据算法本身进行调度; RR:roundrobin,轮询; WRR:Weighted RR,加权轮询; SH:Source Hashing,实现session sticy,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定; DH:Destination Hashing;目标地址哈希,将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡; 动态方法:主要根据每RS当前的负载状态及调度算法进行调度; Overhead= LC:least connections 选中最少连接数的RS服务器 Overhead=activeconns*256+inactiveconns WLC:Weighted LC 默认调度方法 Overhead=(activeconns*256+inactiveconns)/weight SED:Shortest Expection Delay 最短期望延迟, Overhead=(activeconns+1)*256/weight NQ:Never Queue 永不排队,权重小的不会空闲 LBLC:Locality-Based LC,动态的DH算法; LBLCR:LBLC with Replication,带复制功能的LBLC; ipvsadm/ipvs: ipvs: ~]# grep -i -C 10 "ipvs" /boot/config-VERSION-RELEASE.x86_64 支持的协议:TCP, UDP, AH, ESP, AH_ESP, SCTP; ipvs集群: 集群服务 服务上的RS ipvsadm: 程序包:ipvsadm Unit File: ipvsadm.service 主程序:/usr/sbin/ipvsadm 规则保存工具:/usr/sbin/ipvsadm-save 规则重载工具:/usr/sbin/ipvsadm-restore 配置文件:/etc/sysconfig/ipvsadm-config ipvsadm命令: 核心功能: 集群服务管理:增、删、改; 集群服务的RS管理:增、删、改; 查看: ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--pe persistence_engine] [-b sched-flags] ipvsadm -D -t|u|f service-address ipvsadm -C ipvsadm -R ipvsadm -S [-n] ipvsadm -a|e -t|u|f service-address -r server-address [options] ipvsadm -d -t|u|f service-address -r server-address ipvsadm -L|l [options] ipvsadm -Z [-t|u|f service-address] 管理集群服务:增、改、删; 增、改: ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] 删: ipvsadm -D -t|u|f service-address service-address: -t|u|f: -t: TCP协议的端口,VIP:TCP_PORT -u: TCP协议的端口,VIP:UDP_PORT -f:firewall MARK,是一个数字; [-s scheduler]:指定集群的调度算法,默认为wlc; 管理集群上的RS:增、改、删; 增、改: ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] 删: ipvsadm -d -t|u|f service-address -r server-address server-address: rip[:port] 选项: lvs类型: -g: gateway, dr类型 -i: ipip, tun类型 -m: masquerade, nat类型 -w weight:权重; 清空定义的所有内容: ipvsadm -C 查看: ipvsadm -L|l [options] --numeric, -n:numeric output of addresses and ports --exact:expand numbers (display exact values) --connection, -c:output of current IPVS connections --stats:output of statistics information --rate :output of rate information 保存和重载: ipvsadm -S = ipvsadm-save ipvsadm -R = ipvsadm-restore 负载均衡集群设计时要注意的问题: (1) 是否需要会话保持; (2) 是否需要共享存储; 共享存储:NAS, SAN, DS(分布式存储) 数据同步: 课外作业:rsync+inotify实现数据同步 lvs-nat: 设计要点: (1) RIP与DIP在同一IP网络, RIP的网关要指向DIP; (2) 支持端口映射; (3) Director要打开核心转发功能; ipvsadm -A -t 172.16.252.127:80 -s rr // -s rr 课不写 默认为wlc ipvsadm -a -t 172.16.252.127:80 -r 192.168.0.5:80 -m //[-w weight_num] ipvsadm -a -t 172.16.252.127:80 -r 192.168.0.6:80 -m //[-w weight_num] ipvsadm -L echo 1 > /proc/sys/net/ipv4/ip_forward 转发功能打开 ifconfig eth0 192.168.191.131/24 route add default gw 192.168.191.1 测试: for i in {1..10} ; do curl 172.16.252.127 ; done 实践作业(博客):负载均衡一个php应用(wordpress); 测试:(1) 是否需要会话保持;(2) 是否需要共享存储; Demo: lvs-dr: dr模型中,各主机上均需要配置VIP,解决地址冲突的方式有三种: (1) 在前端网关做静态绑定; (2) 在各RS使用arptables; (3) 在各RS修改内核参数,来限制arp响应和通告的级别; 限制响应级别:arp_ignore 0:默认值,表示可使用本地任意接口上配置的任意地址进行响应; 1: 仅在请求的目标IP配置在本地主机的接收到请求报文接口上时,才给予响应; 限制通告级别:arp_announce 0:默认值,把本机上的所有接口的所有信息向每个接口上的网络进行通告; 1:尽量避免向非直接连接网络进行通告; 2:必须避免向非本网络通告; RS的预配置脚本: #!/bin/bash # vip=10.1.0.5 mask='255.255.255.255' case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig lo:0 $vip netmask $mask broadcast $vip up route add -host $vip dev lo:0 ;; stop) ifconfig lo:0 down echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac VS的配置脚本: #!/bin/bash # vip='10.1.0.5' iface='eno16777736:0' mask='255.255.255.255' port='80' rs1='10.1.0.7' rs2='10.1.0.8' scheduler='wrr' type='-g' case $1 in start) ifconfig $iface $vip netmask $mask broadcast $vip up iptables -F ipvsadm -A -t ${vip}:${port} -s $scheduler ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1 ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1 ;; stop) ipvsadm -C ifconfig $iface down ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac 课外扩展作业:vip与dip/rip不在同一网段的实验环境设计及配置实现; 博客作业:lvs的详细应用 讲清楚类型、调度方法;并且给出nat和dr类型的设计拓扑及具体实现; FWM:FireWall Mark netfilter: target: MARK, This target is used to set the Netfilter mark value associated with the packet. --set-mark value 借助于防火墙标记来分类报文,而后基于标记定义集群服务;可将多个不同的应用使用同一个集群服务进行调度; 打标记方法(在Director主机): # iptables -t mangle -A PREROUTING -d $vip -p $proto --dport $port -j MARK --set-mark NUMBER 基于标记定义集群服务: # ipvsadm -A -f NUMBER [options] lvs persistence:持久连接 持久连接模板:实现无论使用任何调度算法,在一段时间内,能够实现将来自同一个地址的请求始终发往同一个RS; ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] port Affinity: 每端口持久:每个端口对应定义为一个集群服务,每集群服务单独调度; 每防火墙标记持久:基于防火墙标记定义集群服务;可实现将多个端口上的应用统一调度,即所谓的port Affinity; 每客户端持久:基于0端口定义集群服务,即将客户端对所有应用的请求统统调度至后端主机,必须定义为持久模式; 保存及重载规则: 保存:建议保存至/etc/sysconfig/ipvsadm ipvsadm-save > /PATH/TO/IPVSADM_FILE ipvsadm -S > /PATH/TO/IPVSADM_FILE systemctl stop ipvsadm.service 重载: ipvsadm-restore < /PATH/FROM/IPVSADM_FILE ipvsadm -R < /PATH/FROM/IPVSADM_FILE systemctl restart ipvsadm.service 考虑: (1) Director不可用,整个系统将不可用;SPoF 解决方案:高可用 keepalived heartbeat/corosync (2) 某RS不可用时,Director依然会调度请求至此RS; 解决方案:对各RS的健康状态做检查,失败时禁用,成功时启用; keepalived heartbeat/corosync, ldirectord 检测方式: (a) 网络层检测; (b) 传输层检测,端口探测; (c) 应用层检测,请求某关键资源; ok --> failure failure --> ok ldirectord: Daemon to monitor remote services and control Linux Virtual Server. ldirectord is a daemon to monitor and administer real servers in a cluster of load balanced virtual servers. ldirectord typically is started from heartbeat but can also be run from the command line. 配置示例: checktimeout=3 checkinterval=1 fallback=127.0.0.1:80 autoreload=yes logfile="/var/log/ldirectord.log" quiescent=no virtual=5 real=172.16.0.7:80 gate 2 real=172.16.0.8:80 gate 1 fallback=127.0.0.1:80 gate service=http scheduler=wrr checktype=negotiate checkport=80 request="index.html" receive="CentOS" 补充:共享存储 NAS:Network Attached Storage nfs/cifs 文件系统接口 SAN:Storage Area Network “块”接口

October 13, 2015

Linux负载均衡之lvs-dr模式

[TOC] lvs-dr: dr模型中,各主机上均需要配置VIP,解决地址冲突的方式有三种: (1) 在前端网关做静态绑定; (2) 在各RS使用arptables; (3) 在各RS修改内核参数,来限制arp响应和通告的级别; 限制响应级别:arp_ignore 0:默认值,表示可使用本地任意接口上配置的任意地址进行响应; 1: 仅在请求的目标IP配置在本地主机的接收到请求报文接口上时,才给予响应; 限制通告级别:arp_announce 0:默认值,把本机上的所有接口的所有信息向每个接口上的网络进行通告; 1:尽量避免向非直接连接网络进行通告; 2:必须避免向非本网络通告; RS的预配置脚本: #!/bin/bash # vip=10.1.0.5 mask='255.255.255.255' case $1 in start) echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig lo:0 $vip netmask $mask broadcast $vip up route add -host $vip dev lo:0//当发往本机的请求报文目标地址为 vip 的时候,本机的响应报文从lo:o应答 ;; stop) ifconfig lo:0 down echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac VS ifconfig eno16777736:0 172.16.0.50 netmask 255.255.255.255 broadcast 172.16.0.50 up vip=172.16.0.50 VS的配置脚本: #!/bin/bash # vip='10.1.0.5' iface='eno16777736:0' mask='255.255.255.255' port='80' rs1='10.1.0.7' rs2='10.1.0.8' scheduler='wrr' type='-g' case $1 in start) ifconfig $iface $vip netmask $mask broadcast $vip up iptables -F ipvsadm -A -t ${vip}:${port} -s $scheduler ipvsadm -a -t ${vip}:${port} -r ${rs1} $type -w 1 ipvsadm -a -t ${vip}:${port} -r ${rs2} $type -w 1 ;; stop) ipvsadm -C ifconfig $iface down ;; *) echo "Usage $(basename $0) start|stop" exit 1 ;; esac 课外扩展作业:vip与dip/rip不在同一网段的实验环境设计及配置实现; 博客作业:lvs的详细应用 讲清楚类型、调度方法;并且给出nat和dr类型的设计拓扑及具体实现;

October 13, 2015

PXE配置文档

[TOC] 目前所做为测试,即在虚拟机上的测试。先简单介绍一下整体环境,两台centos7.2系统,7-2-a(安装vsftp tftp)和7-2-b(安装dhcp服务) 在7-2-a ip:192.168.199.149 的操作: systemctl stop firewalld setenforce 0 yum install -y vsftpd tftp-server syslinux cp -a /misc/cd/* /var/ftp cp /root/anaconda-ks.cfg /var/ftp/ks.cfg //这里ks.cfg需要根据自己需求简单修改配置,后面会说明用system-config-kickstart 如何配置ks.cfg 内容修改如下 #platform=x86, AMD64, or Intel EM64T #version=DEVEL # Install OS instead of upgrade install # Keyboard layouts keyboard 'us' # Root password rootpw --iscrypted $1$gfl.Vz5t$mqzEhPMYDiANGwDB8gj/E/ # System timezone timezone Asia/Shanghai user --name=superman --password=$6$cq8y5jAZQCGd4muD$8G7zz.fpZFK3rI0AA7dyAxeD2B3mIjgu1HY/yeOm.PdsYHAYsD77K8uXTjbEPvJs9z7M6s0TECr6FtL2Bc5to/ --iscrypted --gecos="superman" #为服务器添加一个用户 # Use network installation url --url="ftp://192.168.199.149" # System language lang en_US # Firewall configuration firewall --disabled # System authorization information auth --useshadow --passalgo=sha512 # Use text mode install text firstboot --enable # SELinux configuration selinux --disabled # Network information network --bootproto=dhcp --device=eno16777736 --ipv6=auto --activate network --hostname=7-2-test # Reboot after installation reboot # System bootloader configuration bootloader --location=mbr --boot-drive=sda # Partition clearing information clearpart --all --initlabel # Disk partitioning information part / --fstype="xfs" --size=12040 part /boot --fstype="xfs" --size=10240 part /home --fstype="xfs" --size=10240 part /var --fstype="xfs" --size=20480 part /usr --fstype="xfs" --size=10240 part /tmp --fstype="xfs" --size=10240 %packages @^minimal @core @ftp-server %end 配置tftp-server ...

October 13, 2015

Linux程序包的编译安装

[TOC] 在有些源代码程序没有被编译成rpm的时候,或者其他人写了一个源代码程序,要把它安装在服务器上要怎么做呢? 那就需要对源代码进行编译安装了。 C代码编译安装三步骤: 1、./configure: (1)通过选项传递参数,指定启用特性、安装路径等;执行时会参考用户的指定以及makefile.in文件生成makefile (2) 检查依赖到的外部环境,如依赖的软件包 2、make:根据makefile文件,构建应用程序 3、make install:复制文件到相应路径 开发工具: autoconf: 生成configure脚本 automake:生成Makefile.in 注意:安装前查看INSTALL,README 例子: 下面就以编译安装HTTP服务为例进行说明: 首先要 获取到HTTP源代码,此处通过FTP获取 yum install lftp 安装FTP--源代码获取工具 ftp://172.16.0.1/pub/Sources/sources/httpd/httpd-2.2.29.tar.bz2 --下载源代码 tar xvf httpd-2.2.29.tar.bz2 --解压源代码--> 得到http-2.2.29 目录 由于要用到autoconf和automake工具 因此可以安装 工具包 yum groupinstall "Development Tools" 安装工具安装好了之后进入http目录执行 ./configure命令,注意这个命令要指定该软件安装的程序所在目录,以及配置文件所在目录。所以执行./configure命令之前要先看一下目录下的INSTALL、README两个文件 http服务中--prefix=程序安装目录 --sysconfdir=配置文件目录 如果不加这两个选项,是有默认安装路径的。在man帮助中有,接下来执行: ./configure --prefix=/usr/local/huyuhttp --sysconfdir=/etc/huyuhttp/ make 和 make install 这样呢其实已经安装完了http服务,但是此时http还没有启动,帮助文档还不能方便查看,调用的库也不行,共享库有哪些也不知道,所以要进行接下来的配置。 1、在/etc/profile.d/目录下创建一个以.sh结尾的文件,修改path变量,加入http二进制程序路径,这样就可以不用加路径直接执行http程序了。 vim /etc/profile.d/huyuhttp.sh PATH=$PATH:/usr/local/huyuhttp/bin . /etc/profile.d/huyuhttp.sh 刷新path变量值 2、添加man手册,可以方便查看帮助 vim /etc/man_db.conf /usr/local/huyuhttp/man 3、添加lib图文件目录 vim /etc/ld.so.conf.d/huyuhttp.conf /usr/local/huyuhttp/lib ldconfig 刷新库文件缓存 4、添加头文件,这里只需要在include的目录中加入http的include目录链接即可 ln -s /usr/local/huyuhttp/include/ /usr/include/huyuhttp 5、关闭防火墙 iptables -F 6、开启http apachectl start 7、查看端口是否打开 netstat -ant 查看80 8、测试查看网页 links ip curl ip

September 20, 2015

dd命令制作U盘启动

[TOC] 1、插入U盘,df -h查看U盘文件系统挂载情况,然后使用umount /dev/sdb*卸载U盘文件系统; 2、执行命令:sudo mkfs.vfat -I /dev/sdb格式化U盘为FAT格式; 3、dd if=*/*.iso of=/dev/sdb bs=4M (数据块大小,每个数据块只能存一个文件的数据) 4、执行sync,同步缓存中的数据至U盘;

September 19, 2015