nginx

[TOC] Nginx:engine X NGINX is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. NGINX is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.(nginx是一个自由的,开源的,高性能的http服务和反向代理。同时也可以是IMAP/POP3反向代理。以他的高性能,高稳定性,丰富的特性设置,简单的配置以及很低的资源消耗而闻名)。 功能特点如下: http协议:web服务器(类似于httpd)、http reverse proxy(类似于httpd)、imap/pop3 reverse proxy C10K(10K Connections)超10k的并发连接数。 nginx的衍生版本:Tengine, OpenResty. Nginx的程序架构: master/worker:一个master进程,多个worker进程 master:负载加载和分析配置文件、管理worker进程、平滑升级 worker:处理并响应用户请求 缓存相关的进程: cache loader:载入缓存对象 cache manager:管理缓存对象 特性:异步、事件驱动和非阻塞 并发请求处理:通过kevent/epoll/select,/dev/poll 文件IO:高级IO sendfile,异步,mmap nginx高度模块:高度模块化,但其模块早期不支持DSO机制;近期版本支持动态装载和卸载; 模块分类: 核心模块:core module 标准模块: HTTP modules: Standard HTTP modules Optional HTTP modules Mail modules Stream modules 3rd party modules nginx的功用: 静态的web资源服务器;(图片服务器,或js/css/html/txt等静态资源服务器) 结合FastCGI/uwSGI/SCGI等协议反代动态资源请求; http/https协议的反向代理; imap4/pop3协议的反向代理; tcp/udp协议的请求转发; nginx的安装配置: 官方的预制包: http://nginx.org/packages/centos/7/x86_64/RPMS/ Fedora-EPEL: 编译安装: # yum install pcre-devel openssl-devel zlib-devel(依赖工具包) # useradd -r nginx # ./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio # make && make install 配置: 配置文件的组成部分: 主配置文件:/etc/nginx/nginx.conf include /etc/nginx/conf.d/*.conf fastcgi, uwsgi,scgi等协议相关的配置文件 mime.types:支持的mime类型 主配置文件的配置指令: directive value [value2 ...]; 注意: (1) 指令必须以分号结尾; (2) 支持使用配置变量; 内建变量:由Nginx模块引入,可直接引用;所有的内建变量可在ngx_http_core_module 模块说明文档的 Embedded Variables 部分找到 自定义变量:由用户使用set命令定义; set variable_name value; 引用变量:$variable_name 主配置文件结构: main block:主配置段,也即全局配置段; event { ... }:事件驱动相关的配置; http { ... }:http/https 协议相关的配置段; mail { ... }:邮件工具的配置段; stream { ... }:TCP udp 相关 http协议相关的配置结构 http { ... ...:各server的公共配置 server { ... }:每个server用于定义一个虚拟主机; server { ... server_name root alias location [OPERATOR] URL { ... if CONDITION { ... } } } } main配置段常见的配置指令: 分类: 正常运行必备的配置 优化性能相关的配置 用于调试及定位问题相关的配置 事件驱动相关的配置 正常 运行必备的配置: 1、user Syntax: user user [group]; Default: user nobody nobody; Context: main Defines user and group credentials used by worker processes. If group is omitted, a group whose name equals that of user is used. 2、pid /PATH/TO/PID_FILE; 指定存储nginx主进程进程号码的文件路径; 3、include file | mask; 指明包含进来的其它配置文件片断; 4、load_module file; 指明要装载的动态模块; 性能优化相关的配置: 1、worker_processes number | auto; worker进程的数量;通常应该为当前主机的cpu的物理核心数; 2、worker_cpu_affinity cpumask ...; worker_cpu_affinity auto [cpumask]; CPU MASK: 00000001:0号CPU 00000010:1号CPU ... ... 3、worker_priority number; 指定worker进程的nice值,设定worker进程优先级;[-20,20] 4、worker_rlimit_nofile number; worker进程所能够打开的文件数量上限; 调试、定位问题: 1、daemon on|off; 是否以守护进程方式运行Nignx; 2、master_process on|off; 是否以master/worker模型运行nginx;默认为on; 3、error_log file [level]; 事件驱动相关的配置: events { ... } 1、worker_connections number; 每个worker进程所能够打开的最大并发连接数数量; worker_processes * worker_connections 2、use method; 指明并发连接请求的处理方法; use epoll; 3、accept_mutex on | off; 处理新的连接请求的方法;on意味着由各worker轮流处理新请求,Off意味着每个新请求的到达都会通知所有的worker进程; Nginx配置: http协议的相关配置: http { ... ... server { ... server_name root location [OPERATOR] /uri/ { ... } } server { ... } } 与套接字相关的配置: 1、server { ... } 配置一个虚拟主机; server { listen address[:PORT]|PORT; server_name SERVER_NAME; root /PATH/TO/DOCUMENT_ROOT; } 2、listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size] default_server:设定为默认虚拟主机; ssl:限制仅能够通过ssl连接提供服务; backlog=number:后援队列长度; rcvbuf=size:接收缓冲区大小; sndbuf=size:发送缓冲区大小; 3、server_name name ...; 指明虚拟主机的主机名称;后可跟多个由空白字符分隔的字符串; 支持*通配任意长度的任意字符;server_name *.magedu.com www.magedu.* 支持~起始的字符做正则表达式模式匹配;server_name ~^www\d+\.magedu\.com$ 匹配机制: (1) 首先是字符串精确匹配; (2) 左侧*通配符; (3) 右侧*通配符; (4) 正则表达式; 练习:定义四个虚拟主机,混合使用三种类型的虚拟主机; 仅开放给来自于本地网络中的主机访问; 4、tcp_nodelay on | off; 在keepalived模式下的连接是否启用TCP_NODELAY选项; 5、sendfile on | off; 是否启用sendfile功能; 定义路径相关的配置: 6、root path; 设置web资源路径映射;用于指明用户请求的url所对应的本地文件系统上的文档所在目录路径;可用的位置:http, server, location, if in location; 7、location [ = | ~ | ~* | ^~ ] uri { ... } location @name { ... } 在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置; =:对URI做精确匹配;例如, http://www.magedu.com/, http://www.magedu.com/index.html location = / { ... } ~:对URI做正则表达式模式匹配,区分字符大小写; ~*:对URI做正则表达式模式匹配,不区分字符大小写; ^~:对URI的左半部分做匹配检查,不区分字符大小写; 不带符号:匹配起始于此uri的所有的url; 匹配优先级:=, ^~, ~/~*,不带符号; root /vhosts/www/htdocs/ http://www.magedu.com/index.html --> /vhosts/www/htdocs/index.html server { root /vhosts/www/htdocs/ location /admin/ { root /webapps/app1/data/ } } 8、alias path; 定义路径别名,文档映射的另一种机制;仅能用于location上下文; 注意:location中使用root指令和alias指令的意义不同; (a) root,给定的路径对应于location中的/uri/左侧的/; (b) alias,给定的路径对应于location中的/uri/右侧的/; 9、index file ...; 默认资源;http, server, location; 10、error_page code ... [=[response]] uri; Defines the URI that will be shown for the specified errors. 11、try_files file ... uri; 定义客户端请求的相关配置 12、keepalive_timeout timeout [header_timeout]; 设定保持连接的超时时长,0表示禁止长连接;默认为75s; 13、keepalive_requests number; 在一次长连接上所允许请求的资源的最大数量,默认为100; 14、keepalive_disable none | browser ...; 对哪种浏览器禁用长连接; 15、send_timeout time; 向客户端发送响应报文的超时时长,此处,是指两次写操作之间的间隔时长; 16、client_body_buffer_size size; 用于接收客户端请求报文的body部分的缓冲区大小;默认为16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置; 17、client_body_temp_path path [level1 [level2 [level3]]]; 设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量; 16进制的数字; client_body_temp_path path /var/tmp/client_body 1 2 2 对客户端进行限制的相关配置: 18、limit_rate rate; 限制响应给客户端的传输速率,单位是bytes/second,0表示无限制; 19、limit_except method ... { ... } 限制对指定的请求方法之外的其它方法的使用客户端; limit_except GET { allow 192.168.1.0/24; deny all; } 文件操作优化的配置 20、aio on | off | threads[=pool]; 是否启用aio功能; 21、directio size | off; 在Linux主机启用O_DIRECT标记,此处意味文件大于等于给定的大小时使用,例如directio 4m; 22、open_file_cache off; open_file_cache max=N [inactive=time]; nginx可以缓存以下三种信息: (1) 文件的描述符、文件大小和最近一次的修改时间; (2) 打开的目录结构; (3) 没有找到的或者没有权限访问的文件的相关信息; max=N:可缓存的缓存项上限;达到上限后会使用LRU算法实现缓存管理; inactive=time:缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项; 23、open_file_cache_valid time; 缓存项有效性的检查频率;默认为60s; 24、open_file_cache_min_uses number; 在open_file_cache指令的inactive参数指定的时长内,至少应该被命中多少次方可被归类为活动项; 25、open_file_cache_errors on | off; 是否缓存查找时发生错误的文件一类的信息; ngx_http_access_module模块: 实现基于ip的访问控制功能 26、allow address | CIDR | unix: | all; 27、deny address | CIDR | unix: | all; http, server, location, limit_except ngx_http_auth_basic_module模块 实现基于用户的访问控制,使用basic机制进行用户认证; 28、auth_basic string | off; 29、auth_basic_user_file file; location /admin/ { alias /webapps/app1/data/; auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.ngxpasswd; } 注意:htpasswd命令由httpd-tools所提供; ngx_http_stub_status_module模块 用于输出nginx的基本状态信息; Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106 Active connections: 活动状态的连接数; accepts:已经接受的客户端请求的总数; handled:已经处理完成的客户端请求的总数; requests:客户端发来的总的请求数; Reading:处于读取客户端请求报文首部的连接的连接数; Writing:处于向客户端发送响应报文过程中的连接数; Waiting:处于等待客户端发出请求的空闲连接数; 30、stub_status; 配置示例: location /basic_status { stub_status; } ngx_http_log_module模块 the ngx_http_log_module module writes request logs in the specified format. 31、log_format name string ...; string可以使用nginx核心模块及其它模块内嵌的变量; 课外作业:为nginx定义使用类似于httpd的combined格式的访问日志; 32、access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; access_log off; 访问日志文件路径,格式及相关的缓冲的配置; buffer=size flush=time 33、open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time]; open_log_file_cache off; 缓存各日志文件相关的元数据信息; max:缓存的最大文件描述符数量; min_uses:在inactive指定的时长内访问大于等于此值方可被当作活动项; inactive:非活动时长; valid:验正缓存中各缓存项是否为活动项的时间间隔; ngx_http_gzip_module: The ngx_http_gzip_module module is a filter that compresses responses using the “gzip” method. This often helps to reduce the size of transmitted data by half or even more. 1、gzip on | off; Enables or disables gzipping of responses. 2、gzip_comp_level level; Sets a gzip compression level of a response. Acceptable values are in the range from 1 to 9. 3、 gzip_disable regex ...; Disables gzipping of responses for requests with “User-Agent” header fields matching any of the specified regular expressions. 4、 gzip_min_length length; 启用压缩功能的响应报文大小阈值; 5、gzip_buffers number size; 支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小; 6、gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any ...; nginx作为代理服务器接收到从被代理服务器发送的响应报文后,在何种条件下启用压缩功能的; off:对代理的请求不启用 no-cache, no-store,private:表示从被代理服务器收到的响应报文首部的Cache-Control的值为此三者中任何一个,则启用压缩功能; 7、gzip_types mime-type ...; 压缩过滤器,仅对此处设定的MIME类型的内容启用压缩功能; 示例: gzip on; gzip_comp_level 6; gzip_min_length 64; gzip_proxied any; gzip_types text/xml text/css application/javascript; ngx_http_ssl_module模块: 1、 ssl on | off; Enables the HTTPS protocol for the given virtual server. 2、ssl_certificate file; 当前虚拟主机使用PEM格式的证书文件; 3、ssl_certificate_key file; 当前虚拟主机上与其证书匹配的私钥文件; 4、ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]; 支持ssl协议版本,默认为后三个; 5、ssl_session_cache off | none | [builtin[:size]] [shared:name:size]; builtin[:size]:使用OpenSSL内建的缓存,此缓存为每worker进程私有; [shared:name:size]:在各worker之间使用一个共享的缓存; 6、ssl_session_timeout time; 客户端一侧的连接可以复用ssl session cache中缓存 的ssl参数的有效时长; 配置示例: server { listen 443 ssl; server_name www.magedu.com; root /vhosts/ssl/htdocs; ssl on; ssl_certificate /etc/nginx/ssl/nginx.crt; ssl_certificate_key /etc/nginx/ssl/nginx.key; ssl_session_cache shared:sslcache:20m; } ngx_http_rewrite_module模块: The ngx_http_rewrite_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations. bbs.magedu.com/ --> www.magedu.com/bbs/, http://www.magedu.com/ --> https://www.magedu.com/ http://www.magedu.com/login.php;username=tom --> http://www.magedu.com/tom/ 将用户请求的URI基于regex所描述的模式进行检查,而后完成替换; 1、rewrite regex replacement [flag] 将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI; 注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此,隐含有循环机制;[flag]所表示的标志位用于控制此循环机制; 如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端; 301:永久重定向; [flag]: last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环; break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环; redirect:重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头; permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求; 2、return return code [text]; return code URL; return URL; Stops processing and returns the specified code to a client. 3、 rewrite_log on | off; 是否开启重写日志; 4、 if (condition) { ... } 引入一个新的配置上下文 ;条件满足时,执行配置块中的配置指令;server, location; condition: 比较操作符: == != ~:模式匹配,区分字符大小写; ~*:模式匹配,不区分字符大小写; !~:模式不匹配,区分字符大小写; !~*:模式不匹配,不区分字符大小写; 文件及目录存在性判断: -e, !-e -f, !-f -d, !-d -x, !-x 5、set $variable value; 用户自定义变量 ; ngx_http_referer_module模块: The ngx_http_referer_module module is used to block access to a site for requests with invalid values in the “Referer” header field. 1、valid_referers none | blocked | server_names | string ...; 定义referer首部的合法可用值; none:请求报文首部没有referer首部; blocked:请求报文的referer首部没有值; server_names:参数,其可以有值作为主机名或主机名模式; arbitrary_string:直接字符串,但可使用*作通配符; regular expression:被指定的正则表达式模式匹配到的字符串;要使用~打头,例如 ~.*\.magedu\.com; 配置示例: valid_referers none block server_names *.magedu.com *.mageedu.com magedu.* mageedu.* ~\.magedu\.; if($invalid_referer) { return 403; } ngx_http_proxy_module模块: The ngx_http_proxy_module module allows passing requests to another server.(该模块可以是实现请求转发功能) 1、proxy_pass URL; Context: location, if in location, limit_except 注意:proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机; server { ... server_name HOSTNAME; location /uri/ { proxy http://host[:port]; } ... } http://HOSTNAME/uri --> http://host/uri proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri; server { ... server_name HOSTNAME; location /uri/ { proxy http://host/new_uri/; } ... } http://HOSTNAME/uri/ --> http://host/new_uri/ 如果location定义其uri时使用了正则表达式的模式,则proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加代理到的服务的之后; server { ... server_name HOSTNAME; location ~|~* /uri/ { proxy http://host; } ... } http://HOSTNAME/uri/ --> http://host/uri/; 2、proxy_set_header field value; 设定发往后端主机的请求报文的请求首部的值;Context: http, server, location proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 3、proxy_cache_path 定义可用于proxy功能的缓存;Context: http proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time]; 4、proxy_cache zone | off; 指明要调用的缓存,或关闭缓存机制;Context: http, server, location 5、 proxy_cache_key string; 缓存中用于“键”的内容; 默认值:proxy_cache_key $scheme$proxy_host$request_uri; 6、proxy_cache_valid [code ...] time; 定义对特定响应码的响应内容的缓存时长; 定义在http{...}中; proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=pxycache:20m max_size=1g; 定义在需要调用缓存功能的配置段,例如server{...}; proxy_cache pxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 1h; proxy_cache_valid any 1m; 7、proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...; Determines in which cases a stale cached response can be used when an error occurs during communication with the proxied server.(当与代理服务器通信错误时,应该返回那种结果给客户端) 8、proxy_cache_methods GET | HEAD | POST ...; If the client request method is listed in this directive then the response will be cached. “GET” and “HEAD” methods are always added to the list, though it is recommended to specify them explicitly. 设定允许客户端请求的方式,get和head默认都会有 9、proxy_hide_header field; By default, nginx does not pass the header fields “Date”, “Server”, “X-Pad”, and “X-Accel-...” from the response of a proxied server to a client. The proxy_hide_header directive sets additional fields that will not be passed.设置隐藏服务器返回给客户端的报文的头部信息, 10、proxy_connect_timeout time; Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.链接超时时间默认为60s; ngx_http_headers_module模块 The ngx_http_headers_module module allows adding the “Expires” and “Cache-Control” header fields, and arbitrary fields, to a response header. 向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值; 1、add_header name value [always]; 添加自定义首部;可用上下文:http, server, location, if in location add_header X-Via $server_addr; add_header X-Accel $server_name; 2、expires [modified] time; expires epoch | max | off; 用于定义Expire或Cache-Control首部的值; ngx_http_fastcgi_module模块: The ngx_http_fastcgi_module module allows passing requests to a FastCGI server. 1、fastcgi_pass address; address为fastcgi server的地址; location, if in location; 2、fastcgi_index name; fastcgi默认的主页资源; 3、fastcgi_param parameter value [if_not_empty]; Sets a parameter that should be passed to the FastCGI server. The value can contain text, variables, and their combination. 配置示例1: 前提:配置好fpm server和mariadb-server服务; location ~* \.php$ { root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name; include fastcgi_params; } 配置示例2:通过/pm_status和/ping来获取fpm server状态信息; location ~* ^/(pm_status|ping)$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $fastcgi_script_name; } 4、fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time]; 定义fastcgi的缓存;缓存位置为磁盘上的文件系统,由path所指定路径来定义; levels=levels:缓存目录的层级数量,以及每一级的目录数量;levels=ONE:TWO:THREE leves=1:2:2 keys_zone=name:size k/v映射的内存空间的名称及大小 inactive=time 非活动时长 max_size=size 磁盘上用于缓存数据的缓存空间上限 5、fastcgi_cache zone | off; 调用指定的缓存空间来缓存数据;http, server, location 6、fastcgi_cache_key string; 定义用作缓存项的key的字符串; 7、fastcgi_cache_methods GET | HEAD | POST ...; 为哪些请求方法使用缓存; 8、fastcgi_cache_min_uses number; 缓存空间中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项; 9、fastcgi_cache_valid [code ...] time; 不同的响应码各自的缓存时长; 示例: http { ... fastcgi_cache_path /var/cache/nginx/fastcgi_cache levels=1:2:1 keys_zone=fcgi:20m inactive=120s; ... server { ... location ~* \.php$ { ... fastcgi_cache fcgi; fastcgi_cache_key $request_uri; fastcgi_cache_valid 200 302 10m; fastcgi_cache_valid 301 1h; fastcgi_cache_valid any 1m; ... } ... } ... } 10、fastcgi_keep_conn on | off; By default, a FastCGI server will close a connection right after sending the response. However, when this directive is set to the value on, nginx will instruct a FastCGI server to keep connections open. 博客作业:以上所有内容; 练习:实现lnmp,提供多个虚拟主机; (1) http, 提供wordpress; (2) https, 提供pma; ngx_http_upstream_module模块 The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass directives. 1、upstream name { ... } 定义后端服务器组,会引入一个新的上下文;Context: http upstream httpdsrvs { server ... server... ... } 2、server address [parameters]; 在upstream上下文中server成员,以及相关的参数;Context: upstream address的表示格式: unix:/PATH/TO/SOME_SOCK_FILE IP[:PORT] HOSTNAME[:PORT] parameters: weight=number 权重,默认为1; max_fails=number 失败尝试最大次数;超出此处指定的次数时,server将被标记为不可用; fail_timeout=time 设置将服务器标记为不可用状态的超时时长; max_conns 当前的服务器的最大并发连接数; backup 将服务器标记为“备用”,即所有服务器均不可用时此服务器才启用; down 标记为“不可用”; 3、least_conn; 最少连接调度算法,当server拥有不同的权重时其为wlc; 4、 ip_hash; 源地址hash调度方法;能够将来自同一个源IP地址的请求始终发往同一个upstream server; 5、hash key [consistent]; 基于指定的key的hash表来实现对请求的调度,此处的key可以直接文本、变量或二者的组合; 作用:将请求分类,同一类请求将发往同一个upstream server; consistent:参数,指定使用一致性hash算法; If the consistent parameter is specified the ketama consistent hashing method will be used instead. 示例: hash $request_uri consistent; hash $remote_addr; 6、keepalive connections; 为每个worker进程保留的空闲的长连接数量; (8) health_check [parameters]; 定义对后端主机的健康状态检测机制;只能用于location上下文; 可用参数: interval=time:检测频率,默认为每隔5秒钟; fails=number:判断服务器状态转为失败需要检测的次数; passes=number:判断服务器状态转为成功需要检测的次数; uri=uri:判断其健康与否时使用的uri; match=name:基于指定的match来衡量检测结果的成败; port=number:使用独立的端口进行检测; 仅Nginx Plus有效; 7、 least_conn; 最少连接调度算法; 当server拥有不同的权重时为wlc; 8、 least_time header | last_byte; 最短平均响应时长和最少连接; header:response_header; last_byte: full_response; 仅Nginx Plus有效; 9、 match name { ... } Defines the named test set used to verify responses to health check requests. 定义衡量某检测结果是否为成功的衡量机制; 专用指令: status:期望的响应码; status CODE status ! CODE ... header:基于响应报文的首部进行判断 header HEADER=VALUE header HEADER ~ VALUE ... body:基于响应报文的内容进行判断 body ~ "PATTERN" body !~ "PATTERN" 仅Nginx Plus有效; nginx的其它的二次发行版: tengine OpenResty ngx_stream_core_module模块 模拟反代基于tcp或udp的服务连接,即工作于传输层的反代或调度器; 1、 stream { ... } 定义stream相关的服务;Context:main stream { upstream sshsrvs { server 192.168.22.2:22; server 192.168.22.3:22; least_conn; hash $remote_addr consistent; } server { listen 10.1.0.6:22022; proxy_pass sshsrvs; } } 2、 listen listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];

November 23, 2015

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