笔记

          Day18(DNS)

.           一

Dns and Bind

   DNS:Domain Name Service,协议(C/S,53.UDP,53/TCP):应用层协议

   BIND:Backerley Internat Name Domain,ISC (www.isc.org)

TCP:面向连接协议

UDP:User Datagram Protocol,无连接协议

本地名称解析配置文件:hosts

   /etc/hosts

   %WINDOWS%/system32/drivers/etc/hosts

DNS查询类型

   递归查询:发出一次请求,可以得到最终结果

   迭代查询:服务器发出查询后,得到查考答案或最终答案,获得最终答案一般需要发送多次查询请求

名称服务器:域内负责解析本域的名称主机

   根服务器:13组服务器

解析类型:

   正向解析:FQDN ——》 IP

   反向解析:IP ——》 FQDN

   FQDN:Full Qualified Domain name

.           二

Dns服务器类型

主DNS服务器:维护所有负责解析的域内解析库服务器:解析库由管理维护

辅   助DNS服务器:从主DNS服务器或其他的从DNS服务器哪“复制”(区域传递)一份解析库

  序列号:解析库的版本号:前提:主服务器解析库内容发生变化,其序列递增

  刷新时间间隔:从服务器从主服务器请求同步解析库的时间间隔

  重试时长间隔:从服务器从主服务器请求同步解析库失败时,再次尝试时间间隔

  过期时长:从服务器,始终联系不到主服务器时候,多久后从服务器角色,停止提供服务

  “通知”机制,主服务器改变后,回向从服务器通知

缓存DNS服务器:不负责解析任何区域

转发器

 

区域传送

   全量传送:传递正个解析库

增量传送:传递解析库发生变化的那部分内容

一次完成的请求流程

   Client à hosts文件 à DNS Service

          Local Cache à Dns server (recursion递归) à Server Cache à iteration(迭代)

   解析答案:

          肯定答案:正确解析请求内容;

          否定答案:请求的条目不存在等原因无法返回结果;

         

          权威答案:

          非权威答案:

区域解析库:由众多RR组成

资源记录:Resource Record,RR

              记录类型:A,AAAA,PTR,SOA,NS,CNAME,MX

          SOA:start Of Authority,起始授权记录:一个区域解析库仅能有一个SOA记录,而且必须为解析库的第一条记录;

  A:internet Address,作用,FQDN à IP

  AAAA:FQDN à IPv6

  NS:Name Server,专用于标明当前区域的DNS服务器

  CNAME:Canoical Name,别名记录

  MX:Mail Exchanger,邮件交换器

资源记录定义格式

语法:name   [TTL]     IN   rr_type value

 

          注意:

(1)   TTL可从全局继承

(2)   @可用于引用当前区域的名字

(3)   同一个名字可以通过多条记录定义多个不同的值,此时DNS会以轮询响应

(4)   同一个值也可以有多个name

SOA:

             name:当前区域的名字,例如‘p-pp.cn.’

             value:由多部分组成

(1)   当前区域的主DNS的FQDN,也可以使用当前区域的名字;@

(2)   当前区域管理员的邮箱地址,但是地址中不能使用@符号,一般使用.替换

(3)   (主从服务协调属性的定义以及否定的答案的统一的TTL)

例如:

       p-pp.cn.             86400    IN SOA  ns.p-pp.cn. nsadmin.p-pp.cn.     (

                            2018041201 ; 序列号

                            2H                ; 刷新时间,M()、H(小时)、D(天)、W(周),默认为秒

                            10M              ;重试时间

                            1W               ;过期时间

                            1D                ;否定应答的TTL值

)

              NS:

                 name;当前区域的名字

                 value:当前区域的某DNS服务器的名字,例如ns.p-pp.cn.;

注意:一个区域可以有多个NS记录

                 例如:

                          p-pp.cn.             IN          NS  ns1.p-pp.cn.

                          p-pp.cn.             IN          NS  ns2.p-pp.cn.

                      注意:

(1)   相邻的两个资源记录的name相同时,后续可省略

(2)   对NS记录而言,任何一个ns记录后边的服务器名字,都应该在后续有一个A记录

MX:

                 name:当前区域的名字

                 value:当前区域的某邮件服务器(smtp)的主机名

                        vakue之前应该有一个数字(0-99),表示此服务器的优先级,数字越小,优先级越高

                 例如:

                        p-pp.cn.             IN          MX  10  mx1.p-pp.cn.

                                             IN          MX  20  mx2.p-pp.cn.

                      注意:

(1)   相邻的两个资源记录的name相同时,后续可省略

(2)   对NS记录而言,任何一个ns记录后边的服务器名字,都应该在后续有一个A记录

A:

                 name:某主机的FQDN,例如www.p-pp.cn.

                 vakue:主机名对应的IP地址;

                 例如:

                        www.p-pp.cn.           IN   A     1.1.1.1

www.p-pp.cn.           IN   A     1.1.1.2

*.p-pp.cn.           IN  A   6.6.6.6    # 泛域名解析

AAAA

                 name:FQDN

                 value:IPv6

PTR:指针

                 name:IP,有特特定格式,返回来写;  1.2.3.4 要写成4.3.2.1:而且有特定后缀:4.3.2.1.in-addr.area.

                 value:FQDN

                 例如:

                        4.3.2.1.in-addr.area. IN PTR  www.p-pp.cn

CNAME:别名

                 name:别名的FQDN

                 value:正式名字的FQDN

                 例如:

                        web.p-pp.cn.            IN   CNAME www.p-pp.cn.

.           三(1.33)

Dns and Bind

   子域授权:每个域的名称服务器,都是通过其上级名称服务器在解析库中进行授权

 

   类似根域授权tld:

          .cn.               IN                 NS                ns1.cn.

          .cn.               IN                 NS                ns2.cn.

          ns1.cn.         IN                 A                   1.1.1.1

          ns2.cn.         IN                 A                   1.1.1.2

 

   p-pp.cn.在.cn的名称服务器上,解析库中添加资源记录

          p-pp.cn.                    IN                 NS                ns1.p-pp.cn.

          p-pp.cn.                    IN                 NS                ns2.p-pp.cn.

          p-pp.cn.                    IN                 NS                ns3.p-pp.cn.

          ns1.p-pp.cn.             IN                 A                   2.2.2.1

          ns2.p-pp.cn.             IN                 A                   2.2.2.2

          ns3.p-pp.cn.             IN                 A                   2.2.2.3

 

   上边的是glue record:黏合记录

 

Bind的安装配置

dns服务:程序包名bind,程序名:named

  服务脚本:/etc/rc.d/init.d/named

  主配置文件:/etc/named.conf,/etc/named.rfc1912.zones,/etc/rndc.key

  解析库文件:/var/named/ZONE_NAME.ZONE

              注意:

(1)   一台服务器可以同时为多个区域提供解析

(2)   应该有跟区域文件

(3)   应该有两个(如果包括ipv6的,应该更多)实现localhost本地回环地址的解析库

 

主配置文件:

   全局配置:options{}

   日志系统配置:logging{}

   区域定义:本机能工为那些zone进行解析,就要定义那些zone

 

   注意:任何服务如果期望被其他网络访问,至少监听在能够和网络通信的ip端口上

[root@www ~]#cat /etc/named.conf

//

// named.conf

//

// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS

// server as a caching only nameserver (as a localhost DNS resolver only).

//

// See /usr/share/doc/bind*/sample/ for example named configuration files.

//

// See the BIND Administrator's Reference Manual (ARM) for details about the

// configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html

 

options {

        listen-on port 53 { any; };           # 监听端口

//      listen-on-v6 port 53 { ::1; };

        directory       "/var/named"; # 解析库文件目录

        dump-file       "/var/named/data/cache_dump.db";

        statistics-file "/var/named/data/named_stats.txt";

        memstatistics-file "/var/named/data/named_mem_stats.txt";

        recursing-file  "/var/named/data/named.recursing";

        secroots-file   "/var/named/data/named.secroots";

//      allow-query     { any; };                   # 允许谁解析

 

        /*

         - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.

         - If you are building a RECURSIVE (caching) DNS server, you need to enable

           recursion.

         - If your recursive DNS server has a public IP address, you MUST enable access

           control to limit queries to your legitimate users. Failing to do so will

           cause your server to become part of large scale DNS amplification

           attacks. Implementing BCP38 within your network would greatly

           reduce such attack surface

        */

        recursion yes;        # 是否允递归查询

//      dnssec-enable yes;

//      dnssec-validation yes;

 

        /* Path to ISC DLV key */

//      bindkeys-file "/etc/named.iscdlv.key";

 

//      managed-keys-directory "/var/named/dynamic";

 

        pid-file "/run/named/named.pid";

        session-keyfile "/run/named/session.key";

};

 

定义区域

(1)   在主配置文件中定义区域

[root@C7-1 ~]#vim /etc/named.rfc1912.zones

zone “ZONE_NAME” IN {
    type {master|alave|hint|forward} ;
    file “ZONE_NAME.zone”;
};

 

(2)    

(3)   定义区域解析库

[root@www named]#vim p-pp.cn.zone

$TTL 86400

$ORIGIN p-pp.cn.        # 当资源记录相对时,补上的路径

@       IN      SOA     ns1.p-pp.cn. admin.p-pp.cn. (

                        2015042201

                        1H

                        5M

                        7D

                        1D )

        IN      NS      ns1

        IN      NS      ns2

        IN      MX 20   mx2

ns1     IN      A       172.19.137.31

ns2     IN      A       172.19.137.32

mx1     IN      A       172.19.137.33

mx2     IN      A       172.19.137.34

www     IN      A       172.16.137.31

ftp     IN      A       172.16.137.31

[root@C7-1 ~]#named-checkconf    # 检测语法

[root@C7-1 ~]#named-checkzone  "p-pp.cn" /var/named/p-pp.cn    # 检测某个单独区域

zone p-pp.cn/IN: p-pp.cn/MX 'mail.p-pp.cn' is a CNAME (illegal)

zone p-pp.cn/IN: loaded serial 0

OK

[root@C7-1 ~]#chown root:named /var/named/p-pp.cn

[root@C7-1 ~]#rndc status

version: 9.9.4-RedHat-9.9.4-61.el7 <id:8f9657aa>

CPUs found: 2

worker threads: 2

UDP listeners per interface: 2

number of zones: 103

debug level: 0

xfers running: 0

xfers deferred: 0

soa queries in progress: 0

query logging is OFF

recursive clients: 0/0/1000

tcp clients: 0/100

server is up and running

[root@C7-1 ~]#dig -t A www.p-pp.cn @192.168.9.71

 

 

          Day19

          Day26(Iptables)

.           一、(iptables netfilter基础)

Firewalld:防火墙

隔离工具:工作于主机或网络的边缘,对于进出本主机或网络的报文根据事先定义好检查规则匹配检测,对于能够被规则所匹配到的报文作出相应处理的组件;

   主机防火墙

   网络防火墙

 

IDS:入侵检测系统,当发现危险访问的时候,告诉防火墙,防火墙会将发起攻击的主机加入黑名单

      HIDS:主机入侵检测系统

      NIDS:网络入侵检测系统

honeypot:蜜罐

蜜罐技术是一种对抗病毒的技术手段,它会主动吸引黑客和病毒的攻击,利用脚本虚拟出的主机服务与黑客和病毒交互

 

iptables/netfilter

   功能:

          filter:过滤,防火墙;

          nat:network address translation,网络地址转换;

          mangle:拆解报文,做出修改,封装报文;

          raw:关闭nat表上启用的连接追踪机制;

   链(内置):

          PREROUTING

          INPUT

          FORWARD

          OUTPUT

          POSTROUTING

三种流向

流入:PREROUTING à INPUT

流出:OUTPUT à POSTROUTING

转发:PREROUTING à FORWARD à POSTROUTING

各功能的分别实现:

   filter:INPUT,FORWARD,OUTPUT

   nat:PREROUTING(DNAT),OUTPUT,POSTROUTING(SNAT)

   mangle:PREROUTING,INPUT,OUTPUT,FORWARD,OUTPUT,POSTROUTING

   raw: PREROUTING, OUTPUT

iptables:四表五链

添加规则的考量点:

(1)   要实现那种功能:判断添加在那张表上;

(2)   报文流经的路径:判断添加在那个链上;

链:链上规则次序,即为检查次序;因此隐含一定的法则

(1)   同类规则(访问同一应用),匹配范围小的放上边;

(2)   不同类规则(访问不同应用),匹配到报文频率较大的放上边;

(3)  合并可由一条规则描述多个规则合并为一个

(4)  设置默认策略

功能的优先级次序:raw  à  mangle  à  nat à  filter

规则:

   组成部分:报文的匹配条件,匹配之后处理动作

              匹配条件:根据协议报文特征指定

                 基本匹配条件:源IP、端口,目标IP、端口 等

                 扩展匹配条件:MAC、追踪等

              处理动作

                 内建处理机制

                 自定义处理机制

              注意:报文不会经过自定义链,只能在内置链上通过引用后生效;

.           二、三(Iptables)

iptables:规则管理工具

添加、修改、删除、显示等

规则和链有计数器

   pkts:由规则或链匹配到的报文的个数

   bytes:由规则或链匹配到的所有报文大小只和

 

iptables命令

iptables [-t table] SUBCOMMAND(子命令) CHAIN(链) CRETERIA(匹配规则) –j TARGET(处理动作)

       iptables [-t table] {-A|-C|-D} chain rule-specification

       iptables [-t table] -I chain [rulenum] rule-specification

       iptables [-t table] -R chain rulenum rule-specification

       iptables [-t table] -D chain rulenum

       iptables [-t table] -S [chain [rulenum]]

       iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]

       iptables [-t table] -N chain

       iptables [-t table] -X [chain]

       iptables [-t table] -P chain target

       iptables [-t table] -E old-chain-name new-chain-name

-t table

          filter,nat,mangle,raw     省略则为filter

链管理

              -F:flush,清空规则链;省略链:清空指定表上的所有链;
              -N:new,创建新的自定义规则链;
              -X:drop,删除用户自定义的空的规则链;
              -Z:zero,清零,置零规则计数器;
              -P:policy,设置指定链的默认处理机制:对filter表的链而言,默认策略通常有ACCEPT,DORP,REJECT;
              -E:rename,重命名自定义链;引用计数不为零的自定义链,无法改名也无法删除

规则管理

              -A:append,将新规则追加于指定链的尾部;
              -I:insert,将新的规则插入为制定位置;
              -D:delete,删除指定链上的指定规则;

                 有两种指定

(1)   指定匹配条件

(2)   指定规则编号

-R:replace,替换指定链上的指定规则;

查看:

              -L:list,列出指定链上的所有规则

                 -n:numberic,以数字格式显示地址和端口号

                 -v:verbose,显示详细信息,-v –vv

                 --line-numbers:显示规则编号

                 -x:exactly,显示计数器计数结果的精确值

示例

   查看规则、删除规则、添加链

 

[root@C6_1 ~]#iptables -t raw –L                          # 查看raw表的规则

[root@C6_1 ~]#iptables -L -n                             # 查看当前默认表的规则,-n表示已数字格式显示端口号

[root@C6_1 ~]#iptables –X                               # 如果不加参数,则会将所有的用户自定义的空链删除

[root@C6_1 ~]#iptables -t filter -N IN_PUBLIC                # 在filter表中添加一个IN_PUBLIC规则

[root@C6_1 ~]#iptables -t filter -E IN_PUBLIC OUT_PUBLIC      # 将filter表中的IN_PUBLIC链的名字改为OUT_PUBLIC

[root@C7_2 ~]#iptables -t filter -P FORWARD DROP           # 更改filter表的FORWARD默认策略为拒绝

[root@C7_2 ~]#iptables -L -n --line-number                 # 查看默认表filter的里边规则,--line-number带上编号

[root@C7_2 ~]#iptables -D FORWARD 9                   # 删除默认表FORARD的第九条规则

 

匹配条件:

基本匹配:

          [ ! ] –s,--src,--source IP | NNetaddr : 检查报文中源IP地址是否符合此处指定的地址范围

          [ ! ] –d,--dst,--destination IP | Netaddr:检查报文源IP地址是否符合此处指定的地址范围

          [ ! ] –p,--protocol {tcp | udp | icmp}:检查报文中的协议,即IP首部中的protocol所标识的协议

            [ ! ] –i,--in-interface IFACE:数据报文的流入接口;仅能用于PREROUTING,INPUT,FORWARD链上

          [ ! ]-o,--out-interface IfACE:数据报文的流出流出借口;仅能用于OUTPUT,POSTROUTING

扩展匹配:-m match_name –spec_options

                 例如:-m tcp –dport 22

隐式扩展:对-p protocol指明的协议进行扩展,可省略-m选项
-p tcp

                        --dport PORT [-PORT]:目标端口可以是单个端口,或连续多个端口

                               [root@C7_2 ~]#iptables -I INPUT -d 192.168.9.72 -p tcp --dport 22 -j ACCEPT

                        --sport PORT [-PORT]

                               [root@C7_2 ~]#iptables -I OUTPUT -s 192.168.9.72 -p tcp --sport 22 -j ACCEPT

                        --tcp-flags list1 list2:检查list1,切这些标记位中,list2列出的所有标记位必须为1,而余下的必须为0:没有list1中指明的,不做检查

                               SYN,ACK,FIN,RST,PSH,URG

                        --syn:检查是不是tcp请求的第一次请求

-p udp

                        --dport

                        --sport

-p icmp

                        --icmp-type

                               可用数字表示类型

                                      0:echo-reply

                                      8:echo-require

                               例如:只让自己ping别人,不让别人ping自己

[root@C7_2 ~]#iptables -A INPUT -d 192.168.9.72 -p icmp --icmp-type 0 -j ACCEPT

[root@C7_2 ~]#iptables -A OUTPUT -s 192.168.9.72 -p icmp --icmp-type 8 -j ACCEPT

 

显示扩展:必须使用-m选项指定使用的扩展模块(rpm -ql iptables | grep "[[:lower:]]\.so"可以看到扩展)

                        centos6:man iptables

                        centos7:man iptables-extensions

1、multiport扩展:以离散方式定义多端口匹配机制,最多指定15个端口;

                        [!] --source-ports,--sports port[,port|,port:port]...    指明做个源端口;

                        [!] --destination-ports,--dports port[,port|,port:port]...   指明多个目标端口;

                        [!] --ports port[,port|,port:port]...    既能匹配源,也能匹配目标

                 例:允许tcp的22端口和80端口

                 [root@C7_2 ~]#iptables -I INPUT -s 192.168.9.0/24 -d 192.168.9.72 -p tcp -m multiport --dport 22,80 -j ACCEPT

                 [root@C7_2 ~]#iptables -I OUTPUT -d 192.168.9.0/24 -s 192.168.9.72 -p tcp -m multiport --sport 22,80 -j ACCEPT

 

2、iprange扩展:指明连续的ip地址范围(一般不能为整个网络)

                        [!] --src-range from[-to]:指明连续的源ip地址范围

                        [!] --dst-range from[-to]:指明连续的目标地址范围

                  例子:允许192.168.9.0-192.168.9.10的ip访问本机的22,23,80端口

[root@C7_2 ~]# iptables -I INPUT -d 192.168.9.72  -p tcp -m multiport --dport 22:23,80 -m iprange --src-range 192.168.9.0-192.168.9.10 -j ACCEPT                 # 22:23的意思是从22端口到23端口

[root@C7_2 ~]# iptables -I OUTPUT -s 192.168.9.72  -p tcp -m multiport --sport 22:23,80 -m iprange --dst-range 192.168.9.0-192.168.9.10 -j ACCEPT          

3、string扩展 :检查报文中的字符串

                        --algo {bm|kmp}

                               bm = Boyer-Moore,

kmp = Knuth-Pratt-Morris

                          --from offset

                          --to offset  

                          [!] --string pattern

                          [!] --hex-string pattern

                          例如:当请求回应的时候包含某个字符串的时候,拒绝

[root@C7_2 ~]#iptables -I OUTPUT -M string --algo bm --string "movie" -j REJECT   # 当包含”movie”则会被拒绝

4、time扩展:根据报文到达的时间于指定的时间范围匹配

                        --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]

                        --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]

                        --timestart hh:mm[:ss]

                        --timestop hh:mm[:ss]

                        [!] --monthdays day[,day...]

                        [!] --weekdays day[,day...]     Mon, Tue, Wed, Thu, Fri, Sat, Sun

                        例如:设置某段时间不能访问,注意:这里是UTP时间

[root@C7_2 ~]#iptables -I INPUT -d 192.168.9.72 -p tcp --dport 80 -m time --timestart 11:35 --timestop 11:40 -j REJECT

5、connlimitj扩展:根据没客户端IP(也可以是地址块)做并发连接数匹配

                        --connlimit-above n:连接的数量大于n

                        --connlimit-upto n:连接的数量小于等于n

                        例子:设置ssh的并发连接数数量大于3个的话就拒绝

                 [root@C7_2 ~]#iptables -I INPUT  -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT

6、limit:基于收发报文速率做检查

                        令牌桶过滤器

                        --limit rate[/second|/minute|/hour|/day]

                        --limit-burst number

                        例如:设置别人对本机的ping请求的峰值为5,速率为每分钟30个

                 [root@C7_2 ~]#iptables -I INPUT -d 192.168.9.72 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 30/minute -j ACCEPT

7、state扩展:根据每个连接追踪检查连接的状态

                        调整连接追踪所能容纳的最大连接数量

                               /proc/sys/net/nf_conntrack_max

                        已经追踪并记录下的连接

                               /proc/net/nf_conntrack

                        不同协议或连接连接的时长

                               /proc/sys/net/netfilter/

 

          iptables的链接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max,链接碰到各种状态的超时后就会从表中删除。

 

          所以解決方法一般有两个:

          (1) 加大 ip_conntrack_max 值

          vi /etc/sysctl.conf

          net.ipv4.ip_conntrack_max = 393216

          net.ipv4.netfilter.ip_conntrack_max = 393216

          (2): 降低 ip_conntrack timeout时间

          vi /etc/sysctl.conf

          net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300

          net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120

          net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

          net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

 

          iptables -t nat -L -n

                        可追踪的连接状态

                               NEW:新发出的请求:连接追踪模板(/proc/net/nf_conntrack)中不存在此链接的信息条目

                               ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信的状态;

                               RELATED:相关的连接;如ftp协议中的命令连接与数据连接之间的关系

                               INVALIED:无法识别的连接:

                        [!] --state state1,state2....

                               [root@C7_2 ~]#iptables -I INPUT -d 192.168.9.72 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

[root@C7_2 ~]#iptables -I OUTPUT -s 192.168.9.72 -p tcp --sport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

                        问题:如何开放被动模式ftp服务

(1)  装载ftp追踪时的专用模块

a)     [root@C7_2 ~]#modprobe nf_conntrack_ftp

(2)  放行请求:

a)     命令连接:NEW,ESTABLISHED

b)     数据连接:RELATED,ESTABLISHED

[root@C7_2 ~]#iptables -A INPUT -d 192.168.9.72 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT 

[root@C7_2 ~]#iptables -A INPUT -d 192.168.9.72 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT

(3)  放行响应报文

a)     ESABLISHED

[root@C7_2 ~]#iptables -A OUTPUT -s 192.168.9.72 -p tcp -m state --state ESTANLISHED -j ACCEPT

目标(动作):

-j TARGET:jump,跳转

   ACCEPT:接受

   DROP:丢弃

   REJECT:拒绝

   RETURN:返回调用链

   REDIRECT:端口重定向

 LOG:记录日志

   MAPK:做防火墙标记

   DNAT:目标地址转换

   SNAT:源地址转换

   MASQUERADE:地址伪装

   ....

   自定义链:由自定义链上的规则进行匹配检查

示例

  

[root@C7_2 ~]#iptables -t filter -A INPUT -d 192.168.9.72 -p tcp -j ACCEPT      # 添加一条规则,目标地址是192.168.9.72就放行

[root@C7_2 ~]#iptables -t filter -A OUTPUT -s 192.168.9.72 -p tcp -j ACCEPT    # 允许源地址为192.168.9.72的流量出去

# 下边三条命令是将filter的三条链的默认权限全部设置为丢弃,前提需要上边两步允许了192.168.9.72的访问,否则ssh链接会断开

[root@C7_2 ~]#iptables -P INPUT DROP

[root@C7_2 ~]#iptables -P FORWARD DROP

[root@C7_2 ~]#iptables -P OUTPUT DROP

# 现在测试ping 192.168.9.72是无法ping通的,可以做一下设置

①限定icmp

[root@C7_2 ~]#iptables -t filter -A INPUT -p icmp -j ACCEPT           # 允许icmp流量进来

[root@C7_2 ~]#iptables -t filter -A OUTPUT -p icmp -j ACCEPT         # 允许icmp报文出去

②限定接口

[root@C7_2 ~]#iptables -A INPUT -d 192.168.9.72 -i ens33 -j ACCEPT

[root@C7_2 ~]#iptables -A OUTPUT -s 192.168.9.72 -o ens33 -j ACCEPT

 

 

.           四

如何保存重载规则

保存规则至指定文件

   iptables-save > /PATH/TO/SOMEFILE

从指定文件重载规则

   iptables-restore < /PATH/TO/SOMEFILE

Ceentos 6:

   service iptables save

          iptables-save > /etc/sysconfig/iptables

   service iptables restore

          iptables-restore < /etc/sysconfig/iptables

Centos 7:

   引入了新的iptables前段管理服务工具:firewalld

          firewall-cmd

          firewall-config

网络防火墙

 实验:使用三台linux服务器,第一台A为内网服务器,第二台B为网络防火墙,第三台C为外网主机,实现ftp、ssh、web的访问

 

A eth0:192.168.9.6       eth0:192.168.9.7 B eth1:192.168.80.7                eth0:192.168.80.17 C

 

A的配置

   ①安装并启动服务vsftpd、httpd、sshd:使用yum安装,想默认共享目录存放验证文件,启动即可

   ②设置网关为192.168.9.7

B的配置

   ①开启路由转发功能:[root@c7_1 ~]#sysctl -w net.ipv4.ip_forward=1

   ②防火墙配置

          [root@C7_1 ~]#modprobe nf_conntrack_ftp

          [root@c7_1 ~]#iptables -P FORWARD DROP

          [root@c7_1 ~]#iptables -A FORWARD -d 192.168.9.6 -p tcp -m multiport --dport 21,22,80 -m state --state NEW -j ACCEPT

          [root@c7_1 ~]#iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

 

C:配置192.168.9.0的下一条为192.168.80.7

   [root@redhat ~]#ip route add 192.168.9.0/24 via 192.168.80.7

 

.           练习

主机防火墙:

          放行telent,ftp,web服务              telent:23/tcp

          放行samba服务                           samba:137/udp、138/udp、139/tcp、445/tcp

          放行dns服务(对本机的请求、区域传送)  dns:INPUT:53/udp,OUTPUT:53/tdp

网络防火墙

          放行telent,ftp,web服务

          放行samba服务

          放行dns服务

 

          Day27(iptables)

.           一(iptables的nat表)、

nat:Network Address Translation,安全性,网络层+传输层

proxy:代理,应用层

nat

SNAT:只修改请求报文的源地址

DNAT:只修改请求报文的目的地址

nat表

   PREROUTING:DNAT

   FORWARD

   POSTROUTING:SNAT

 

SNAT配置

例子:A为内网主机,B为网络nat防火墙,C为公网Web主机

          A:192.168.9.7   gw:192.168.9.72

          B:192.168.9.72,开启路由转发功能

                 192.168.80.7

          C:192.168.80.17,只需要设置ip

 

     B: [root@B ~]#iptables -t nat -A POSTROUTING -s 192.168.9.0/24 ! -d 192.168.9.0/24 -j SNAT --to-source 192.168.80.7

     A:curl 192.168.80.17     # 可以访问到web即可

DNAT配配置

   例子:A为内网web主机,B为网络nat防火墙,C为公网主机

          A:192.168.9.7   gw:192.168.9.72

          B:192.168.9.72,开启路由转发功能

                 192.168.80.7

          C:192.168.80.17,只需要设置ip

 

MASQUERADE:地址伪装

SNAT 的实验环境,将B防火墙的主机策略修改

          [root@B ~]#iptables -t nat -A POSTROUTING -s 192.168.9.0/24 -p tcp --dport 80 ! -d 192.168.9.0/24 -j MASQUERADE

 

 

 

 

 

 

.           三(Nginx)

淘宝扫地僧“多隆“:https://www.xinmei6.com/news/view/newsId/29251.html

 

 

HTTP/1.0200OK

Data:Mon,31Dec200104:25L57GMT

Server:Apache/1.3.14(Unix)      # 可以定义服务器

Connent-type:text/html

Last-modifined:Tue,17Apr200106:46:28GMT

Etag:”a030f020ac7c01:1e9f”             # 页面改变则这个值就会变

Content-length:39725426

Connent-range:bytes554554-40279979/40279980

 

.           四

HTTP(超文本传输协议)

常见实现方式

html:php、jsp、python

pv:page view,一次页面的访问,淘宝、京东每天大概有二十亿以上

uv:User view,多少用户访问,

active conntion:活动连接数

qps:没秒的new的请求

一个日pv为2亿的网站,active conntion差不多为一百万,qps为1-2万

MIME:Multipurpose Internet Mail Extension (MIME的引入,可以让超文本协议不仅可以传输文本,可以传输图片等)

          major/minor

                 text/plain

                 image/jpeg

  

Nginx

①是一款轻量级的Web服务器

②反向代理服务器(负载均衡器)

③电子邮件代理服务

④能实现缓存功能

 

select 和 epoll

select:同步阻塞

(1)      每次调用select,都需要吧fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

(2)      同时每次调用select都需要在内核便利传递进来的所有fd,这个开销在fd很多时也很大

(3)      selct支持的文件描述符数量小,默认是1024

epoll:异步模型

(1)      支持一个进程打开大数目的socket描述符

(2)      IO效率不随FD数目增加而线性下降

(3)      使用mmap加速内核与用户空间的消息传递

(4)      边缘触发和水平触发

 

优点

(1)高并发连接

(2)内存消耗少

(3)配置文件非常简单

(4)成本低廉

(5)支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP 请求分到不同的后端服务器群组

(6)内置的健康检查功能:如果Nginx Proxy 后端某台Web服务区不能用了,会将该机器makedown

(7)节省带宽:支持GZIP压缩

(8)稳定性高、:用于反向代理

(9)模块化设计:模块可以动态编译

(10)       外围支持好:一文档全、二次开发和模块较多

(11)       支持热部署:可以不停机重载配置文件

(12)       支持事件驱动、AIO、mmap等性能优化

 

          day28(Nginx)

.           一(nginx 安装和配置)

Nginx的主要应用类别

  1. 使用nginx几个FastCGI运行 php、JSP、Perl等程序
  2. 使用Nginx做反向代理、负载均衡、规则过滤
  3. 使用Nginx运行静态HTML页、图片
  4. Nginx与其他新技术的结合使用

 

Nginx的模块

Nginx的模块从结构上分为核心模块、基础模块、第三方模块

Nginx的模块从功能上分为三类,分别是

(1)   Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个;
(2)   Filtrs(过滤器模块)
(3)   proxies (代理类模块)

Nginx的安装

   官网下载软件包,然后解压

预编译:

[root@C7_2 nginx-1.14.2]#yum install gcc gcc-c++ pcre-devel openssl-devel gd-devel -y

./configure --prefix=/usr/local/nginx1.14.2 --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module

make && make install

 

常见的配置文件

nginx.conf:应用程序的基本配置文件

mime.types:MIME类型关联的扩展文件

fastcgi.conf:与fastcgi相关的配置

proxy.conf:与proxy相关的配置

sites.conf:配置nginx提供的网站,包括虚拟主机

.           二、

主配置文件nginx.conf

main段 官方文档:http://nginx.org/en/docs/ngx_core_module.html

worker_processes  4;                       # 进程数

worker_cpu_affinity 0101 1010;        # 为进程绑定cpu

worker_priority -10;                          # 优先级,数字越小越高-20 – 20,其实是nice优先级100-139

worker_rlimit_nofile 65535;              # nginx的打开最大文件数

timer_resoluyion                               # 计时器解析度:降低次值,提高性能

 

 

events段

       worker_connections  1024;          # 每个进程的的最大连接数

       accept_mutex {off | on}          # master调度用户请求各worker进程时使用的负载均衡锁;on表示能让多个worker轮流相应新请求

       look_file file                             # accept_metex用到的锁文件

       use [epoll | rtsig | select | poll]             # 连接处理方法

用于调试、定位问题  --with-debug

  1. daeon { on | off };             # 是否以守护进程方式运行nginx;调试时应该设置为off;
  2.  master_process { on | off};   # 是否以master/worker 模型来运行nginx;调试可以设置为off;
  3. error_log 位置 级别;             # 若要使用debug级别,需要--with-debug

 

 

http段 http://nginx.org/en/docs/http/ngx_http_core_module.html

include       mime.types;         # 导入其他配置文件

       root

Context:httpserverlocationif in location

 

sendfile        on;               # 不用交互发文件,高效传输

keepalive_timeout  65;          # 长链接65秒

tcp_nodelay on                      # 是否对长连接使用tco_nodelay

gzip  on;                                # 支持压缩

gzip_min_length 1000;             # 最小长度,1000字节

gzip_proxied    expired no-cache no-store private auth;          # 那些不压缩

gzip_types      text/plain application/xml;            # 压缩的类型
gzip_comp_level 6;            # 压缩级别为6

server段

listen

listen 127.0.0.1:8000;

listen 127.0.0.1 default_server

listen 8000;

listen *:8000;

listen localhost:8000;

server_name

              www.p-pp.cn;

              *.p-pp.cn;

              www.p-pp.*

              ~^.*\.p-pp\.cn$

              default_server

              精确匹配 > 左侧通配符匹配 > 右侧通配符 > 正则表达式检查 > default_server

              ~^img\.p-pp\.cn$;

location

 

句法:

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

默认:

-

语境:

server, location

 

       location /www

       location = /www

       location ^~ /www

       location ~ /www         # 区分大小写

       location ~* /www

 

 

location = / {

    [ configuration A ]

}

 

location / {

    [ configuration B ]

}

 

location /documents/ {

    [ configuration C ]

}

 

location ^~ /images/ {

    [ configuration D ]

}

 

location ~* \.(gif|jpg|jpeg)$ {

    [ configuration E ]

}

The “/” request will match configuration A, the “/index.html” request will match configuration B, the “/documents/document.html” request will match configuration C, the “/images/1.gif” request will match configuration D, and the “/documents/1.jpg” request will match configuration E.

 

 

 

(location =) > (location ^~ 路径) > (~ location ~* 正则) > (location  路径)

查找优先级顺序

(1)    带有“=”的精确匹配

(2)    没有修饰符的精确匹配

(3)    正则表达式按照他们在配置文件中定义的顺序

(4)    带有”^~修饰符的”,开头匹配

(5)    带有“~” 或 “~*” 修饰符的,如果正则表达式与URL匹配

(6)    没有修饰符的,如果指定字符与URL开头匹配

alias path           # 用于location配置段,定义路径别名,root和alias的区别

      location /images/ {

      root /vhosts/web1;                 # http://www.p-pp.cn/images/a.jpg   à /vhosts/web1/images/a.jpg

}

      location /images/ {

      alias /chost/web1;                  # http://www.p-pp.cn/images/a.jpg       à   /www/web1/a.jpg

}

error_page 404=200 /404_customde.html;         # 如果访问的代码是404,就会返回404_customde.html文件,并且返回代码为200

.           三(第三方模块、访问控制、用户验证、ststus)

安装第三方模块echo

https://github.com/openresty/echo-nginx-module

./configure --prefix=/usr/local/nginx1.14.2 --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_flv_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --add-module=echo-nginx-module-0.60

make && make install

 

 

访问控制

Allow、Deny

allow 192.168.9.61/32;                                                 

deny all;

 

用户认证访问

       Auth_basic

              auth_basic "Welcome to Vip user"; 

       Auth_basic_user_file

       auth_basic_user_file /usr/local/nginx/basic_user.file;

状态(status)监测

        location = /status {

                stub_status on;

                access_log off;                                                

        }

Active connections: 1                    # 当前所有处于打开状态连接

server accepts handled requests

 161 161 223

(1)    已经接受过的连接数

(2)    已经处理的连接数

(3)    已经处理的请求数:在“保持模式下”,请求数量可能会多于连接数量

Reading: 0 Writing: 1 Waiting: 0

Reading:正处于接收请求状态的连接数。

Writing:请求已经完成,正处于请求或发送响应的过程中的连接数。

Waiting:保持连接模式,且处于活动状态的连接数。

https的配置

[root@C7_2 web1]#cd /etc/pki/CA/

[root@C7_2 CA]#(umask 077;openssl genrsa -out private/cakey.pem 2048)

[root@C7_2 CA]#openssl req -new -x509 -key private/cakey.pem -out cacert.pem  -days 36500

[root@C7_2 CA]#touch serial index.txt

[root@C7_2 CA]#echo 01 > serial

[root@C7_2 CA]#cd /usr/local/nginx

[root@C7_2 nginx]#(mkdir ssl;umask 077;openssl genrsa -out ssl/nginx.key 1024)

[root@C7_2 nginx]#openssl req -new -key ssl/nginx.key -out ssl/nginx.csr

[root@C7_2 nginx]#openssl ca -in ssl/nginx.csr -out ssl/nginx.crt -days 3650

[root@C7_2 nginx]#vim conf/nginx.conf

    server {

        listen       443 ssl;

        server_name  C7-2.p-pp.cn;

        ssl_certificate      /usr/local/nginx/ssl/nginx.crt;

        ssl_certificate_key  /usr/local/nginx/ssl/nginx.key;

        location / {

            root   html;

            index  index.html index.htm;                                                             

        }

    }

 

 

.           四(Rewrite、)

Rewrite重写

       rewrite语法:rewrite regex replacement flag;

              rewrite ^/images/(*\jpg)$ /imgs/$1   break;# $1代表前边括号的东西

       flag:

              last:此rewrite重写完成后,不在被后边的其他rewrite进行处理,而是由User Agent对重写后URL再一次发起请求,并重头执行类似的过程

                     rewrite ^/rw/(.*\.html)$ /img/$1 last;

              break-一旦此rewrite重写后,由User Agent对重写后URL再一次发起请求,切不再会被当前location的人格规则所检查

                     rewrite ^/rw/(.*\.html)$ /img/$1 break;

              redirect-返回临时重定向的HTTP状态302

                     rewrite ^/rw/(.*\.php)$ http://C7-2.p-pp.cn/img/$1 redirect;

              permanent – 返回永久重定向HTTP状态301

 

 

if (condition) {...}

condition

  1. 变量名:变量值为空串,或者以“0”开始,则为false,其他均为true
  2. 以变量为操作数构成的比较表达式,可使用=,!=类似的比较操作符测试
  3. 正则表达式的模式匹配操作

a)      ~:区分大小写的模式匹配检查

b)     ~*:不区分大小写

c)      !~ 和 !~*:对上边两种取反

  1. 测试路径为文件的可能性:-f,!-f
  2. 测试目录可能性:-d,!-d

浏览器分离

       if($http_user_agent ~ Firefox) {

              rewrite ^(.*)$ /firefox/$1 break;

}

 

防盗链

 location ~* \.{jpg|gif|jeng|png}$ {

       valid_referer none blocked www.p-pp.cn;              # 定于合法的引用者,不阻止的域名

       if ($invald_referer) {          # invald_referer,所有不被valid_referer合法引用的,都是invald_referer不合法引用

              rewrite ^/ http://www.p-pp.cn/403.html ;

}

}

 

fastcgi的相关配置:

LNMP:php启用fpm模型

 

Nginx负载均衡(proxy)

 

RR:轮询

IPhash:用于登录,购买等

 

upstream xuan {

    ip_hash;

        server 192.168.9.51:80 weight=1 down;

        server 192.168.9.61:80 weight=1 backup;

        server 192.168.9.71:80 weight=1 max_fails=1 file_timeout=1s;;

}

location / {

                proxy_pass http://xuan;

}

 

          day29(LVS)

.           一

Cluster

       系统扩展的方式

              scale up:向上扩展,性能好的代替会性能差的

              scale out:向外扩展,当主机难以解决现有请求,可以添加主机

集群类型

              LB:负载均衡集群,load balancing

              HA:高可用集群,High Availability

              HP:高性能集群,High Performancing

       系统:

              可扩展性

              可用性

              容量:在一定时间内内完成的工作的总量

              性能:衡量响应时间的

 

     总结:

              分层:静态内容层、动态内同层、数据存储层

              分割:

              分布式:分布式应用、静态资源、数据和存储、计算

 

.           二、(LB集群的实现、lvs的类型)

LB 集群的实现

       硬件

              F5 big-ip:最好的,价格高

              Citrix NetScaler

              A10 A10

       软件

              lvs

              haproxy

              nginx

              ats(apache traffic server)

              perlbal

              基于工作层次划分

                     传输层:lvs,haproxy(mode tcp)

                     应用层:haproxy、nginx、ats、perlbal

 

lvs(linux virtual server)

       l4:四层交换:根据请求报文的目标IP和PORT将其转发至后端主机集群中的某一台主机(根据算法挑选);

 

       ipvsadm:用户态的命令行工具,用于管理及群服务

       ipvs:内核态,工作在netfilter INPUT链上;

 

lvs arch

       调度器:director(导演),dispatcher(分发器),balabcer(均衡器)

       RS:Real Server (后端的真实服务器)

 

       Client IP:CIP

       VIP:

       Director:DIP

       Real Server IP : RIP

lVS type

       lvs-nat:MASQUERADE

              多目标的DNAT(iptables):他通过修改请求报文的目标ip地址(同事可能可能会修改目标端口)至少挑选出某RS的RIP地址实现转发

(1)    RS应该和DIP使用私网地址,切RS的网关要指向DIP

(2)    请求和响应报文都要经有director转发:极高负载场景中,director可能会成为系统瓶颈

(3)    支持端口映射

(4)    RS可以使用任意OS

(5)    RS的RIP和Director的DIP必须在同一IP网络

 

       lvs-dr   (direct routing)

              它通过修改请求报文的目标MAC地址进行转发

                     Director:VIP、DIP

                     Real server:RIP、VIP

                     请求报文经过direct,回应报文由real server 直接回应,回应的源ip是VIP

(1)    保证前段路由器将目标ip为VIP的请求发给director;

a)      静态绑定,将MAC与VIP进行绑定,但是不能实现高可用

b)     arptables,使用arp防火墙(不会)

c)      修改RS主机的内核参数

(2)    RS的RIP可以使用私有地址,但是也可以使用公网地址;

(3)    RS根Director必须在同一物理网络中

(4)    请求报文经由Director调度,但响应报文不一定经由Director;

(5)    不支持端口映射

(6)    RS可以使大多OS

(7)    RS的网关不能是DIP

 

       lvs-tun  (ip tunneling)

              不修改请求报文的ip首部,而是通过原有ip首部(cip <--> vip)之外,在封装一个首部(dip <-->);

(1)    RIP,DIP,VIP全得是公网地址

(2)    RS的网关不能指向DIP

(3)    请求报文必须有director调度,但响应报文必须不经由director

(4)    不支持端口映射

(5)    RS的OS 必须支持隧道功

       lvs-fullnat:(Centos 6 的内核默认不支持fullnat)

              director通过同事修改

(1)    VIP是公网地址:RIP和DIP是私网地址,二者无需再同一网络中

(2)    RS接收到的请求报文的源地址为DIP,因此响应给DIP

(3)    请求报文的响应报文都必须经由Director

(4)    支持端口映射

(5)    RS可以使用任意OS

.           三、(lvs调度器算法、ipvsadm的用法)

http:stateless,http是无状态的

       session保持:

              session绑定

                     source ip hash

                     cookie hash (应用层的负载均衡可以实现,lvs无法实现)

              session集群

              session服务器

 

lvs scheduler:lvs调度器

       静态方法:仅根据算法本身进行调度

              RR:round robin,论调
              WRR:weighed rr,
              SH:source hash,实现session保持的机制,来自同一个ip的请求始终调度至同一RS
              DH:destination hash,将对同一个目标的请求始终发往同一个RS

       动态方法:根据算法及各RS的当前负载均衡状态进行调度

                     overhead:当前的负载

              LC:least Connection

                     overhead=Active * 256 + Inactive

              WLC:weighted LC

                     Overhead=(Active * 256 + Inactive)/ weight

              SED:Shortest Expection Delay

                     Overhead = (active + 1 ) * 256 / weight

              NQ:Never Queue

                     SED算法的改进

              LBLC:Locality-Based LC,即为动态的DH算法

                     正向代理情形下的cache server

              LBLCR:Locality-Based Least-Connection with Replicatio

 

ipvsadm的用法

       管理集群服务

              ipvsadm -A|E -t|u|f service-address [-s scheduler]

              ipvsadm -D -t|u|f service-address       

             

              service-address

                     tcp:-t ip:port

                     udp:-u ip:port

                     fwm:-f mark

       管理集群服务中的RS

              ipvsadm -a|e -t|u|f service-address -r server-address

              ipvsadm -d -t|u|f service-address -r server-address

                    

              -s scheculer

                     默认为wlc(加权最少链接)

              -r server-address

                     real ip:port

              lvs-type

                     -g:Gateway,dr

                     -i:ipip,tun

                     -m:masquerade,nat

       查看和清理

              ipvsadm –C   清空

              ipvsadm -L|l [options]   查看

保存和重载

              ipvsadm –R    重载ipvsadm-resote

       ipvsadm -S [-n]   保存 ipvsadm-save

       置零计数器

              ipvsadm -Z [-t|u|f service-address]

 

 

.           四

lvs-nat的案例

A:scheduler    B:node1   C:node2

A:eth2(和外网通信):192.168.80.7            eth0(与node通信):192.168.9.71

B:eth0:192.168.9.51      gw:192.168.9.71

C:eth0:192.168.9.52      gw:192.168.9.71

 

A:

[root@scheduler ~]#sysctl -w net.ipv4.ip_forward=1

[root@scheduler ~]#ipvsadm -A -t 192.168.80.7:80 -s rr

[root@scheduler ~]#ipvsadm -a -t 192.168.80.7:80 -r 192.168.9.51:80 -m

[root@scheduler ~]#ipvsadm -a -t 192.168.80.7:80 -r 192.168.9.61:80 -m

 

B:

[root@node1 ~]#yum install httpd

[root@node1 ~]#echo node1 > /var/www/html/index.html

[root@node1 ~]#service httpd start

[root@node1 ~]#ip route add default via 192.168.9.71

C:

[root@node2 ~]#yum install httpd

[root@node2 ~]#echo node2 > /var/www/html/index.html

[root@node2 ~]#service httpd start

[root@node2 ~]#ip route add default via 192.168.9.71

 

 

保存现有的ipvsadm配置:

[root@scheduler ~]#ipvsadm -Sn > /tmp/ipvsadm1

[root@scheduler ~]#ipvsadm -R < /tmp/ipvsadm1

修改调度器算法

       [root@scheduler ~]#ipvsadm -E -t 192.168.80.7:80 -s sh              # 修改为原地址hash算法

查看

       [root@scheduler ~]#ipvsadm –ln        # 显示配置列表

[root@scheduler ~]#ipvsadm –lc         # 显示当前建立的连接

       [root@scheduler ~]#ipvsadm -ln –stats      # 显示统计数据

[root@scheduler ~]#ipvsadm -ln –rate       # 速率

[root@scheduler ~]#ipvsadm -ln –exact     # 显示精确值

 

lvsdr的案例

       arp_announce:是否通告给别人

              0:通告

              1:尽量避免想向本网络通告非本网络的接口地址

              2:直通告最佳本地地址,就是只想本网路通告本接口的地址

       arp_ignore:对于请求的arp是否相应

              0:只要收到请求,无论哪个接口请求,只要我的任意接口拥有这个ip,我就回应你

              1:请求报文从那个接口进入,我就必须判断该接口的ip是否是请求的ip,如果不是,我就不做回应

      

A:scheduler B:node1   C:node2

A:eth0(DIP):192.168.9.72            eth0:0(VIP)192.168.9.27/32

B:eth0:192.168.9.51                           lo:0(VIP)192.168.9.27/32

C:eth0:192.168.9.52                           lo:0(VIP)192.168.9.27/32

A:

[root@scheduler ~]#ifconfig eth0:0 192.168.9.27/32 broadcast 192.168.9.27 up

[root@scheduler ~]#route add 192.168.9.27/32 dev eth0:0

[root@scheduler ~]#ipvsadm -A -t 192.168.9.27:80 -s rr 

[root@scheduler ~]#ipvsadm -a -t 192.168.9.27:80 -r 192.168.9.51:80 -g

[root@scheduler ~]#ipvsadm -a -t 192.168.9.27:80 -r 192.168.9.61:80                    # 默认就是-g的直接路由模式

      

B:

[root@node1 ~]#yum install httpd

[root@node1 ~]#echo node1 > /var/www/html/index.html

[root@node1 ~]#service httpd start

[root@node1 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

[root@node1 ~]#echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

[root@node1 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

[root@node1 ~]#echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce

[root@node1 ~]#ifconfig lo:0 192.168.9.27/32 broadcast 192.168.9.27 up

[root@node1 ~]#route add 192.168.9.27/32 dev lo:0

 

C:

[root@node2 ~]#yum install httpd

[root@node2 ~]#echo node2 > /var/www/html/index.html

[root@node2 ~]#service httpd start

[root@node2 ~]#echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

[root@node2 ~]#echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

[root@node2 ~]#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

[root@node2 ~]#echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce

[root@node2 ~]#ifconfig lo:0 192.168.9.27/32 broadcast 192.168.9.27 up

[root@node2 ~]#route add -host 192.168.9.27 dev lo:0

作业:nat模型实现http和https两种负载均衡集群

       ssl:

              RS:都要提供同一个私钥和同一个证书;

       dr模型实现mysql负载均衡

       扩展:实现VIP和RIP不在同一网段

          day30(LVS进阶)

.           一

lvs使用打标记的方法实现负载均衡

介绍:在数据到达mangle的PREROUTING的时候,将前往目标ip为VIP 的数据打上标记,然后使用ipvsadm过滤标记然后发往readl serer即可

 

iptables 打标记

  1. 为目标ip为192.168.80.7的80端口的数据打上10标记

                     iptables -t mangle -A PREROUTING -d 192.168.80.7 -p tcp --dport 80 -j MARK --set-mark 10

  1.  

ipvsadm捕获iptables 打的标记

       ipvsadm -A -f 10 -s rr              # 添加标记为10的VIP,设置调度算法为rr

 

 

 

负载均衡HTTPS

(1)    搭建证书服务器(请参考前边做过的证书服务器)

(2)    申请证书
[root@node1 httpd]#(umask 600;mkdir /etc/httpd/ssl; openssl genrsa -out /etc/httpd/ssl/web.key 512; )   # 生成证书秘钥

[root@node1 httpd]#openssl req -new -key /etc/httpd/ssl/web.key -out /etc/httpd/ssl/web.csr         # 生成证书的申请文件

[root@node1 httpd]#scp /etc/httpd/ssl/web.csr 192.168.9.72:            # 发往证书服务器

[root@C7_2 ~]#openssl ca -in web.csr -out /etc/pki/CA/newcerts/web.crt -days 3650    # 授权

[root@C7_2 ~]#scp /etc/pki/CA/newcerts/web.crt 192.168.9.51:/etc/httpd/ssl         # 生成的证书返回给客户端

[root@node1 ~]#scp -rp ssl 192.168.9.61:/usr/local/nginx/          # 将证书发给另一台real server

       后边就是web站点调用证书,不做过多介绍

(3)    director的配置
[root@C7_1 CA]#iptables -t mangle -A PREROUTING -d 192.168.80.7 -p tcp --dport 443 -j MARK --set-mark 10

[root@C7_1 CA]#ipvsadm -A -f 10 -s rr

[root@C7_1 CA]#ipvsadm -a -f 10 -r 192.168.9.51

[root@C7_1 CA]#ipvsadm -a -f 10 -r 192.168.9.61

[root@C7_1 CA]#ipvsadm –ln

 

.           二

session保持   

       session绑定:lvs sh算法

              对某一特定服务

       session 复制

       session服务器

 

lvs persistence:lvs的持久连接

       功能:无论ipvs使用何种调度方法,其都能实现将来自于同一client的请求始终定向至第一次调度时选出的RS;

              持久连接模板:独立于算法

                     sourceip rs timer

             

持久连接的实现方式

每端口持久:PPC(persistence port connect),单服务持久调度,每个服务一个real server

              ipvsadm –A –t $VIP:port –s rr –p 300         # -p指定持久连接,300是300秒,默认为360秒

              ipvsadm –a –t $VIP:port –r %RIP:port –g

每FWM持久:PFWMC(Persistence FireWall MARK connect ),只要标记相同,director将该标记的所有服务定义至同一real server

              ipvsadm –A –f 10 –s rr –p 3660

              ipvsadm –a –f 10 –r $RIP -g

       每客户端持久:PCC(Persistence Client connect),单客户端持久,用户所有服务请求调用后端的单个real server

              ipvsadm –A –t $VIP:0 –s rr –p 300              # 设置为0,即为所有端口

ipvsadm –a –t $VIP:0 –r %RIP –g

 

HA:

       SPOF:Single Point of Failure

 

      director:高可用群集

       real server:让director对其进行健康状态检测,并且根据检测的结果自动完成添加或移除管理功能

  1. 基于协议的检测

                     ip:icmp

                     传输层:检测端口的开放状态

                     应用层:请求获取关键性资源

  1. 检查频度

 

  1. 状态判断
    下线:OK à failure à failure à failure
    上线:failure à ok à ok à
  2. back server

自己写一个自动检测脚本

 

          day31(Nginx)

.           一

.           二、(proxy)

ngx_http_proxy_module模块

      

location / {

    proxy_pass       http://localhost:8000;                # 后端服务器

    proxy_set_header Host      $host;                    # 发送客户端请求的url

    proxy_set_header X-Real-IP $remote_addr;              # 发送给后端客户端的IP地址

}

 

特殊场景

在使用模式匹配的时候,不需要为后端服务器指定路径,模式匹配会将访问的路径传向后端服务器

 在rewrite的时候,后边的地址不会匹配

 

proxy

       proxy_set_header X-Real-IP $remote_addr;       # 将#remote_addr转发到后端服务器

proxy cache

       proxy_cache_path /cache/nginx/ levels=1:1 keys_zone=mycache:32m;

缓存存放的目录为/cache/nginx

levels 1:1      一级缓存使用一个字符表示,二级缓存使用一个字符表示

keys_zone=mycache:32m     mycache是zone的名字,大小是32m

inactive:非活动期限

       调用cache

proxy_cache mycache;             # 可以写在被代理的的location等,使用的macache,就是在上边定义的zong

proxy_cache_valid 200 1d;        # 如果状态结果是200,缓存1天   

proxy_cache_valid 301 302 10m;           # 301 302代码缓存10分钟

proxy_cache_valid any 1m;                    # any所有的缓存1分钟

proxy_cache_use_stale error timeout http_500 http_502;              # 那种场景中可以使用过期缓存

       查看,当配置完成后,重启之后,使用客户端访问nginx代理服务器
       其他配置

              proxy_commect_timeout:proxy连接后端服务器的超时时间

add_header Nginx-Cache "$upstream_cache_status";   # 可以添加一个抱头,命中则会显示HIT

              proxy_hide_header:隐藏头部,proxy收到后端服务器的内容,构建内容给客户端时,不打算设置的首部

              proxy_cache_method:只对那些方法获取的资源缓存,默认是get和head

              proxy_cache_bypass string:这是在何种情况下nginx将不从cache取数据

             

upstream模块(只能定义在HTTP区块中)

格式

upstream backend {

    server backend1.example.com       weight=5;     # 权重为5

    server backend2.example.com:8080;

    server unix:/tmp/backend3;

 

    server backup1.example.com:8080   backup;    # 备用

    server backup2.example.com:8080   down;      # 标记为不可用

}

 

server {

    location / {

        proxy_pass http://backend;

    }

}

 

 

iphash

    upstream node_all{

        ip_hash;         # 定义轮询算法                                                              

        server 192.168.9.51:80 weight=2;

        server 192.168.9.61:80;

    }

 

后端服务器检测

    upstream node_all{

        server 192.168.9.51:80 max_fails=2 fail_timeout=1;       # max_fails 失败重试次数,fail_timeout每次的超时时间

        server 192.168.9.61:80 max_fails=2 fail_timeout=1;                                    

    }

 

 

 

.           三

ip_hash的缺点:多个局域网主机组SNAT,会将这些主机认为是同一台主机

基于sticky实现session绑定

       cookie:

              sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];

       route

              sticky route $variable ...;

       learn 

         sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];

 

least_conn:最少连接的调度算法

health_check:健康状态监测

       可以专门访问后端服务器的某个资源进行访问检测

       interval=time            # 设置健康状态监测时间,默认5秒

       fails=number            # 失败多少次定义为无法连接,默认一次

       passes=number        # 多少成功连接,将其定义为可连接的后端服务器,默认一次

http {

    server {

    ...

        location / {

            proxy_pass http://backend;

            health_check match=welcome;

        }

    }

 

    match welcome {

        status 200;

        header Content-Type = text/html;

        body ~ "Welcome to nginx!";

    }

}

 

 

自定义响应头部

add_header X-via $server_addr;

add_header X-Cache $upstream_cache_status;            # 添加返回代理HIT代表命中了缓存,MISS代表没命中缓存

 

 

fastcgi module

LNMP

php

[root@C7_1 php]#yum install php-fpm # 安装php-fpm

[root@C7_1 php]#systemctl start php-fpm # 启动

[root@C7_1 ~]#vim /etc/nginx/nginx.conf

        location ~ \.php$ {

                root html;

                fastcgi_pass 127.0.0.1:9000;         # 反向代理的位置

                fastcgi_index index.php;               # 主页

                fastcgi_param SCrIPT_FILENAME /scripts$fastcgi_script_name;        # 向后端传递的参数

                include fastcgi.conf;

        }

[root@C7_1 ~]#vim /usr/share/nginx/html/index.php

<?php

        phpinfo();

?>

[root@C7_1 ~]# systemctl restart nginx php-fpm

然后访问即可

MySQL

[root@C7_1 ~]#yum install php-mysql

[root@C7_1 ~]#systemctl restart nginx php-fpm

[root@C7_1 ~]#yum install mariadb-server.x86_64

[root@C7_1 ~]#vim /usr/share/nginx/html/index.php

<?php

        #phpinfo();                                                              

        $conn = mysqli_connect('127.0.0.1','root','');

        if ($conn)

                echo success;

        else

                echo faile;

?>

       [root@C7_1 ~]# systemctl restart nginx php-fpm mariadb.service

然后访问即可

 

fastcache

[root@C7_1 ~]#vim /etc/nginx/nginx.conf

       # http区段定义

    fastcgi_cache_path /cache/fastcgi levels=1:1 keys_zone=fcgicache:10m interactive=3m max_size=1g; 

          和cache的选项意思一样

          interactive=3m      # 非活动时间3分钟

          max_size=1g                    #  最大空间1g

fastcgi_cache_key $request_uri;  # 该指令用来设置Web缓存的Key值,Nginx根据Key值MD5缓存。一般根据host(域名),host(域名),request_uri(请求的路径)等变量组合成fastcgi_cache_key。

下边的在location中定义

fastcgi_cache fcgicache;

fastcgi_cache_valid 200 10m;

fastcgi_cache_valid 302 3m;

fastcgi_cache_valid any 1m;

[root@C7_1 ~]#ab -n 2000 -c 100 http://192.168.9.71/index.php   #  压力测试,测试缓存与没缓存的区别

 

 

.           四

一个完整配置例(生产环境中使用)

 

user                              nobody nobody;

worker_processes                  4;

worker_rlimit_nofile              51200;

 

error_log                         logs/error.log  notice;

 

pid                               /var/run/nginx.pid;

 

events {

  use                             epoll;

  worker_connections              51200;

}

 

http {

  server_tokens                   off;

  include                         mime.types;

 

  proxy_redirect                off;

  proxy_set_header              Host $host;

  proxy_set_header              X-Real-IP $remote_addr;

  proxy_set_header              X-Forwarded-For $proxy_add_x_forwarded_for;

  client_max_body_size          20m;

  client_body_buffer_size       256k;

  proxy_connect_timeout         90;

  proxy_send_timeout            90;

  proxy_read_timeout            90;

  proxy_buffer_size             128k;

  proxy_buffers                 4 64k;

  proxy_busy_buffers_size       128k;

  proxy_temp_file_write_size    128k;

 

  default_type                    application/octet-stream;

  charset                         utf-8;

 

  client_body_temp_path           /var/tmp/client_body_temp 1 2;

  proxy_temp_path                 /var/tmp/proxy_temp 1 2;

  fastcgi_temp_path               /var/tmp/fastcgi_temp 1 2;

  uwsgi_temp_path                 /var/tmp/uwsgi_temp 1 2;

  scgi_temp_path                  /var/tmp/scgi_temp 1 2;

 

  ignore_invalid_headers          on;

  server_names_hash_max_size      256;

  server_names_hash_bucket_size   64;

  client_header_buffer_size       8k;

  large_client_header_buffers     4 32k;

  connection_pool_size            256;

  request_pool_size               64k;

 

  output_buffers                  2 128k;

  postpone_output                 1460;

 

  client_header_timeout           1m;

  client_body_timeout             3m;

  send_timeout                    3m;

 

 

  log_format main                 '$server_addr $remote_addr [$time_local] $msec+$connection '

                                  '"$request" $status $connection $request_time $body_bytes_sent "$http_referer" '

                                  '"$http_user_agent" "$http_x_forwarded_for"';

 

  open_log_file_cache               max=1000 inactive=20s min_uses=1 valid=1m;

 

  access_log                      logs/access.log      main;

  log_not_found                   on;

 

 

  sendfile                        on;

  tcp_nodelay                     on;

  tcp_nopush                      off;

 

  reset_timedout_connection       on;

  keepalive_timeout               10 5;

  keepalive_requests              100;

 

 

  gzip                            on;

  gzip_http_version               1.1;

  gzip_vary                       on;

  gzip_proxied                    any;

  gzip_min_length                 1024;

  gzip_comp_level                 6;

  gzip_buffers                    16 8k;

  gzip_proxied                    expired no-cache no-store private auth no_last_modified no_etag;

  gzip_types                      text/plain application/x-javascript text/css application/xml application/json;

  gzip_disable                    "MSIE [1-6]\.(?!.*SV1)";

 

 

  upstream tomcat8080 {

    ip_hash;

 

    server                        172.16.100.103:8080 weight=1 max_fails=2;

    server                        172.16.100.104:8080 weight=1 max_fails=2;

    server                        172.16.100.105:8080 weight=1 max_fails=2;

  }

 

  server {

    listen                        80;

    server_name                   www.magedu.com;

    # config_apps_begin

    root                          /data/webapps/htdocs;

    access_log                    /var/logs/webapp.access.log     main;

    error_log                     /var/logs/webapp.error.log      notice;

 

    location / {

   

      location ~* ^.*/favicon.ico$ {

        root                      /data/webapps;

        expires                   180d;

        break;

      }

   

      if ( !-f $request_filename ) {

        proxy_pass                http://tomcat8080;

        break;

      }

    }

 

    error_page                    500 502 503 504  /50x.html;

      location = /50x.html {

      root                        html;

    }

  }

 

  server {

    listen                        8088;

    server_name                   nginx_status;

 

      location / {

          access_log                  off;

          deny                        all;

          return                      503;

      }

 

      location /status {

          stub_status                 on;

          access_log                  off;

          allow                       127.0.0.1;

          allow                       172.16.100.71;

          deny                        all;

      }

  }

 

}

 

 

 

 

 

          day32(Keepalived)

.           一

Keepalived高可用

       Active/Passive

 

vrrp: Virtual Router Redundancy Protocol

keepalived

       keepactived基于vrrp协议

       能顾根据配置文件自动生成ipvs规则

       对各RS做健康状态监测(health check)

       组件

              vrrp stack

              checkers

              IPVS wrapper à ipvs

       配置文件组成部分

              GLOBAL CONFIGURATTION

              VRRPD CONFITURATION

                     vrrp instance

                     vrrp synchoniation

              LVS CONGIGURATION

.           二

HA Cluster  配置前提:

1、        本机的主机名与hosts中保持一直,要与hostname(uname -n)获得的主机名保持一致,各节点能互相解析主机名

2、        各节点时间同步

3、        确保iptables 及其 selinux 不会成为服务的阻碍

 

GLOBAL CONFIGURATTION

global_defs {

   notification_email {

        root@p-pp.cn                      # 当出现问题时,给谁发邮箱的邮箱

   }

     notification_email_from keepadmin@p-pp.cn              # 发送者的邮箱

      smtp_server 127.0.0.1             # smtp server的地址

      router_id C7-1.p-pp.cn        # route id 建议使用主机名

      vrrp_mcast_group4 224.0.0.71                    # ipv4的组播地址

VRRPD CONFITURATION

       vrrp_instance VI_1 {                 # VI_1是实例名称,多个不能一样

    state BACKUP                         # 初始状态

    interface eth0                         # 虚拟ip定义到那个接口

    virtual_router_id 51                # 虚拟的id好,每组要唯一,一般0-255

    priority 99                               # 优先级,0-255

    advert_int 1                             # 通告周期时间

    authentication {                      # 周期信息的认证

        auth_type PASS              # 认证类型,也可以使用md5

        auth_pass 1111              # 密码

        virtual_ipaddress {          # 虚拟ip

        <IPADDR>/<MASK> brd <IPADDR>  dev  <STRING>  scope  <SCOPE>  label<LABEL>

        192.168.200.17/24 dev eth1        # ip配置的网卡

        192.168.200.18/24 dev eth2 label eth2:1               # label指定网卡的别名

         }

    }

怎么不重启降低优先级

       [root@C7_1 ~]#vim /etc/keepalived/keepalived.conf

       定义在vrrp_instance外

              vrrp_script chk_file {         # chk_file是脚本的名字

        script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"                    # 检查/etc/keepalived/down这个文件

        interval 1           # 多少秒检查

        weight -2          # 减小多少优先级

}

       定义在vrrp_instance内

    track_scrip {

        chk_file             # 调用上边定义的脚本名字

    }                  

 

同步组

   vrrp_sync_group VG_1 {

    group {

    inside_network   # name of the vrrp_instance (see below)

    outside_network  # One for each movable IP

     ...

   }

LVS

A:real server 1

       eth0:192.168.9.51

       lo:0:192.168.9.10

B:real server 2

       eth0:192.168.9.61

       lo:0:192.168.9.10

C:keepalived + LVS

       eth0:192.168.9.71

D:keepalived + LVS

       eth0:192.168.9.72

步骤一:给real server 设置

[root@C7_1 day22]#cat setLVSreal.sh

#!/bin/bash

case $1 in

start)

        echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

        echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

        echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

        echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce

        ip addr add 192.168.9.10/32 dev lo label lo:0 broadcast 192.168.9.10

        ip route add 192.168.9.10/32 dev lo:0

        ;;

stop)

        echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore

        echo 0 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

        echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce

        echo 0 > /proc/sys/net/ipv4/conf/eth0/arp_announce

        ip addr del 192.168.9.10/32 dev lo label lo:0 broadcast 192.168.9.10

        ;;

esac

[root@C7_1 day22]#ansible 192.168.9.51,192.168.9.61 -m script -a 'setLVSreal.sh start'

步骤二:搭建keepalived的real_server

 

C:

[root@C7_1 ~]#cat /etc/keepalived/keepalived.conf                     # 修改后的配置文件

! Configuration File for keepalived                                                                             

 

global_defs {

   notification_email {

     root@C7-1.p-pp.cn

   }

   notification_email_from

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

   vrrp_skip_check_adv_addr

   vrrp_strict

   vrrp_garp_interval 0

   vrrp_gna_interval 0

}

vrrp_script chk_weight {

    script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"                     # 这里尽量用脚本

    interval 1

    weight -2

}

 

vrrp_instance VI_1 {

    state MASTER

    interface eth0

    virtual_router_id 51

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass e4b2c876f806

    }

    virtual_ipaddress {

        192.168.9.10/32 dev eth0 label eth0:0

    }

    track_script {

        chk_weight

    }

 

    notify_master "/etc/keepalived/notify.sh master"         # 邮件

    notify_backup "/etc/keepalived/notify.sh backup"

    notify_fault "/etc/keepalived/notify.sh fault"

}

virtual_server 192.168.9.10 80 {           # 第一个实例ip和监听的端口

    delay_loop 6                    # 失败转几圈

    lb_algo wrr                       # 算法rr、wrr、lc、wlc、lblc、sh、dh

lb_kind DR                       # 模式NAT、DR、TUN

    nat_mask 255.255.255.255    # 子网

    persistence_timeout 50         # 持久保持时间50秒,就是LVS的保持时间,ipvsadm -A -t IP -s rr -p 50

    protocol TCP

   

    real_server 192.168.9.51 80 {

        weight 1

        HTTP_GET {                     # 使用http_get验证后端服务器,除此之外,还有ssl_check、tcp_check

            url {

              path /

              status_code 200                # 验证状态返回码,如果是200,则为成功过

!              digest ff20ad2481f97b1754ef3e12ecd3a9cc           # 可以使用mad5的值验证,前边的!是将此行注释

            }

            connect_timeout 3      # 连接超时时间

            nb_get_retry 3                       # get重试次数

            delay_before_retry 3           # 延迟重试时间

    real_server 192.168.9.61 80 {

        weight 2

        HTTP_GET {

            url {

              path /

              status_code 200

!              digest ff20ad2481f97b1754ef3e12ecd3a9cc

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

[root@C7_1 ~]#cat /etc/keepalived/notify.sh                  # 配置邮件相关的脚本

#!/bin/bash

# description: An example of notify script

#

vip=192.168.9.10

contact='root@localhost'

 

notify() {

    mailsubject="`hostname` to be $1: $vip floating"

    mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"

    echo $mailbody | mail -s "$mailsubject" $contact

}

 

case "$1" in

    master)

        notify master

        exit 0

    ;;

    backup)

        notify backup

        exit 0

    ;;

    fault)

        notify fault

        exit 0

    ;;

    *)

        echo 'Usage: `basename $0` {master|backup|fault}'

        exit 1

    ;;

esac

 

[root@C7_1 ~]#chmod +x /etc/keepalived/notify.sh

[root@C7_1 ~]#scp /etc/keepalived/notify.sh /etc/keepalived/keepalived.conf 192.168.9.72:/etc/keepalived            # 复制后更改state 、priority

[root@C7_1 ~]#tcpdump -i eth0 -nn host 192.168.9.72         # 抓包查看组播发送的存活信息和健康状态监测

 

步骤三:搭建Sorry_server

 

virtual_server 192.168.9.10 80 {           # 在virtual_server 中指定

       ……

    sorry_server 127.0.0.1 80

       ……

}

TCP-check健康状态监测

       修改real_server检测方法就行

           real_server 192.168.9.51 80 {

        weight 1

        TCP_CHECK {

            }

        }

.           四

HA servers:Nginx

步骤一:做好nginx的upstream,和location调用proxy_pass

步骤二:配置keepalived,加入以下内容

      

 

双主模型

          day34(corosync)

.           一(43)

可用性计算

A(可用性)=MTBF/(MTBF+MTTR)

       MTBF(平均无故障时间):Meean Time Between Failure

       MTTR(平均修复时间):Mean Time To Repair

0<A<1;90%,95%,99%,99.9%,99.99%,99.999%

 

 

 

 

 

vote system 投票系统

       隔离:

              STONITH:shoot the other node on the head 节点级别隔离

              Fence:资源级别的隔离

 

资源约束性

       位置约束:资源对节点的倾向性

       排列约束:资源彼此间是否能运行于统一节点的倾向性

       顺序约束:多个资源启动顺序依赖关系

偶数节点

       Ping node

       qdisk

 

 

层次的各个组件

       Messaging layer(信息管理层):

              heartbeat

                     v1

                     v2

                     v3

              corosync

              cman

       Cluster Resource Manager(CRM)

              heartbeat v1 heartsource

              heartbeat v2 crm

              heartbeat v3,pacemaker

              rgmanager

              组和方式

heartbeat v1 (heartsources)

heartbeat v2 (crm)

heartbeat v3 + pacemaker

corosync + pacemaker

   cocosync v1 + pacemaker (plugin)

   corosync v2 + pacemaker (standlone service)

cman + rgmanager

corosync v1 + cman + pacemaker

 

RHCS:Red Het Cluster Suite

   Rhel5:

cman + rgmanager + conga (ricci/luci)

   Rhel6:

          cman + rgmanager + conga (ricci/luci)

          corosync + pacemaker

          corosync + cman + pacemaker

Rhel7:corosync + pacemaker

       Resource Agent:

              service

              LSB

              OCF

              STONITH

              Systemctl

.           二

约束:score

       位置约束:资源对节点倾向性

              (-oo,+oo)

                     任何值+无穷大=无穷大

                     任何值+负无穷大=负无穷大

                     无穷大+负无穷大=负无穷大

       排列约束:资源笔记间是否能运行同一节点的倾向性

       顺序约束:多个资源启动顺序依赖关系

 

安装配置

       Centos 7:corosync + pacemaker

              corosync v2:vote system

              pacemkaer:独立服务

       集群全生命周期管理工具

              pcs

              crmsh

       配置集群前提

(1)   时间同步

(2)   基于当前正在运行的主机名互相访问

(3)   是否用到仲裁设备

配置:

              [root@C7-1 ~]#yum install pcs -y

       [root@C7-1 ~]#ansible C7 -m service -a 'name=pcsd enabled=yes state=started'

       [root@C7-1 ~]#ansible C7 -m shell -a 'echo "xuan" | passwd --stdin hacluster'

              [root@C7-1 ~]#pcs cluster auth C7-1 C7-2 -u hacluster

              [root@C7-2 ~]#pcs cluster setup --name mycluster C7-1 C7-2

              [root@C7-1 corosync]#pcs cluster start --all

              [root@C7-1 corosync]#corosync-cfgtool -s

Printing ring status.

Local node ID 1

RING ID 0

        id      = 192.168.9.71

        status  = ring 0 active with no faults     # no faults 没有失败

       [root@C7-2 etc]#corosync-cmapctl         # 可以查看很多群集过程

       [root@C7-2 etc]#pcs status                       # 查看状态

      WARNING: no stonith devices and stonith-enabled is not false       # 没有设备stonith,但是却开启了stonith

      Current DC: C7-1             # DC是所有节点选举出来的用来做全集集群事物角色的节点

[root@C7-2 etc]#pcs property list --all | grep  stonith-enabled          # 查看stonith是否开启

       [root@C7-2 etc]#crm_verify -L –V      # 查看报的错误

                 error: unpack_resources:     Resource start-up disabled since no STONITH resources have been defined

   error: unpack_resources:     Either configure some or disable STONITH with the stonith-enabled option

   error: unpack_resources:     NOTE: Clusters with shared data need STONITH to ensure data integrity

Errors found during check: config not valid

       [root@C7-2 etc]#pcs property set  stonith-enabled=false           # 关闭 stonith

      

 

          day35(Haproxy)

.           一

.           二

web arch:haproxy

       mode:http,tcp(https,MySQL)

HAProxy

代理(http):掮客(broker):中间人,一手托两家

正向代理

反向代理

 

代理作用:web缓存(加速)、反向代理、内容路由(根据流量及内容类型等将请求转发至特定服务器 )、转码器;

在代理服务器添加Via首部

 

缓存的作用:

减少冗余内容传输;

节省带宽、缓解网络瓶颈

              降低了对原始服务期的请求压力

              降低了传输延迟

 

       Haproxy:只是http的反向代理,不提供缓存代理功能:但额外支持对tcp层对基于tcp通信的应用做LB

              HAProxy实现了一种事件驱动单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。

安装:

[root@C7-2 ~]#yum install -y haproxy    # 安装

[root@C7-2 ~]#cp /etc/haproxy/haproxy.cfg{,.bak}  # 备份控制文件

 

 

haproxy:

frontend:前端

   use_backend

   default_backend   websrv1 # 默认的后端服务器为websrv1

backend websrv1:后端服务器,名字为websrv1

   use_backend

   server

   server

 

listen:    相当于frontend 和 backend的结合

   server

default

配置文件:haproxy.cfg

       全局配置

   代理配置:frontend、backend、listen、default

 

示例

#---------------------------------------------------------------------

# main frontend which proxys to the backends

#---------------------------------------------------------------------

frontend  main *:80

    default_backend             websrvs

 

#---------------------------------------------------------------------

# static backend for serving up images, stylesheets and such

#---------------------------------------------------------------------

backend websrvs

    balance     roundrobin

    server web1 10.244.1.72:80 check

    server web2 10.244.1.73:80 check

.           三

代理参数

       balance:指明调度算法

              动态:权重可动态调整

              静态:调整权重不会实时生效

             

roundrobin:轮询,动态算法,每个后端最多支持4128个链接;

static-rr:静态轮询,每个后端主机不限量

leastconn:新的链接被派发给目前链接的最少的后端服务器

source:

  hash-type

         map-based:取模法;静态

         consistent:一致性哈希;动态

        backend websrvs

    balance     source

uri

  hash-type

         map-based

         consitent

backend websrvs

    balance     uri

    hash-type    consistent

       url_param

  hash-type

         map-based

         consitent

       hdr(name) 对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索

  hash-type

         map-based

         consitent

backend websrvs

    balance     hdr(User-Agent)

    hash-type    consistent

[root@C7-1 ~]#curl -A "Xuan" 192.168.9.72  # -A 可以修改User-Agent

 

bind:只能用于frontend,listen;

       frontend  main

    bind *:80

    bind *:9205

 

 

mode {tcp | http | health}

       Haproxy的工作模式,默认为tcp

log

log global

log <address> <facility> [<level> [<minlevel>]]

为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数,不过,如果使用了“log global”且"global"段已经定了两个log参数时,多余了log参数将被忽略。

 

maxconn

maxconn <conns>

35   03   1.05

 

 

maxqueue <maxqueue>:请求队列的最大长度

 

observe <mode>:默认禁用,动态只能判断后端server的健康状态

 

weight <weight>:指定权重,默认为1,最大256, 0则表示不调度

 

redirect <prefix>:启用重定向,均已302相应

       server srv1 192.168.100.1:80 redir http//:www.p-pp.cn check

 

检测方法

option httpchk

option httpchk <uri>

option httpchk <method> <uri>

option httpchk <method> <uri> <version>:不能用于frontend段,例如:

 

       backend https_relay

              mode tcp

              oprion httpchk OPTIONS * HTTP/1.1 \r\nHost:\ www.p-pp.cn

              server apache1 192.168.9.71:443 check port 80

 

.           四

基于cookie实现

backend websrvs

    balance    roundrobin

    cookie SERVERID insert nocache indirect

    server web1 192.168.9.71:80 check weight 1 cookie xuan_sr1

    server web2 192.168.9.72:81 check weight 3 cookie xuan_sr2

[root@C7-2 ~]#curl -I 192.168.9.72       

Set-Cookie: SERVERID=xuan_sr2; path=/

 

 

haproxy的状态信息

最简单的,这样会被别人看到重要信息

listen statistics

    bind *:9206   #绑定到80端口,其他区段非必需

    stats enable  #开启功能

 

 

 

密码登录

listen statistics

    bind *:9206

    stats enable

    stats hide-version   #隐藏版本号

    stats scope .   #启用统计报告并限定报告的区段

    stats uri /haproxy?xuan   #入口URL

    stats realm "Haproxy\ Statistics"

    stats auth xuan1:xuan1   #用户名、密码

    stats auth xuan2:xuan2   #用户名、密码

 

 

 

开启管理员

listen statistics

    bind *:9206

    stats enable

    stats hide-version

    #stats scope .

    stats uri /haproxy?xuan

    stats realm "Haproxy\ Statistics"

    stats auth xuan1:xuan1

    stats auth xuan2:xuan2

stats admin if TRUE

 

 

向日志记录额外信息:

       capture request header

       capture response header

 

记录真实请求者的IP地址

option forwardfor       except 127.0.0.0/8                # 在全局配置中已经定义

 

nginx:

         log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                     '$status $body_bytes_sent "$http_referer" '

                     '"$http_user_agent" "$http_x_forwarded_for"';

       apache:

                     LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

 

错误页面重定向:

       errorfile:使用haproxy主机本地文件进行响应

       errorloc,errorloc302:使用制定的url进行响应响应码为302;不适用GET以为的其它请求方法

       errorloc303:返回303状态码;

 

自定义请求或响应报文首部

       reqadd

       rspadd

 

.           五、ACL

blick阻塞

       192.168.9.1用户访问stats状态界面,并显示错误网页

    acl xuan1 src 192.168.9.1     # 定义ACL 名字为xuan1,并指定源地址为192.168.9.1

    block if xuan1    # 阻止ACLxuan1

errorloc 403 http://www.p-pp.cn   # 错误重定向到其他网站

    stats enable

    stats hide-version

    stats uri /haproxy?xuan

    stats realm "Haproxy\ Statistics"

    stats auth xuan1:xuan1

    stats auth xuan2:xuan2

stats admin if TRUE

 

 

相关参数

        acl allowstats src 172.16.251.196
        # http-request allow if allowstats  \\允许allowstats中的IP访问stats状态界面
        http-request deny  unless allowstats \\除了allowstats之外全部拒绝访问,即仅允许allowstats访问
        # http-request deny if allowstats \\拒绝allowstats访问
        errorloc 403 http://172.16.253.108:10080/403.html \\错误网页文件

 

haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义ACL,即定义一个测试条件,而后在条件得到满足时执行某特定的动作,如阻止请求或转发至某特定的后端。定义ACL的语法格式如下。


acl <aclname> <criterion> [flags] [operator] [<value>] ...

这样一条语句建立了一个acl 测试;
这些测试应用在请求或响应中被"标准"< criterion > 部分所指定的内容,而且可以指定[ flags] 进行特性调整,有些< criterion > 支持操作符[operator] 进行运算,同时一些转换格式的关键字可以跟在< criterion >后面,使用" , "隔开。而值[< value >] 要求被
< criterion > 所支持的数据形式,多个值使用空格分隔。
< criterion > 通常是指获取样本方法的名称。使用一个获取样本方法,暗含着其输出样本的类型,类型是以下列出的一种:

  • boolean
  • integer (signed or unsigned)
  • IPv4 or IPv6 address
  • string
  • data block

ACL引擎匹配数据使用的模式类型如下:

  • boolean
  • integer or integer range
  • IP address / network
  • string (exact, substring, suffix, prefix, subdir, domain)
  • regular expression
  • hex block

ACL flags 可用列表如下:

  • -i : 忽略大小写
  • -f filename : 从文件中载入模式
  • -m method : 指定模式匹配方法
  • -n : 禁止DNS解析
  • -M : -f 载入的文件作为映射文件使用
  • -u : 强制ACL的名称唯一
  • -- : 强制结束flag结束,避免了字符串中含有的- 引起混淆

其中flag中的 -m 选项可使用的模式匹配方法如下,需要说明的是有些方法已被默认指定无需声明,例如int,ip

  • "found" : 只是用来探测数据流中是否存在指定数据,不进行任何比较
  • "bool" : 检查结果返回布尔值。匹配没有模式,可以匹配布尔值或整数,不匹配0和false,其他值可以匹配
  • "int" : 匹配整数类型数据;可以处理整数和布尔值类型样本,0代表false,1代表true
  • "ip" : 匹配IPv4,IPv6地址类型数据。该模式仅被IP地址兼容,不需要特别指定
  • "bin" : 匹配二进制数据
  • "len" : 匹配样本的长度的整数值
  • "str" : 精确匹配,根据字符串匹配文本
  • "sub" : 子串匹配,匹配文本是否包含子串
  • "reg" : 正则匹配,根据正则表达式列表匹配文本
  • "beg" : 前缀匹配,检查文本是否以指定字符串开头
  • "end" : 后缀匹配,检查文本是否以指定字符串结尾
  • "dir" : 子目录匹配,检查部分文本中以" / "作为分隔符的内容是否含有指定字符串
  • "dom" : 域匹配。检查部分文本中以" . "作为分隔符的内容是否含有指定字符串

5.1 常用的测试标准(criteria)

5.1.1 be_sess_rate

be_sess_rate(backend) <integer>

用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件;常用于在指定backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。例如:

backend dynamic

mode http

acl being_scanned be_sess_rate gt 50

redirect location /error_pages/denied.html if being_scanned

 

5.1.2 fe_sess_rate

fe_sess_rate(frontend) <integer>

用于测试指定的frontend(或当前frontend)上的会话创建速率是否满足指定的条件;常用于为frontend指定一个合理的会话创建速率的上限以防止服务被滥用。例如下面的例子限定入站邮件速率不能大于50封/秒,所有在此指定范围之外的请求都将被延时50毫秒。

ontend mail

bind :25

mode tcp

maxconn 500

acl too_fast fe_sess_rate ge 50

tcp-request inspect-delay 50ms

tcp-request content accept if ! too_fast

tcp-request content accept if WAIT_END

 

5.1.3 hdr <string>

hdr(header) <string>

用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close。

hdr(Connection) -i close

 

5.1.4 method <string>

method <string>

测试HTTP请求报文中使用的方法。

5.1.5 path_beg <string>

用于测试请求的URL是否以指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头。

acl url_static path_beg -i /static /images /javascript /stylesheets

5.1.6 path_end <string>

用于测试请求的URL是否以<string>指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾。

 

acl url_static path_end -i .jpg .gif .png .css .js

5.1.7 hdr_beg <string>

用于测试请求报文的指定首部的开头部分是否符合<string>指定的模式。例如,下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp。

 

acl host_static hdr_beg(host) -i img. video. download. ftp.

5.1.8 hdr_end <string>

用于测试请求报文的指定首部的结尾部分是否符合<string>指定的模式

 

 

          day36(varnish)

.           一、WEB缓存

key-value存储

命中率:hit/(hit + miss)

       文档命中率:从文档个数进行衡量

       自己命中率:从内容大小进行衡量

 

缓存处理的步骤

       接受请求 à 解析请求 (提取请求的URL及各种首部) à 查询缓存 à 新鲜度检测 à 创建响应报文本 à 发送响应 à 记录日志

 

新鲜度检测机制(用于检测缓存内容是否过期)

       过期日期

              HTTP/1.0 Expires

.           二、varnish(基础应用)

web-cache

       varnish、squid

 

varnish官网:http://varnish-cache.org/

 

管理进程:编译VCL并应用新配置;监控varnish:初始化varnish;CLI接口

Child/cache

       Acceptor:接受新的连接请求

       worker threads:处理用户请求

       Expiry:清理缓存中的过期对象;

 

日志:Shard Memory Log,共享内存日志大小一般为90MB,分为两部分,前一部分为计数器,后一部分为请求的内容

 

vcl:varnish Configuration Language

       缓存策略配置接口

       基于 “域”的简单编程语言;

 

内存分配和回收

       malloc(),free()

 

varnish如何存储对象:

       file:单个文件;不支持持久机制

       malloc:内存

       persistent:基于文件持久性存储

 

配置varnish

1、varnishd应用程序的命令行参数            (定义varnish主程序的工作特性)

       监听的socket,使用存储类型等等:额外的配置参数

              -p param=value

              -r param,param,...:设定只读参数列表

       2、-p选项指明的参数                               (定义varnish各子进程或线程的工作特性)

              运行时参数

                     可在程序运行中,通过气CLI进行配置

       3、vcl:配置缓存系统的缓存机制                   (指明线程中的缓存特性)

              通过vcl配置文件进行配置

                     先编译,后应用,依赖于C编译器

# 查看参数文件

[root@C7-1 xuan]#cat /etc/varnish/varnish.params

# Varnish environment configuration description. This was derived from

# the old style sysconfig/defaults settings

 

# Set this to 1 to make systemd reload try to switch VCL without restart.

RELOAD_VCL=1

 

# Main configuration file. You probably want to change it.

VARNISH_VCL_CONF=/etc/varnish/default.vcl

 

# Default address and port to bind to. Blank address means all IPv4

# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted

# quad, or an IPv6 address in brackets.

# VARNISH_LISTEN_ADDRESS=192.168.1.5

VARNISH_LISTEN_PORT=6081    # 访问端口

 

# Admin interface listen address and port

VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1

VARNISH_ADMIN_LISTEN_PORT=6082   # 管理端口

 

# Shared secret file for admin interface

VARNISH_SECRET_FILE=/etc/varnish/secret

 

# Backend storage specification, see Storage Types in the varnishd(5)

# man page for details.

VARNISH_STORAGE="malloc,256M"

#VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,256M"

 

# User and group for the varnishd worker processes

VARNISH_USER=varnish

VARNISH_GROUP=varnish

 

# Other options, see the man page varnishd(1)

#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"

 

修改后端服务器

[root@C7-1 xuan]#vim /etc/varnish/default.vcl

vcl 4.0;   # 版本

 

# Default backend definition. Set this to point to your content server.

backend default {

    .host = "192.168.9.72";    # 后端服务器ip

    .port = "8080";          # 端口                                                                                                       

}

……

[root@C7-1 xuan]#systemctl start varnish   # 启动后其他主机就可以访问了,默认端口为6081

 

 

varnishadmin

[root@C7-1 xuan]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082    # 连接,默认管理接口只监听在本地的端口

进来之后,可以使用help获取帮助

 

ping   # ping后端服务器

200       

PONG 1560278498 1.0

status    # 查看状态

200       

Child in state running 

vcl.list   # 查看VAL文件

200       

active          0 boot    # 默认只有这一个,启动时加载的

vcl.load test default.vcl   # 加载一个VAL文件,名字为test,文件为default.vcl,相对路径,相对于/etc/varnish

200       

VCL compiled.

vcl.list    #  再次查看,会发现新增加的test

200       

active          0 boot

asd

available       0 test   # 新增加的默认是有效 ,但是并不是active的

vcl.use test   # 使用test的VAL文文件

200       

VCL 'test' now active

vcl.list    # 再次查看,即可发现test已经是active的了

200       

available       0 boot

active          0 test

vcl.use boot

200       

VCL 'boot' now active

vcl.discard test   # 删除test

200       

 

vcl.list    # 再次查看

200       

active          0 boot

 

vcl.show boot   # 查看这个VCL启动前的配置参数

 

 

param.show   # 查看运行时参数

thread_pools               2 [pools] (default)    # 进程的个数

 

param.set thread_pools 4    # 设置运行时参数

param.show thread_pools    # 查看

Value is: 4 [pools]   # 已经设置为4

 

varnish> storage.list    # 查看存储

200       

Storage devices:

        storage.Transient = malloc

        storage.s0 = malloc

 

varnish> backend.list    # 查看后端服务器

200       

Backend name                   Refs   Admin      Probe

default(192.168.9.72,,8080)    1      probe      Healthy (no probe)

ban <field> <operator> <arg> [&& <field> <oper> <arg>]...  # 用于清除缓存

 

log

varnishiog

varnishincsa

Statistics

 varnishstat

Top

 varnishitop

 

.           三

http cache:

       Expires:  缓存后的新鲜度期限,由于各个时区时间不同,后来出现了Cache-Control

       Cache-Control

              max-age:总有限时长

              s-maxage

       Cache-Control:

              no-cache:可以缓存,但是会向上有服务器检测

              no-store:不允许缓存

              must-revalidate:每次客户端访问,必须向上游做有效性校验

      条件式请求

              If-Modified-Since:自从指定了某个时间后是否修改

              If-None-Match:做扩展标签比对

配置

       varnishd进程配置:命令行选项:/etc/varnish/varnish.params

              -p

       varnishd Child/cache:实时参数

              varnishiadm

                     param.set

       缓存功能配置

              vcl(varnish configuration langure)

                     state engine:各引擎之间一定程度上的相关性

                            vcl_recv

                            vcl_hash

                            vcl_hit

                            vcl_miss

                            vcl_fetch

                            vcl_deliver

                            vcl_pipe

                            vcl_pass

                            vcl_error

                     编程语言语法

                            1、 //,#,/* */  用于注释;会被编译器忽略

                            2、 sub $name:用于定义子例程

                                   sub vcl_recv {

 

}

                            3、 不支持循环

                            4、 有众多内置变量,变量可调用位置与state engine有密切相关性

                            5、 支持终止语句,return(action):没有返回值

                            6、 操作符: =、==、~、!、&&、||

 

                            条件判断语句

                            if (CONDTION) {

 

} else {

}

 

                            变量赋值     set name=value

                                                 unset name

                            req.http.heADER:调用erquest报文中http协议指定的HEADER首部

                                   req.http.X-Forwarded-For

                                   req.http.Auhtorization

                                   req.http.cookie

                            req.request:请求方法         

                            client.ip:客户端ip

 

                     state engine workflow(v3):

                            vcl_recv à vcl-hash à vcl_hit à vcl_deliver

                            vcl_recv à vcl_hash à vcl_mis à vcl_fetch à vcl_deliver

                            vcl_recv à vcl_pass à vcl_fetch à vcl-deliver

                            vcl_recv à vcl_pipe

                     state engine workflow(4)  http://book.varnish-software.com/4.0/chapters/VCL_Basics.html

sub vcl_recv {

    if (req.method == "PRI") {

        /* We do not support SPDY or HTTP/2.0 */

        return (synth(405));

    }

    if (req.method != "GET" &&

      req.method != "HEAD" &&

      req.method != "PUT" &&

      req.method != "POST" &&

      req.method != "TRACE" &&

      req.method != "OPTIONS" &&

      req.method != "DELETE") {

        /* Non-RFC2616 or CONNECT which is weird. */

        return (pipe);

    }

    if (req.method != "GET" && req.method != "HEAD") {

        /* We only deal with GET and HEAD by default */

        return (pass);

    }

    if (req.http.Authorization || req.http.Cookie) {

        /* Not cacheable by default */

        return (pass);

    }

    return (hash);

}

 

 

例一:

[root@C7-1 ~]#cp /etc/varnish/default.vcl /etc/varnish/test.vcl

[root@C7-1 ~]#vim /etc/varnish/test.vcl

# 修改一

sub vcl_recv {

    # Happens before we check if we have this in cache already.

    #

    # Typically you clean up the request here, removing cookies you don't need,

    # rewriting the request, etc.

    if (req.method == "PRI") {

        /* We do not support SPDY or HTTP/2.0 */

        return (synth(405));

    }

    if (req.method != "GET" &&

      req.method != "HEAD" &&

      req.method != "PUT" &&

      req.method != "POST" &&

      req.method != "TRACE" &&

      req.method != "OPTIONS" &&

      req.method != "DELETE") {

        /* Non-RFC2616 or CONNECT which is weird. */

        return (pipe);

    }

    if (req.method != "GET" && req.method != "HEAD") {

        /* We only deal with GET and HEAD by default */

        return (pass);

    }

    if (req.http.Authorization || req.http.Cookie) {

        /* Not cacheable by default */

        return (pass);

    }

    return (hash);

 

}

 

# 修改二

sub vcl_deliver {

    # Happens when we have all the pieces we need, and are about to send the

    # response to the client.

    #

    # You can do accounting or modifying the final object here.

    if (obj.hits>0) {     # 如果命中次数大于零

        set resp.http.X-Cache = "X-HIT";    # 在返回的报文中添加头部信息“HIT”

    } else {

        set resp.http.X-cache = "X-MISS";   # 否者添加“MISS“

    }

}

 

[root@C7-1 ~]#varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082    # 连接varnishadm

vcl.load  test1 /etc/varnish/test.vcl   # 添加VCL

vcl.use test1   # 使用vcl

 

[root@C7-2 ~]#curl -I 192.168.9.71:6081     #使用curl访问

X-cache: X-MISS    # 可以看到没有命中

[root@C7-2 ~]#curl -I 192.168.9.71:6081   # 再次访问

X-Cache: X-HIT    # 命中

 

 

varnish内置变量 https://varnish-cache.org/docs/4.1/reference/vcl.html#variables

变量种类:

client

server

req

reqsp

breq

bresp

obj

storge

 

bereq

bereq.http.HEADERS:由varnish发往baskend server 的请求报文的指定首部

bereq.request:请求方法

bereq.ur;

bereq.proto:http协议版本

beresp

   beresp.proto

   beresp.status:后端服务器响应状态码

   beresp.reason:原因短语,是为了给出状态码的简单的文本描述,状态码用于控制,而原因短语用于用户阅读

   beresp.backend.ip

   beresp.backend.name

   beresp.backend.HEADERS:从backend server响应的报文首部

   beresp.ttl:后端服务器相应的内容的余下生命时长

obj

   obj.ttl:对象的ttl值

   obj.hits:此对象从缓存命中的次数

server

   server.ip

   server.hostname

  

 

 

 

 

.           四(0分)

 

 

 

 

 

          day47(Zabbix)

.           一、

可监控对象

       设备:服务器、路由器、交换机、IO系统

       软件:OS、网络、应用程序

       偶发性小故障:主机DOWN机、服务不可用、主机不可达

       严重故障:磁盘满了,replication(复制)延迟

       主机新能指标

       时间序列数据展示:多用来绘图

监控工具

       Basic solutions(解决方案):top、vmstat、iostat、mytop、innoto

Graphical(绘图) solutions:Nagios(Opsview,Icinga),Cacti(使用的rrd(round robin database)数据库)、Zabbix(使用mysql、pgsql)

 

.           二

Zabbix架构

zabbix-server:C语言

       OS:zabbix-agent:C语言

       zabbix-web:用于实现zabbix设定和展示

       zabbix:分布式监控环境的专用环境

 

       zabbix database:MySQL、PGSQL、Oracle、DB2、SQLLite

zabbix 产生的书籍主要由四部分组成

       配置数据

       历史数据

       历史趋势数据

       时间数据

创建数据库

       mysql> create database zabbix character set utf8 collate utf8_bin;

       mysql> grant all on zabbix.* to 'zbxuser'@'%' identified by 'zbxuser';

zabbix安装

 

下载zabbix文件夹:wget -r --no-parent http://repo.zabbix.com/zabbix/4.2/rhel/7/x86_64/ -P zabbix

服务端:

              [root@C7_1 zabbix]#yum install zabbix-server-mysql-4.2.1-1.el7.x86_64.rpm zabbix-get-4.2.1-1.el7.x86_64.rpm zabbix-web-4.2.1-1.el7.noarch.rpm zabbix-web-mysql-4.2.1-1.el7.noarch.rpm zabbix-agent-4.2.1-1.el7.x86_64.rpm zabbix-agent-4.2.1-1.el7.x86_64.rpm   # 会自动再httpd得conf.d目录下创建文件         

              [root@C7_1 ~]#cd /usr/share/doc/zabbix-server-mysql-4.2.1/

              [root@C7_1 zabbix-server-mysql-4.2.1]#gunzip create.sql.gz

              [root@C7_1 zabbix-server-mysql-4.2.1]#mysql -h 192.168.9.71 -uzbxuser -p zabbix < create.sql

                     三个数据库的导入顺序:

mysql -uzabbix -pzabbix zabbix < /usr/share/doc/zabbix-server-mysql-2.4.8/create/schema.sql
mysql -uzabbix -pzabbix zabbix < /usr/share/doc/zabbix-server-mysql-2.4.8/create/images.sql
mysql -uzabbix -pzabbix zabbix < /usr/share/doc/zabbix-server-mysql-2.4.8/create/data.sql

              [root@C7_1 zabbix-server-mysql-4.2.1]#cd /etc/zabbix/  

              [root@C7_1 zabbix]#vim zabbix_server.conf

       基本参数

# ListenPort=10051                # 默认端口,无需修改

              # SourceIP=                          # 别人看到的ip

              LogFile=/var/log/zabbix/zabbix_server.log             # 日志文件

              LogFileSize=0                         # 日志文件大小,用于日志滚动,比如设为1G,当日志大小达到1G时,则会打开第二个日志

              # DebugLevel=3                     # 记录日志的级别

              PidFile=/var/run/zabbix/zabbix_server.pid

              DBHost=192.168.9.71       # 数据库节点,改为数据库节点的ip,如果是本机,则不用修改

              DBUser=zbxuser               # zabbix连接数据库的账号

              DBPassword=zbxuser        # zabbix连接数据库的密码

              DBPort=3306                    # 端口

       其他参数解释

              # StartPollers=5                      # 打开的pollers的个数,0-1000个,默认为5个

              # StartIPMIPollers=0              # ipmi检测poller

              # StartPollersUnreachable=1              # 探测一个主句不在线用到,会不断探测什么时候在线

              # StartTrappers=5                  # 随时等待客户端等待主动发信息过来

              # StartPingers=1                    # 通过ping加测主机是否在线

              # StartDiscoverers=1              # 启动几个发现进程,发现新主机加入

              # StartHTTPPollers=1

              # StartTimers=1               # 计时器进程

              # JavaGateway=       # 是否启动javagateway

              # JavaGatewayPort=10052           # 如果启动Javagateway的端口

              # StartJavaPollers=0

              SNMPTrapperFile=/var/log/snmptrap/snmptrap.log          # 收到anmp的agent段的trapper信息保存在哪里

              # StartSNMPTrapper=0         # 是否启动

              # ListenIP=0.0.0.0     # 监听在那个ip

              # HousekeepingFrequency=1      # 多长时间执行Housekeeping操作

              # MaxHousekeeperDelete=5000        # 一批最多删除多少过期数据

              # CacheSize=8M                    # 配置缓存空间

              # CacheUpdateFrequency=60            # cache更新的时间

              # StartDBSyncers=4        # db同步进程的个数

              # HistoryIndexCacheSize=4M

              AlertScriptsPath=/usr/lib/zabbix/alertscripts   # 报警脚本

              ExternalScripts=/usr/lib/zabbix/externalscripts              # 调用外部操作的脚本

              # FpingLocation=/usr/sbin/fping       # fping的文件

              # SSHKeyLocation=        # ssh验证的key

              [root@C7_1 ~]#systemctl start zabbix-server.service

              [root@C7_1 ~]#vim /etc/php.ini

              date.timezone = Asia/Shanghai          # 修改时区

              [root@C7_1 ~]#systemctl restart httpd.service

浏览器访问

 

 

             

 

 

 

 

 

 

 

 

 

 

 

agent端

       [root@C7_1 ~]#vim /etc/zabbix/zabbix_agentd.conf

       Server=127.0.0.1,192.168.9.71                   # 允许那些来连接获取数据

       # ListenPort=10050          # 客户端的端口

       # ListenIP=0.0.0.0            # 监听的ip

       # StartAgents=3       # 启动多少agent进程

       ServerActive=127.0.0.1,192.168.9.71              # 客户端主动发起数据通知给的地址

       Hostname=C7-1.p-pp.cn           # 告诉server的本机的主机名

       [root@C7_1 ~]#systemctl start zabbix-agent.service       # 启动angen

       在浏览器添加

 

 

 

 

提示:

       自己搭建的LAMP如何设置zabbix

       ① 复制zabbix文件

cp /etc/httpd/conf.d/zabbix.conf /usr/local/httpd/conf/xuan/

       ② 设置httpd运行的用户,冰江zabbix文件导入

vim /usr/local/httpd/conf/httpd.conf

              User apache

Group apache

              Include conf/xuan/zabbix.conf

       ③ 设置php开启bcmath(若安装时已经开启,则无需开启)

cd /usr/src/php-5.5.38/ext/bcmath/

              /usr/local/php/bin/phpize

./configure --with-php-config=/usr/local/php/bin/php-config --enable-bcmath

make && make install

       ④ 调用bcmath

echo "extension=bcmath.so"  >> /usr/local/php/php.ini

       ⑤重启

              /etc/init.d/httpd restart

支持:GD、jpeg、png等,请看:https://www.cnblogs.com/-xuan/p/10787448.html

 

.           三

.           四

zabbix报警给微信发信息:java开发的:alert-agent

 

zabbix组件

       zabbix-server

       zabbix-database

       zabbix-web

       zabbix-agent

       zabbix-proxy

zabbix逻辑组件

       主机组、主机

       item(监控项)、application(应用)

       graph(图形)

       trigger(触发器)

              event(事件)

       action

              notice

              command

       media

              users(media)

监控系统:

       数据采集、数据存储、报警、数据可视化

 

客户机支持snmp

       [root@C7-2 ~]#yum install net-snmp

       [root@C7-2 ~]#systemctl start snmpd

监控项Item的创建

每个item拥有相对应的类型,Zabbix agent、SNMp、SSH agent等,zabbix服务器会使用相同类型的协议机制同被监控端通信

每个item都有一个专用的‘key’,全局唯一,监控端要获取被监控端某一item的值,就是要被控端某一指定的key的值

手动获取zabbix 的值:

[root@C7-1 ~]#zabbix_get -s 192.168.9.72 -p 10050 -k "system.uname"    # 获取system.uname的值
    date "+%Y-%m-%d %H:%M:%S" -d @`zabbix_get -s 192.168.9.72 -p 10050 -k "system.localtime"`    # 获取当前时间
    zabbix_get -s 192.168.9.72 -p 10050 -k "system.hostname"            # 获取主机名

创建ITEM

①点击item


       ② 点击右上角的

③item的相关设置

 

 

 

 

属性

描述

Host

主机或者模板

Name

监控项item名称可以使用如下宏变量:

$1, $2…$9,这9个参数对应item key的参数位置。

例如: Free disk space on $1

如果item key为“vfs.fs.size[/,free]”,那么对应的名称会变成”Free disk space on /“,$1对应了第一个参数”/“,你明白了吗?

Type

item类型(常见agent、SNMP、agent(active)等),请看后续监控项类型相关文章.

Key

监控项item的key.点击select可以看到系统很多自带的key,也可以看到用户自定义的key,如何自定义key,情继续关注ttlsa后续的zabbix教程.

Host interface

主机接口,例如agent、SNMP、impi等

Type of information

获取到得数据类型

Numeric (unsigned) – 64bit unsigned integer

Numeric (float) – floating point

numberCharacter – 字符串,最长255字节

Log – 日志文件. key必须为log[].

Text – 大小无限制的文本

Data type

定义获取到整数数据的数据类型

Boolean – 数据为0或者1.’true’表示1,’false’为0,不区分大小写。

如下为True和False的定义:

TRUE – true, t, yes, y, on, up, running, enabled, available

FALSE – false, f, no, n, off, down, unused, disabled, unavailable

任何非0数字都被认为是TRUE,0被定义为FALSE.负数呢?

Octal – 八进制

Decimal – 十进制

Hexadecimal – 十六进制

zabbix将会自动把他们转为数字

Units

默认情况下,如果原始值超过1000,那么他会先除以1000并且显示出来例如,设置了单位为bps并且收到的值为11102,将会显示为11.1Kbps

如果单位被指定为 B (byte), Bps (bytes per second) ,那么它会除以1024然后再显示数据。所以大家在监控流量和文件大小的时候不要用错单位,否则会出现数据不一致的情况。

如下为时间单位:

unixtime – 转为 “yyyy.mm.dd hh:mm:ss”. 只能使用正数。

uptime – 转为“hh:mm:ss” 或者“N days, hh:mm:ss”

例如,收到的值为881764秒,他将会显示为“10 days, 04:56:04”

s – 转为“yyy mmm ddd hhh mmm sss ms”;

例如,收到的值为881764(单位秒),他将会被显示为10d 4h 56m”,只会显示3个单元。有时候只会显示2个单元,例如”1m 5h”(不包含分,秒,毫秒),如果返回的值小于0.001,他只会显示”<1 ms”禁用单位:ms、rpm、RPM、%

Use custom multiplier

如果启用这个选项,所有接收到的整数或者浮点数都会乘以这个文本框里面的值。使用这个选项,zabbix将会把收到的KB,MBps等数据先转为B,Bps。否则zabbix不能正确设置前缀(K,M,G等等).

zabbix 2.2开始支持科学计数法,例如:1e+70.

Update interval (in sec)

数据更新时间注意:如果设置为0,那么这个数据将永久不更新。但是如果在灵活更新间隔(flexible interval)里面设置了一个非0间隔,那么以这个为准

Flexible intervals

可以创建例外的更新间隔,例如:

Interval:10,Period:1-5,10:00-19:00,表示周一到周五的早上10点到晚上19点每十秒更新一次数据。其余时间使用默认值。这边最多只能设置7个灵活更新间隔.如果设置的多个灵活时间间隔有冲突,那么他会使用最小的时间间隔。

两个注意点:如果时间间隔被设置为0,那么数据永久不会更新。它不能用在zabbix主动方式的item

Keep history(in days)

历史记录可以在数据库中保存多久,过期的历史数据将会被Housekeeper删除.

从Zabbix2.2开始,这个值可以被一个全局值覆盖:Administrator->General->Housekeeper->勾选Keep history(in days),输入你希望历史记录保留的时间。

zabbix官方推荐大家尽量开启他,尽量使用一个较短的历史记录。如果你想看历史数据的画,你可以将”趋势历史记录Keep trends”的保留时间设置长一点。

Keep trends(in days)

趋势数据(以小时为单位的min,max,avg,count的数据)在数据库中保留时常,过期数据将会被HouseKeeping删除。

从zabbix2.2开始.这个值可以被一个全局值覆盖(请参考上面的Keep history)

备注:趋势数据只能存数字类型数据,字符、日志这些都无法存储。

Store value

As is – 数据不作处理

Delta (speed per second) –

计算值公式为 (value-prev_value)/(time-prev_time)

value – 获取到得原始值

value_prev – 上次接收到的值

time – 当前时间

prev_time – 上次接收数据的时间一般用于数据增长的类型,例如:

网卡流量,每次获取到得都是当前网卡总流量。比如第一次给的值是0字节(UNIX时间为1),第二获取到得是3000字节(UNIX时间为31),那么套用公式(3000-0)/(31-30),可以得出数据是100字节/秒

备注:如果当前获取到的值比上一个值更小,那么zabbix会忽略这个值,等待下一次的值

Delta (simple change) –

计算公式为 (value-prev_value),value – 当前值value_prev – 上次获取到得值

Show value

值映射,需要配置数字映射到字符的映射表。例如:

1=>ttlsa.com访问正常。如果key返回的数据为1,那么监控页面不会显示1,而是显示ttlsa.com访问正常。key返回的数据只能为整数,并且不做任何修改保存到数据库中。只有在显示的时候才会根据映射表来展示相应的内容。

Log time format

只可以用在LOG类型中,支持占位符:

y: 年(0001-9999)

M: 月(01-12)

d: 日(01-31)

h: 小时(00-23)

m: 分钟(00-59)

s: 秒(00-59)如果时间搓留空不会被解析。

例如:

如 下为zabbix agent日志” 23480:20100328:154718.045 Zabbix agent started. Zabbix 1.8.2 (revision 11211).”前面6个字符是PID,后面更上日期,时间和日志内容,日志时间类为“pppppp:yyyyMMdd:hhmmss”

备注:“p” 与 ”:” 为占位符,除了“yMdhms”不能为占位符,其它任意字符都可以作为占位符

New application

创建一个新的应用

Applications

包含多个应用,例如:

cpu、disk、network,监控项可以属于多个应用

Populates host inventory field

数据自动填充到inventory资产清单的相应属性,前提是你的inventory处于自动模式

Description

监控项的描述

Enabled

是否启用这个监控项.

 

 

graph(图形),将采集到的数据做成图片展示

①点击graphs

 

②点击右上角的

 

 

触发器

       监控项仅负责收集数据,而通常收集的数据的目的还包括指标对应的数据超出合理范围时给相关人员送告警信息,“触发器”正式用于为监控项所收集的数据定义阈值

       一旦某次采集的数据超出了此触发器定义的阈值,触发器状态将会转换为“problem”;而采取的数据回归至合理范围内时,其状态重新返回ok

       触发器表达式高度灵活,可以以之创建出非常复杂的测试条件

 

基本触发器表达式:{<server>:<key>.<function>(<parameter>)}<operator><constan>

       server:主机名称

       key:主机上关系的响应监控项key

       function:评估采集到的数据是否在合理范围内使用的函数,其评估过程可以根据采取的数据、当前时间其及其他因素进行

       触发器支持的函数:avg(平均值)、count(计数)、change(变化数据量)、date(日期)、dayofweek(周几)、delta(增量)、diff(差量)、iregexp(不区分大小写的正则)、last(最近一次采样)、max(最大值)、min(最小值)、nodata(没有数据)、now(此刻)、sum(求和)等

       parameter:函数参数;大多数数值函数可以接受秒其参数,而如果在数值参数之前使用“#”作为前缀,则表达为最近几次的取值,如果(300)表示300秒内所有取值之和,而sum(#10)则表示最近10次取值之和

       此外,avg、count、last、min、max还支持使用第二个参数,用于完成时间限定;例如,max(1h,7d)将返回一周之前的最大值。

 

trigger:名称中可以使用宏

       {HOST.HOST},{HOST.NAME},{HOST.IP},{HOST.CONN},{HOST.DNS}

创建触发器(trigger)

 

点击右上角的创建

 

 

 

使用hping3测试上边创建的cpu终端触发器触发器(trigger)

hping3 192.168.9.72 --faster

       --fast:每秒发10个

       --faster:每秒有一百个

       --flood:能发多少就发多少

 

 

Action(报警的动作)有两类,

       send message

       command

创建

 

 

 

 

.           五

zabbix监控某关注的指标

host group à host à item (存储MySQL)à graph(zabbix-web)à trigger(触发器) à action(conditon+operation)

              application:把功能相近的一组item归类在一起进行管理组件

 

       依赖关系 à ITEM à Trigger à Actionà Notice,command

添加主机到zabbix server

       discovery,auto_registrion

       low level discovery

      

Item:默认的item有多种类型

       zabbix-agent:工作模式:passive,active

       网卡流量相关

              net.if.out[if,<mode>]

                     if:接口,如eth0

                     mode:bytes,packets,errors,dropped

              net.if.out[if,<mode>]

              net.if.total[if,<mode>]

       端口相关:

              net.tcp.listen[port]

              net.tcp.port[<ip>,port]

              net.tcp.service[service,<ip>,<port>]

              net.udp.listen[port]

       进程相关

              kernel.maxfiles   # 最大打开文件数

              kernel.maxproc  # 最大进程数

       CPU相关

              system.cpu.intr  # 中断次数

              system.cpu.load[<cpu>,<mode>]      # 负载

              system.cpu.num[<type>]      # cpu克数

              system.cpu.switches        # 上下文切换次数

              system.cpu.util[<cpu>,<type>,<mode>] # 利用率

       磁盘IO相关

              vfs.dev.read[<device>,<type>,<mode>]

              vfs.dev.write[<device>,<type>,<mode>]

              vfs.fs.innode[fs,<mode>]

       自定义ITEM:

              关键:选取一个唯一的key

              命令:收集数据的命令或脚本

 

Trigger

       状态:

              OK

              PROBLEM:有事件发生

       zabbix server 每次接收到item的新数据时。就会与item的当前采样进行判断,即与trigger的表达式进行比较;

 

Action:

       触发条件一般为事件

              trigger events:ok à PROBLEM

              Discovery events:zabbix的network discovery工作时发现主机

              Auto registration events:主动模式的agent注册时产生的事件

              Internal events:Item变成不在被支持,或Trigger变成未知状态

       operations

              send message

              Remote command

              配置send message

(1)    定义好Media

(2)    定义好用户

(3)    配置要发送的信息

邮件发送失败,cannot connect to SMTP server "localhost": cannot connect to [[localhost]:25]: [111] Connection refused

       关闭IPv6

Step 1: add this rule in /etc/sysctl.conf : net.ipv6.conf.all.disable_ipv6=1
Step 2: add this rule in /etc/sysconfig/network: NETWORKING_IPV6=no
Step 3: add this setting for each nic X (X is the corresponding number for each nic) in /etc/sysconfig/network-scripts/ifcfg-ethX: IPV6INIT=no
Step 4: disable the ip6tables service : chkconfig ip6tables off
Step 5: Reload the sysctl configuration:
# sysctl -p
or
# reboot

注意:禁用IPV6后,可能会导致某些服务无法启动,比如VSFTP,对于VSFTP,需要修改/etc/vsftpd/vsftpd.conf文件中的listen和listen_ipv6两个选项:

listen=YES

listen_ipv6=NO

 

 

 

          day48(Zabbix)

.           一

 

Zabbix常用术语

       Item key

       Escalation

       Template

       Web Scennario

Item key

       key的官方文档:https://www.zabbix.com/documentation/4.0/manual/config/items/itemtypes/zabbix_agent

       word文档:zabbix的item.key.docx

       命名要求:数字、字符、下划线、点号、连接符

       接受参数:system.cpu.load[<cpu><mode>]

              注意:每个key背后都应该有一个命令或脚本来实现数据收集;此命令或脚本可调用传递给key的参数,调用方式$1,$2

       咋Zabbix中定义item调用某key,还需要定义数据采集频率、历史数据的保存时间等

              {<server>:<key>.<function>(<paramter>)}<operator> <constant>

 

Action

       message

       condtion

       operation

              event:

                     trigger

                     discovery

              send message

                     Media

                            Media Type

                                   Email,SMS,Jabber,Script,EZ Texting

                     User

              remote comman

                     给Zabbix用户定义sudo规则

 

Script:Alert Script

              放置于特定目录:AlertScriptsPath=/usr/lib/zabbix/alertscripts

                     [root@C7-1 ~]#grep "Alert" /etc/zabbix/zabbix_server.conf

                     AlertScriptsPath=/usr/lib/zabbix/alertscripts              # 由这个参数指定脚本配置文件

       编写脚本

              脚本中可使用$1,$2,$3来调用action中的邮件的收件人,Default subject,Default Message

              [root@C7-1 ~]#vim /usr/lib/zabbix/alertscripts/alerttest.sh

#!/bin/bash

to="$1"

subject="$2"

body="$3"

echo "$body" |mail -s "${subject}xuan" "$to" 

[root@C7-1 ~]#chmod +x /usr/lib/zabbix/alertscripts/alerttest.sh

              打开浏览器Zabbix控制台

 

 

 

用户设置

 

 

 

 

Action实现remote comman

[root@C7-1 ~]#vim /etc/zabbix/zabbix_agentd.conf

EnableRemoteCommands=1       # 开启远程执行命令

LogRemoteCommands=1

 

(1)    给Zabbix用户定义sudo规则

(2)    不支持active模式的agent

(3)    不支持代理模式

(4)    命令长度不得超过255个字符

(5)    可以使用宏

(6)    zabbix-server仅执行命令,不管是否成功

 

例:检测web服务

① 添加新的application命名为httpd service

② 添加item 命名为 item httpd service ,key=net.tcp.listen[80],布尔值(端口开启返回1,否则返回0)

③ 添加trigger

命名为trigger httpd service

expression:Item item httpd service

function:最后一次是否为0,为0则触发

       ③创建action

命名为action httpd service

设置trigger为trigger httpd service

设置第一步,执行命令,第二步发邮件

       切记,Centos6的visudo,需要将#Defaults    requiretty 注释

 

 

 

 

 

 

 

.           二

图形

       其实在创建item的时候,已经为每个item自动创建了一个单独的图形,可以在Montiring à Latest Data中过滤对应的条件,应用后可以点击每个主机后边的Graph查看图形

screen(屏幕)

       将多个表放在屏幕上,可以同时观看

 

 

     宏

              宏就是变量,在zabbix中叫宏,其中也有内置宏,也就是内建变量,宏明只能是大写字母

       宏的两种分类

              内置宏:{HOST.NANE}、{HOST.IP}
              自动以宏:{$MACRO}

       宏的三个级别使用

              Global、Template、Host

              级别优先级:Host à Template à Global       # 找到后不会再找

       主机宏

 

       Template宏

 

       全局宏定义

 

 

 

Template(模板)

       一系列配置的集合,这些配置可以连接到指定的主机

维护时间

 

 

 

User Parameters

       zabbix 内置了许多item key,User Parameters实现用户自动以item key,实现特有数据指标监控

       语法:UserParameter=<key>,<command>

例子一:创建一个求agent内存的使用了多少的item key

       agent设置

      [root@C7-2 ~]#vim /etc/zabbix/zabbix_agentd.d/userparameter_mem.conf

UserParameter=os.memory.used,free -m | awk '/^Mem/{print $3}'

      [root@C7-2 ~]#systemctl restart zabbix-agent.service

      

浏览器设置

              找到对应的主机,添加item,添加后如图所示

 

      

 

 

 

 

例子二

       agent设置

[root@C7-2 ~]#vim /etc/zabbix/zabbix_agentd.d/xuan_mysql.conf

UserParameter=mysql.dm[*],mysql -h$1 -u$2 -p$3 -e 'show global status' | awk '/Com_$4\>/{print $$2}'

# $1:IP     $2:用户        $3:密码        $4:过滤条件       $$2代表awk中print $2

       浏览器设置

              找到对应的主机,添加item,添加后如图所示

 

      

.           三

zabbix发现:网络发现(Network Discovery),LLD(low level discovery)

此二者的功能:

       自动添加主机、链接至模板、添加监控项、分组、定义触发器、执行远程脚本;

 

网络发现功能Network discovery

       HTTP、iCMP、SSH、LDAP、TCP、Telnet、zabbix_agent扫描指定网络内的主机

       一旦主机被发现,如果对其进行操作,将由action来决定

       网络的两个步骤

              discovery à action

       发现中的事件

              Service Discovery,Service Lost,Service Up,Service Down,Host Discovery,Host List,Host Up,Host Down

       actions:

              Sending notifications ……

             

 

 

 

 

 

 

 

 

 

 

 

LLD:low level discovery

       自动发现特定变量的名称

              #IFNAME,#FSNAME

       添加针对变量的Item

 

auto_registation

       配置过程

              Agent设置

[root@C7-2 ~]#vim /etc/zabbix/zabbix_agentd.conf
Server=192.168.9.71
ServerActive=192.168.9.71
Hostname=C7-2.p-pp.cn
# ListenPort=10050
ListenIP=192.168.9.72
HostMetadata=ar1                   #浏览器可以根据HostMetadata来决定是否做对应操作

浏览器设置

 

 

 

 

 

 

 

然后等待自动添加完成即可,一分钟左右

.           四

 

Web监控

       zabbix agent

       snmp:simple netwrk management protocol

       IPMI:智能平台管理接口(Intelligent Platform Management Interface)原本是一种Intel架构的企业系统的周边设备所采用的一种工业标准。IPMI亦是一个开放的免费标准,用户无需支付额外的费用即可使用此标准。

       JMX:Java Management Extensions,用于通过java自己的接口对java程序监控

              zabbix-java-gateway

 

SNMP:监控方式

              操作:Get,Gateway,Set,Response,Trap

              MIB:是别管理对象的集合,而且还额外定义了被管理对象的名称、访问权限、数据类型等属性

              MIB视图:MIB的子集

              授权:将某MIB视图与某Commuity绑定来实现

              OID:Object ID

                     1:sysytem

                     2:interface

                     4:ip

                     6:tcp

                     7:udp

                    

zabbix-proxy

 

 

 

 

 

 

          REDIS

ansible 'all:!192.168.9.81:!192.168.9.71' -m copy -a 'src=/root/redis-3.2.9.tar.gz dest=/root/'

ansible 'all:!192.168.9.81:!192.168.9.71' -m shell -a 'tar -xf /root/redis-3.2.9.tar.gz -C /root/'

ansible 192.168.9.73,192.168.9.74 -m yum 'name=gcc,gcc-c++'

ansible 'all:!192.168.9.81:!192.168.9.71' -m shell -a 'chdir=/root/redis-3.2.9 make'

ansible 'all:!192.168.9.81:!192.168.9.71' -m shell -a 'chdir=/root/redis-3.2.9 make install'

 

每台主机执行:/root/redis-3.2.9/utils/install_server.sh

 

ansible 'all:!192.168.9.81' -m shell -a 'sed -i -e "62c\bind 127.0.0.1 {{ip}}" /etc/redis/6379.conf'

ansible 'all:!192.168.9.81' -m shell -a 'sed -i -r -e "722s@# @@g" -e "730s@# @@g" -e "736s@# @@g" -e "813c \cluster-require-full-coverage no" /etc/redis/6379.conf'

ansible 'all:!192.168.9.81' -m service -a 'name=redis_6379 state=restarted'

ansible 'all:!192.168.9.81' -m yum  -a 'name=ruby,rubygems'

ansible 'all:!192.168.9.81:!192.168.9.71' -m copy -a 'src=/root/redis-3.2.0.gem dest=/root/'

ansible C7 -m shell -a 'chdir=/root gem install redis --version 3.2.0'

 

./redis-trib.rb create --replicas 1 192.168.9.51:6379 192.168.9.61:6379 192.168.9.71:6379  192.168.9.72:6379  192.168.9.73:6379  192.168.9.74:6379 

 

.           一(简介和基本使用)

1.1:简介

Redis(Remote Dictionary Server)在2009年发布,开发者Salvatore Sanfilippo是意大利开发者,他本想为自己的公司开发一个用于替换MySQL的产品Redis,但是没有想到他把Redis开源后大受欢迎,短短几年,Redis就有了很大的用户群体,目前国内外使用的公司有知乎网、新浪微博、GitHub等

redis是一个开源的、遵循BSD协议的、基于内存的而且目前比较流行的键值数据库(key-value database),是一个非关系型数据库,redis提供将内存通过网络远程共享的一种服务,提供类似功能的还有memcache,但相比memcache,redis还提供了易扩展、高性能、具备数据持久性等功能。

1.2:redis对比memcached:

支持数据的持久化:可以将内存中的数据保持在磁盘中,重启redis服务或者服务器之后可以从备份文件中恢复数据到内存继续使用。

支持更多的数据类型:支持string(字符串)、hash(哈希数据)、list(列表)、set(集合)、zet(有序集合)

支持数据的备份:可以实现类似于数据的master-slave模式的数据备份,另外也支持使用快照+AOF。

支持更大的value数据:memcache单个key value最大只支持1MB,而redis最大支持512MB。

Redis 是单线程,而memcache是多线程,所以单机情况下没有memcache并发高,但redis 支持分布式集群以实现更高的并发,单Redis实例可以实现数万并发。

支持集群横向扩展:基于redis cluster的横向扩展,可以实现分布式集群,大幅提升性能和数据安全性。

都是基于C语言开发。

1.3:Redis安装及使用:

官方下载地址:http://download.redis.io/releases/

 

下载源码包

[root@C7-1 ~]#wget http://download.redis.io/releases/redis-5.0.3.tar.gz

[root@C7-1 ~]#tar xf redis-5.0.3.tar.gz

[root@C7-1 ~]#cd redis-5.0.3/

[root@C7-1 redis-5.0.3]#make PREFIX=/usr/local/redis install

[root@C7-1 ~]# ll /usr/local/redis/bin/

total 32656

-rwxr-xr-x 1 redis redis 4365488 Dec 13 09:21 redis-benchmark #redis性能测试工具

-rwxr-xr-x 1 redis redis 8088920 Dec 13 09:21 redis-check-aof #AOF文件检查工具

-rwxr-xr-x 1 redis redis 8088920 Dec 13 09:21 redis-check-rdb #RDB文件检查工具

-rwxr-xr-x 1 redis redis 4800752 Dec 13 09:21 redis-cli #redis #客户端工具

lrwxrwxrwx 1 redis redis   12 Dec 13 09:21 redis-sentinel -> redis-server #哨兵,软连接到server

-rwxr-xr-x 1 redis redis 8088920 Dec 13 09:21  #redis-server #redis 服务端

 

1.4启动

[root@C7-1 redis-5.0.3]#/usr/local/redis/bin/redis-server redis.conf

 

32695:M 13 Jun 2019 01:09:06.995 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.  

32695:M 13 Jun 2019 01:09:06.995 # Server initialized

32695:M 13 Jun 2019 01:09:06.995 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 

32695:M 13 Jun 2019 01:09:06.995 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. 

32695:M 13 Jun 2019 01:09:06.995 * Ready to accept connections

 

# 启动后会有三个警告

1.4.1:lower value of 128.    backlog参数控制的是三次握手的时候server端收到client ack确认号之后的队列值。

两种解决方法

1.修改内核 :net.core.somaxconn = 512

2.修改配置文件:tcp-backlog =128

1.4.2:vm.overcommit_memory = 1   # 让修改内核改为1,这个值有三个

0、表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1、表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2、表示内核允许分配超过所有物理内存和交换空间总和的内存

1.4.3:echo never > /sys/kernel/mm/transparent_hugepage/enabled   # 执行这命令即可

 

1.5创建启动脚本

[root@c7-1 redis-5.0.3]# vim /usr/lib/systemd/system/redis.service

[Unit]

Description=Redis persistent key-value database

After=network.target

After=network-online.target

Wants=network-online.target

 

[Service]

ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf  --supervised systemd

ExecReload=/bin/kill -s HUP $MAINPID

ExecStop=/bin/kill -s QUIT $MAINPID

Type=notify

User=redis

Group=redis

RuntimeDirectory=redis

RuntimeDirectoryMode=0755

 

[Install]

WantedBy=multi-user.target

[root@c7-1 redis-5.0.3]# mkdir /usr/local/redis/etc

[root@c7-1 redis-5.0.3]# cp redis.conf  /usr/local/redis/etc

[root@C7-1 redis-5.0.3]#useradd -r -s /sbin/nologin redis

[root@C7-1 redis-5.0.3]#systemctl start redis

[root@C7-1 redis-5.0.3]#ln -s /usr/local/redis/bin/* /usr/local/sbin/

 

1.6 配置文件

[root@C7-1 redis-5.0.3]#mkdir /usr/local/redis/data;chown redis: /usr/local/redis/ -R

[root@C7-1 ~]#vim /usr/local/redis/etc/redis.conf

bind 192.168.9.71

protected-mode yes  #redis3.2 之后加入的新特性,在没有设置bind IP和密码的时候只允许访问127.0.0.1:6379

port 6379     #监听端口

timeout 0     #客户端和Redis服务端的连接超时时间,默认是0,表示永不超时,一本设为600秒

tcp-keepalive 300     #tcp 会话保持时间

daemonize yes     # 默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes,当redis作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面

logfile "/usr/local/redis/data/redis_6379.log"    # 日志文件

databases 30   #设置db 库数量,默认16个库

always-show-logo no    #在启动redis 时是否显示log

 

save 900 1 #在900秒内有一个键内容发生更改就出就快照机制

save 300 10

save 60 10000

stop-writes-on-bgsave-error no  #快照出错时是否禁止redis 写入操作

rdbcompression yes #是否开启快照压缩功能

dbfilename redis_6379.rdb   #快照文件名

dir /usr/local/redis/data     #快照文件保存路径

 

replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式:1) 如果replica-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。2) 如果replica-serve- stale-data设置为no,除去指定的命令之外的任何请求都会返回一个错误"SYNC with master in progress"。

 

requirepass 123456   # 设置密码

 

maxclients 32768     # 客户端最大数

 

maxmemory 8589934592    # 设置对大内存为8G

 

appendonly yes     #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。

appendfilename "appendonly.aof"    # AOF日志存放的文件

 

auto-aof-rewrite-percentage 100 #当Aof log增长超过指定比例时,重写log file, 设置为0表示不自动重写Aof 日志,重写是为了使aof体积保持最小,而确保保存最完整的数据。

auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件尺寸

 

 

1.7.测试

[root@C7-1 data]#systemctl restart redis 

[root@C7-1 data]#redis-cli -h 192.168.9.71

192.168.9.71:6379> set key1 v1

(error) NOAUTH Authentication required.    # 提示认证失败,需要输入密码

192.168.9.71:6379> AUTH 123456   # 密码验证

OK

192.168.9.71:6379> set k1 name1  # 设置key

OK

192.168.9.71:6379> get k1  # 获取key

"name1"

192.168.9.71:6379> SELECT 29  # 切换数据库,在配置文件中设置了30个,为0-29

OK

192.168.9.71:6379> exit

[root@C7-1 data]#ll

total 32

-rw-r--r--. 1 redis redis   110 Jun 13 02:09 appendonly.aof     # AOF日志文件,会记录每一步的操作

-rw-r--r--. 1 redis redis 19661 Jun 13 02:09 redis_6379.log       # 启动日志

-rw-r--r--. 1 redis redis     6 Jun 13 02:07 redis_6379.pid       # pid文件

-rw-r--r--. 1 redis redis   107 Jun 13 02:09 redis_6379.rdb       # 快照文件

 

.           二、(数据类型)

2.1、字符串

字符串是所有编程语言中最常见的和最常用的数据类型,而且也是redis最基本的数据类型之一,而且redis中所有的key的类型都是字符串。

2.1.1:添加一个key:

127.0.0.1:6379> set key1 value1

OK

127.0.0.1:6379> get key1

"value1"

127.0.0.1:6379> TYPE key1

string

 

2.1.2:获取一个key的内容:

127.0.0.1:6379> get key1

"value1"

 

2.1.3:删除一个key:

127.0.0.1:6379> DEL key1

(integer) 1

 

 

 

2.1.4:批量设置多个key:

127.0.0.1:6379> MSET key1 value1 key2 value2

OK

 

2.1.5:批量获取多个key:

127.0.0.1:6379> MSET key1 value1 key2 value2

OK

 

2.1.6:追加数据:

127.0.0.1:6379> APPEND key1 append

(integer) 12

127.0.0.1:6379> get key1

"value1append"

 

2.1.7:数值递增:

127.0.0.1:6379> set num 10

OK

127.0.0.1:6379> INCR num

(integer) 11

127.0.0.1:6379> get num

"11"

 

2.1.8:数值递减:

127.0.0.1:6379> set num 10

OK

127.0.0.1:6379> DECR num

(integer) 9

127.0.0.1:6379> get num

"9"

 

2.2:列表

2.2.1

192.168.9.71:6379> LPUSH list1 1 2 3    # 创建列表list1,并设置三个值,分别为 1 2 3

(integer) 3

2.2.2

192.168.9.71:6379> LLEN list1     # 查看list1的长度

(integer) 3

2.2.3:移除列表数据:

127.0.0.1:6379> RPOP list1 #最后一个

"1"

127.0.0.1:6379> LPOP list1 #第一个

"3"

 

 

 

2.3集合(set):

Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

2.3.1:生成集合key:

127.0.0.1:6379> SADD set1 v1

(integer) 1

127.0.0.1:6379> SADD set2 v2 v4

(integer) 2

127.0.0.1:6379> TYPE set1

set

127.0.0.1:6379> TYPE set2

set

 

2.3.2:追加数值:

追加的时候不能追加已经存在的数值

127.0.0.1:6379> SADD set1 v2 v3 v4

(integer) 3

127.0.0.1:6379> SADD set1 v2 #没有追加成功

(integer) 0

127.0.0.1:6379> TYPE set1

set

127.0.0.1:6379> TYPE set2

set

 

2.3.3:查看集合的所有数据:

127.0.0.1:6379> SMEMBERS set1

1) "v4"

2) "v1"

3) "v3"

4) "v2"

127.0.0.1:6379> SMEMBERS set2

1) "v4"

2) "v2"

 

2.2.4:获取集合的差集:

差集:已属于A而不属于B的元素称为A与B的差(集)

127.0.0.1:6379> SDIFF set1 set2

1) "v1"

2) "v3"

 

2.3.5:获取集合的交集:

交集:已属于A且属于B的元素称为A与B的交(集)

127.0.0.1:6379> SINTER set1 set2

1) "v4"

2) "v2"

 

2.3.6:获取集合的并集:

并集:已属于A或属于B的元素为称为A与B的并(集)

127.0.0.1:6379> SUNION  set1 set2

1) "v2"

2) "v4"

3) "v1"

4) "v3"

 

2.4其他命令

2.4.1:CONFIG:

config 命令用于查看当前redis配置、以及不重启更改redis配置等

2.4.1.1:更改最大内存:

127.0.0.1:6379> CONFIG set maxmemory 8589934592

OK

127.0.0.1:6379> CONFIG get maxmemory

1) "maxmemory"

2) "8589934592"

 

2.4.1.2:设置连接密码:

127.0.0.1:6379> CONFIG SET requirepass 123456

OK

 

 

2.4.1.3:或当前配置:

 

 

2.4.2:info:

显示当前节点redis运行状态信息

 

 

2.4.3:SELECT:

切换数据库

 

 

2.4.4:keys:

查看当前库下的所有key:

 

 

2.4.5:BGSAVE:

手动在后台执行RDB持久化操作

 

 

2.4.6:DBSIZE:

返回当前库下的所有key 数量

 

 

2.4.7:FLUSHDB:

强制清空当前库中的所有key

 

2.4.8:FLUSHALL:

强制清空当前redis服务器所有数据库中的所有key,即删除所有数据

 

.           三(高可用群集)

3.0先在其它两台也搭建一遍redis,然后做群集

主:

1.1.1.1 node1.com

       1.1.1.2 node2.com

       1.1.1.3 node3.com

3.1在从服务器上,配置主服务器的ip、端口和密码

[root@node1 ansible]# /usr/local/redis/bin/redis-cli -h 1.1.1.1 -a xuan    # 先在node1的redis中创建一些数据

1.1.1.1:6379> MSET a A b B c C d D e E

 

node2设置node1为主

[root@node2 ~]# vim /usr/local/redis/etc/redis.conf

286 # replicaof <masterip> <masterport>

 287 replicaof 1.1.1.1 6379   # 主的ip和端口

294 # masterauth <master-password>

 295 masterauth xuan   # 密码

[root@node2 ~]# systemctl restart redis

[root@node2 ~]# /usr/local/redis/bin/redis-cli -h 1.1.1.2 -a xuan

1.1.1.2:6379> keys *   # 可以看到node1设置的key 和 value

1) "c"

2) "b"

3) "a"

4) "d"

5) "e"

 

node3做和node2同样的配置

 

[root@node1 ansible]# /usr/local/redis/bin/redis-cli -h 1.1.1.1 -a xuan

1.1.1.1:6379> info   # 可以看到从的信息

role:master

connected_slaves:2

slave0:ip=1.1.1.2,port=6379,state=online,offset=644,lag=1

slave1:ip=1.1.1.3,port=6379,state=online,offset=644,lag=1

 

 

3.3:哨兵

Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。哨兵(Sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,英文名称:Subjective Down,简称SDOWN。有主观宕机,肯定就有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出 SDOWN 的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。

 

3.1:参数解释

bind 0.0.0.0   # 监听的ip

port 26379  # 监听的端口

daemonize yes    # 启用后台进程

pidfile "/usr/local/redis/data/redis-sentinel.pid"        # PID文件的位置

logfile "/usr/local/redis/data/redis-sentinel.log"     # 日志文件的位置

requirepass "sentinel"       # 连接的密码

dir "/usr/local/redis"          # 相对目录

sentinel monitor mymaster 1.1.1.1 6379 2      # master哨兵的ip和端口,最后的2代表2台主机认为master主观宕机,则将主下线

sentinel auth-pass mymaster xuan      # 发送给master的密码

sentinel down-after-milliseconds mymaster 30000 #(SDOWN)主观下线的时间

sentinel parallel-syncs mymaster 1  #发生故障转移时候同时向新master同步数据的slave数量,数字越小总同步时间越长

sentinel failover-timeout mymaster 180000 #所有slaves指向新的master所需的超时时间

 

 

3.2sentinel配置

[root@node1 ~]# cp /root/redis-5.0.3/sentinel.conf /usr/local/redis/etc/     # 复制配置文件

[root@node1 ~]# vim /usr/local/redis/etc/sentinel.conf   # 编辑配置文件

bind 0.0.0.0

port 26379

daemonize yes

dir "/usr/local/redis"

pidfile "data/redis-sentinel.pid"

logfile "data/redis-sentinel.log"

sentinel deny-scripts-reconfig yes

sentinel monitor mymaster 1.1.1.4 6379 2

sentinel auth-pass mymaster xuan

sentinel down-after-milliseconds mymaster 10000

 

[root@node1 ~]#/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf   # 启动,其他两台也做相同操作

 

[root@node1 ~]# /usr/local/redis/bin/redis-cli -h 1.1.1.1 -p 26379   # 三台设置完成之后连接

# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=mymaster,status=ok,address=1.1.1.1:6379,slaves=2,sentinels=3    # 名字:mymaster,状态OK,地址:1.1.1.1,有两个从,哨兵有三个

[root@node1 ~]# systemctl stop redis.service   # 关闭主的redis

[root@node1 ~]# /usr/local/redis/bin/redis-cli -h 1.1.1.1 -p 26379   # 再次进入

# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=mymaster,status=ok,address=1.1.1.4:6379,slaves=2,sentinels=3   # 主已经切换到4了,redis.conf的配置文件也会被修改

 

 

 

 

问题:配置完三台哨兵之后,无法查看info信息,显示的哨兵数量低于三台

 

这个是因为sentinel的自动生成的配置项myid一样,可以使用以下命令生成随机字符

openssl rand -base64 40 | tr -dc '[:alnum:]' | head -c 40   # 然后重启sentinel即可

 

 

          mamcache

.           一、安装libevent

 

 

 

1.1:安装依赖包: yum install gcc gcc-c++ automake

1.2:下载:wget https://github.com/libevent/libevent/releases/download/release-2.1.10-stable/libevent-2.1.10-stable.tar.gz

1.3:编译安装

[root@node5 ~]# tar xf libevent-2.1.10-stable.tar_2.g

[root@node5 libevent-2.1.10-stable]#  ./configure   --prefix=/usr/local/libevent

[root@node5 libevent-2.1.10-stable]# make && make install

[root@node5 ~]# tar xf memcached-1.2.8-repcached-2.2.tar.gz

[root@node5 ~]# cd memcached-1.2.8-repcached-2.2/

 

[root@node6 ~]#tar xf memcached-1.2.8-repcached-2.2.tar.gz

[root@node6 ~]#cd memcached-1.2.8-repcached-2.2/

[root@node6 memcached-1.2.8-repcached-2.2]#./configure  --prefix=/usr/local/repcached --enable-replication

# vim memcached.c 
  55 /* FreeBSD 4.x doesn't have IOV_MAX exposed. */
  56 #ifndef IOV_MAX
  57 #if defined(__FreeBSD__) || defined(__APPLE__)
  58 # define IOV_MAX 1024
  59 #endif
  60 #endif
改为如下内容:
  55 /* FreeBSD 4.x doesn't have IOV_MAX exposed. */
  56 #ifndef IOV_MAX   
  57 # define IOV_MAX 1024   
  58 #endif 
#make && make install

 

/usr/local/repcached/bin/memcached  -d -m 1024 -p 11211  -u root -c 1024 -x 192.168.10.102 -X 16000

 

 

 

 

          Mariadb

官网下载:https://downloads.mariadb.org/mariadb/+releases/

解压

预编译

cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mariadb-10.3.3 -DMYSQL_DATADIR=/mydata/data -DSYSCONFDIR=/etc -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DWITH_SSL=system -DWITH_ZLIB=system -DWITH_LIBWRAP=0 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITHOUT_TOKUDB=1

make

make install

[root@C7_2 local]#cd /usr/local

[root@C7_2 local]#groupadd -r -g 3306 mysql

[root@C7_2 local]#useradd -r -g 3306 -u 3306 mysql

[root@C7_2 local]#chown –R mysql:mysql /mydata

[root@C7_2 local]#chown –R root:mysql mariadb-10.3.3

[root@C7_2 local]#cd mariadb

[root@C7_2 mariadb]#./scripts/mysql_install_db --user=mysql --datadir=/mydata/data

[root@C7_2 mariadb]#cat /etc/mysql/my.cnf

[mysqld]

user = mysql

port=3306

socket          = /tmp/mysql.sock

skip-external-locking

key_buffer = 256M

max_allowed_packet = 256M

table_open_cache = 256

skip_name_resolve = ON

read_buffer_size = 256K

read_rnd_buffer_size = 512K

basedir = /usr/local/mariadb

 

datadir = /mydata/data

innodb_file_per_table = ON

[mysqldump]

quick

max_allowed_packet = 16M

 

[mysql]

no-auto-rehash

 

[myisamchk]

key_buffer_size = 64M

sort_buffer_size = 1M

read_buffer = 2M

write_buffer = 2M

 

[mysqlhotcopy]

interactive-timeout

 

[root@C7_2 mariadb]#cp support-files/mysql.server /etc/init.d/mysqld

[root@C7_2 mariadb]#chmod +x /etc/init.d/mysqld

[root@C7_2 mariadb]#chkconfig +x /etc/init.d/mysqld

[root@C7_2 mariadb]#systemctl restart  mysqld

 

 

          mysql读写分离

.           一、配置主从

主服务器配置

[root@C7-1 ~]#vim /etc/my.cnf

 

[mysqld]

#skip-grant-tables

server-id=11

log-bin=master-bin

log-slave-updates=true

[root@C7-1 ~]#systemctl restart mariadb

[root@C7-1 ~]#mysql -uroot -ppwd123 -e "grant replication slave on *.* to 'sqlslave'@'192.168.9.%' identified by 'sql123';"

[root@C7-1 ~]#mysql -uroot -ppwd123 -e "flush privileges;"

[root@C7-1 ~]#mysql -uroot -ppwd123 -e "show master status;"

+-------------------+----------+--------------+------------------+

| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+-------------------+----------+--------------+------------------+

| master-bin.000001 |      476 |              |                  |

+-------------------+----------+--------------+------------------+

 

 

注释:

系统默认采用基于语句的复制类型

 

1:基于语句的复制。 在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。配置:binlog_format = STATEMENT

 

2:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍,从 MySQL 5.0开始支持,配置:binlog_format = ROW

 

3:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制,配置:binlog_format = MIXED

 

log-slave-updates=true     #Slave可以是其他 Slave 的 Master,从而扩散 Master 的更新

binlog-ignore-db=test      #不记录指定的数据库的二进制日志 
replicate-ignore-db=test    #设置不需要同步的库
binlog_cache_size = 1M    #日志缓存的大小
expire_logs_days=3       #自动过期清理日志的天数

以上参数在[mysqld]模块中设置

 

从服务器配置

[root@C7-2 ~]#vim /etc/my.cnf

[mysqld]

#skip-grant-tables

server-id=22

relay-log=relay-log-bin

relay-log-index=slave-relay-bin.index

[root@C7-2 ~]#systemctl restart mariadb

[root@C7-2 ~]#mysql -uroot -pdong9205 -e "change master to master_host='192.168.9.71',master_user='sqlslave',master_password='sql123',master_log_file='master-bin.000001',master_log_pos=476;"

[root@C7-2 ~]#mysql -pdong9205 -e "start slave"         

[root@C7-2 ~]#mysql -pdong9205 -e "show slave status\G;"

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

 

 

注释: Slave 的 IO 线程接收到信息后,将接收到的日志内容依次写入到 Slave 端的Relay Log文件(relay-log-bin.xxxxxx)的最末端,并将读取到的Master端的master-bin的文件名和位置记录到master- info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个master-bin的哪个位置开始往后的日志内容,请发给我

 

验证主从

[root@C7-2 ~]#mysql -pdong9205 -e "show databases"    # 查看从的数据库

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| test               |

+--------------------+

[root@C7-1 ~]#mysql -ppwd123 -e "create database bbb;"      # 在主创建数据库

[root@C7-2 ~]#mysql -pdong9205 -e "show databases"        # 再次查看从的数据库

+--------------------+

| Database           |

+--------------------+

| information_schema |

| bbb                |

| mysql              |

| performance_schema |

| test               |

+--------------------+

 

 

 

.           二、搭建读写分离(mysql-proxy)

场景描述:


数据库Master主服务器:192.168.9.71

数据库Slave从服务器:192.168.9.72
MySQL-Proxy调度服务器:192.168.9.74

 

 

依赖包

# yum install gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig* libevent* glib* readline-devel

 

编译安装lua

MySQL-Proxy的读写分离主要是通过rw-splitting.lua脚本实现的,因此需要安装lua。

lua可通过以下方式获得
从http://www.lua.org/download.html下载源码包

[root@c7-4 lua-5.3.5]#curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz

[root@c7-4 lua-5.3.5]#tar zxf lua-5.3.5.tar.gz

[root@c7-4 lua-5.3.5]#cd lua-5.3.5

[root@c7-4 lua-5.3.5]# make linux

[root@c7-4 lua-5.3.5]# make install

 

1、安装mysql-proxy
实现读写分离是有lua脚本实现的,现在mysql-proxy里面已经集成,无需再安装

下载:http://dev.mysql.com/downloads/mysql-proxy/ 一定要下载对应的版本

tar zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz

[root@c7-4 ~]# mv mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit /usr/local/mysql-proxy

[root@c7-4 ~]# cd /usr/local/mysql-proxy/

[root@c7-4 mysql-proxy]# mkdir lua

[root@c7-4 mysql-proxy]# cp share/doc/mysql-proxy/rw-splitting.lua ./lua/

[root@c7-4 mysql-proxy]# cp share/doc/mysql-proxy/admin-sql.lua ./lua/

[root@c7-4 mysql-proxy]# vim /etc/mysql-proxy.cnf

[mysql-proxy]

user=root #运行mysql-proxy用户

admin-username=lin3615 #主从mysql共有的用户

admin-password=123456 #用户的密码

proxy-address=192.168.179.142:4040 #mysql-proxy运行ip和端口,不加端口,默认4040

proxy-read-only-backend-addresses=192.168.179.147 #指定后端从slave读取数据

proxy-backend-addresses=192.168.179.146 #指定后端主master写入数据

proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua #指定读写分离配置文件位置

admin-lua-script=/usr/local/mysql-proxy/lua/admin-sql.lua #指定管理脚本

log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log #日志位置

log-level=info #定义log日志级别,由高到低分别有(error|warning|info|message|debug)

daemon=true    #以守护进程方式运行

keepalive=true #mysql-proxy崩溃时,尝试重启

[root@c7-4 mysql-proxy]# chmod 660 /etc/mysql-proxy.cnf

 

修改读写分离文件

vim /usr/local/mysql-proxy/lua/rw-splitting.lua

if not proxy.global.config.rwsplit then

 proxy.global.config.rwsplit = {

  min_idle_connections = 1, #默认超过4个连接数时,才开始读写分离,改为1

  max_idle_connections = 1, #默认8,改为1

  is_debug = false

 }

end

 

 

 

启动

# /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnf

[root@c7-4 mysql-proxy]# ss -tnlp | grep 6603

LISTEN     0      128    192.168.9.74:6603                     *:*                   users:(("mysql-proxy",pid=5254,fd=10))

 

 

测试

[root@C7-1 centos]#mysql -ppwd123 -e "grant all on *.* to 'proxyuser'@'%' identified by 'proxypass';"

[root@C7-1 centos]#mysql -uroot -ppwd123

MariaDB [(none)]> use bbb

MariaDB [bbb]> CREATE TABLE `name`  (

    ->   `序号` int(255) NOT NULL AUTO_INCREMENT,

    ->   `姓名` varchar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,

    ->   PRIMARY KEY (`序号`) USING BTREE

    -> ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;

Query OK, 0 rows affected (0.00 sec)

MariaDB [bbb]> insert name(姓名) value("Jerry");

[root@C7-2 ~]#mysql -pdong9205 -e "use bbb;select * from name;"

+--------+--------+

| 序号   | 姓名   |

+--------+--------+

|      1 | Jerry  |

+--------+--------+

[root@C7-2 ~]#mysql -pdong9205 -e "stop slave;"     # 关闭主从

[root@C7-2 ~]#mysql -uproxyuser -pproxypass -h192.168.9.74 -P6603    # 连接mysql-proxy

MariaDB [(none)]> use bbb

Database changed

MariaDB [bbb]> insert name(姓名) value("Tom");

Query OK, 1 row affected (0.00 sec)

 

MariaDB [bbb]> select * from name;    # 查看表的时候发现,并没有新插入的数据,然后分别登录主从查看即可

+--------+--------+

| 序号   | 姓名   |

+--------+--------+

|      1 | Jerry  |

+--------+--------+

1 row in set (0.00 sec)

 

 

 

 

 

 

 

 

          rsyslog

多线程

 

 

 

 

 

 

 

          ELK日志分析系统

.           ELK简介

splunk:收费 500M 国内站点

elk是三款软件

E:Elasticsearch(弹性搜索),Java开发,开源,在这里用于日志存储

       L:logstash(日志贮藏):开源,这里用于收集日志

       K:kibana(基巴呐),这里用于日志展示

 

.           ELK环境初始化

1.   可以解析,配置hosts文件或者搭建dns服务,关闭防火墙,selinux

2.   打开文件的最大限制

[root@C7-1 ~]#echo "* soft nofile 65536" >> /etc/security/limits.conf

[root@C7-1 ~]#echo "* hard nofile 65536" >> /etc/security/limits.conf 

*              soft   nofile         655350      #表示任何一个用户可以打开的最大的文件描述符数量

*             hard    nofile         655350

 

 

.           Elasticsearch安装

配置文件

[root@C7-2 elk]#yum install jdk-8u151-linux-x64.rpm elasticsearch-5.6.5.rpm

[root@C7-2 elk]#vim /etc/elasticsearch/elasticsearch.yml

cluster.name: p-pp.cn                      # 群集名字

node.name: C7-1                             # 当前节点的名字

path.data: /usr/src/elk/data             # 数据存放的路径

path.logs: /usr/src/elk/ log                # 日志存放的路径

bootstrap.memory_lock: true          # 锁定内存

network.host: 192.168.9.71              # 监听的接口ip

http.port: 9200                                  # 监听的端口

discovery.zen.ping.unicast.hosts: ["C7-1", "C7-2"]           # 群集的所有节点,可以使主机名,可以使ip

[root@C7-2 ~]#sed -i '39a\LimitMEMLOCK=infinity' /usr/lib/systemd/system/elasticsearch.service           # 如果开启了锁定内存,则需要开启这个

[root@C7-2 ~]#systemctl daemon-reload

[root@C7-2 elk]#chown elasticsearch: ./data/ ./log/

[root@C7-2 elk]#systemctl start elasticsearch.service

浏览器访问

 

[root@C7-2 elk]#tar xf elasticsearch-head.tar.gz

[root@C7-2 elk]#cd elasticsearch-head/

[root@C7-2 elasticsearch-head]#ll node_modules/grunt            # 确认是否有文件

[root@C7-2 elasticsearch-head]#yum install npm -y

[root@C7-2 elasticsearch-head]#npm run start &

[root@C7-2 elasticsearch-head]#echo -e 'http.cors.enabled: true\nhttp.cors.allow-origin: "*"' >> /etc/elasticsearch/elasticsearch.yml

[root@C7-2 ~]#systemctl restart elasticsearch.service

使用浏览器访问

 

 

 

 

 

测试提交数据

 

查看是否创建了索引

 

 

查看数据

 

 

群集状态

[root@C7-2 ~]#systemctl stop elasticsearch.service

[root@C7-2 elk]#curl -sXGET http://192.168.9.71:9200/_cluster/health?pretty=true

{

  "cluster_name" : "p-pp.cn",

  "status" : "yellow",        # 黄色了,就说明有问题了

  "timed_out" : false,

  "number_of_nodes" : 1,

  "number_of_data_nodes" : 1,

  "active_primary_shards" : 5,

  "active_shards" : 5,

  "relocating_shards" : 0,

  "initializing_shards" : 0,

  "unassigned_shards" : 5,

  "delayed_unassigned_shards" : 0,

  "number_of_pending_tasks" : 0,

  "number_of_in_flight_fetch" : 0,

  "task_max_waiting_in_queue_millis" : 0,

  "active_shards_percent_as_number" : 50.0

}

 

使用python监控群集状态

[root@C7-2 script]#vim elk_status.py

#!/usr/bin/env python

import subprocess

body = ""

false="false"                                                                                                                              

obj = subprocess.Popen(("curl -sXGET http://192.168.9.71:9200/_cluster/health?pretty=true"),shell=True, stdout=subprocess.PIPE)

data =  obj.stdout.read()

data1 = eval(data)

status = data1.get("status")

if status == "green":

    print "50"                  # 如果执行python代码为50,则群集没有问题

else:

    print "100"

[root@C7-2 script]#python elk_status.py

100

[root@C7-2 script]#systemctl start elasticsearch.service

[root@C7-2 script]#python elk_status.py

50

.           logstash安装

[root@C7-2 elk]#yum install logstash-5.6.5.rpm -y

[root@C7-2 elk]#/usr/share/logstash/bin/logstash --help       # 安装之后会有这个命令

-t:检测配置文件,需要结合-f

-f file 指定配置文件

-e:可以直接进行shell命令

 

logstatsh测试

标准输入输入

[root@C7-2 elk]#/usr/share/logstash/bin/logstash -e 'input {stdin{}} output {stdout{code => "rubydebug"}} '

123        # 输入123

{

      "@version" => "1",            # 第一次输入

          "host" => "C7-2.p-pp.cn",             # 这个事件发生在那个主机上

    "@timestamp" => 2019-04-29T17:37:03.632Z,            # 事件

       "message" => "123"        # 内容

}

输出到文件

[root@C7-2 elk]#/usr/share/logstash/bin/logstash -e 'input {stdin{}} output {file{path => "/tmp/logstash.txt"}} '

aaa

bbb

[root@C7-2 ~]#tail -f /tmp/logstash.txt

{"@version":"1","host":"C7-2.p-pp.cn","@timestamp":"2019-04-29T17:40:56.226Z","message":"aaa"}

{"@version":"1","host":"C7-2.p-pp.cn","@timestamp":"2019-04-29T17:41:06.311Z","message":"bbb"}

 

修改配置文件,自动写到elasticsearch

[root@C7-2 elk]#vim /etc/logstash/conf.d/system_log.conf

input {

        file {

                path => "/var/log/messages"

                start_position => "beginning"

                type => "systemlog-0972"

                stat_interval => "2"

        }

}

 

output {

        elasticsearch {

                hosts => ["192.168.9.71:9200"]

                index => "logstash-system-log-0972-%{+YYYY.MM.dd}"

        }

               file {

                path => "/tmp/123.txt"

        }

}

[root@C7-2 elk]#chmod +r /var/log/messages

[root@C7-2 elk]#systemctl restart logstash.service

[root@C7-2 elk]#ll /tmp/123.txt

-rw-r--r--. 1 logstash logstash 1065416 4月  30 02:18 /tmp/123.txt

浏览器访问

 

 

 

.           Kibana的安装

[root@C7-1 elk]#yum install kibana-5.6.5-x86_64.rpm

配置

[root@C7-1 elk]#vim /etc/kibana/kibana.yml

server.port: 5601

server.host: "192.168.9.71"            # 这项如果不是测试,尽量处于关闭状态,否则谁都可以访问

elasticsearch.url: "http://192.168.9.72:9200"

[root@C7-1 elk]#systemctl start kibana.service

浏览器访问

 

 

 

 

 

 

 

 

 

.           配置Nginx代理Kibana

因为直接让每个人都可以访问Kibana会不安全,所以使用nginx代理,nginx可以指定密码等功能

 

 

 

          Docker

.           一、容器

容器是一种基础工具;泛指任何可用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳、存储、运输物品;

人类使用容器的历史至少有十万年,甚至有数百万年的历史

如:瓶、罐、箱、桶、袋

.            二、LXC

主机级虚拟化

       Type-I:

       Type-II:VMware、kvm、zen

 Linux Namespace:

UTS:以名称空间为单位进行隔离,在同一个内核上创建多个名称空间,每个空间可以有单独的名称

Mount:也是名称空间,可以把挂载的文件系统切分为多个

IPC:内核级管理的资源,可以再内核切换为Docker,每一个里边的进程可以IPC通信,但是不能跨边界

PID:不同用户的进程就是通过pidnamespace隔离开的,且不同 namespace 中可以有相同PID

User:每个container可以有不同的 user 和 group id, 也就是说可以以container内部的用户在container内部执行程序而非Host上的用户。

Net:有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过netnamespace实现的

 

nmp

machine + swarm + compose

mesos + marathon

kubernetes à k8s

 

.           三、Docker 的安装使用

安装

       清华大学镜像网源:wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

       [root@C7-1 yum.repos.d]#vim docker-ce.repo

       %s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@g            # 下载后是docker的官方源,修改为清华大学源

       yum install docker-ce            # 安装

 

配置文件

       docker-ce:/etc/docker/daemon.json

docker镜像加速

       docker cn

       阿里云加速器

       中国科技大学

{

  "registry-mirrors": ["https://registry.docker-cn.com"]

}

配置加速

[root@C7-1 ~]#mkdir /etc/docker

[root@C7-1 ~]#vim /etc/docker/daemon.json

 

docker

       docker version

       docker info

常用操作

docker search:搜索

docker pull:下载到本地

              [root@C7-1 ~]#docker pull quay.io/coreos/flannel:v0.11.0-arm64

docker images:

       [root@C7-1 ~]#docker image pull nginx:1.14-alpine         # 下载镜像

       [root@C7-1 ~]#docker image ls         # 查看下载的镜像

       docker container:

              docker container run            # 创建并启动

                     -t:打开tty终端

                     -i:交互式

                     --name:名字

                     --network:网络

                     --rm :停止容器后直接删除

                     -d --detach:后台

                     --network string  # 设置网络

                     --rm   # 删除

                     -h,--hostname string  # 设置主机名

                     --dns list  # 设置dns,默认与宿主机相同

                     --dns-search   # dns搜索域

                     --add-host www.p-pp.cn:2.2.2.2  3 设置hosts文件

                     -p, --publish list       #暴露端口

-p <container:Port> :将那个端口做转换,会使用随机端口转为容器端口

-p <hostPort>:<containterPort>:将本机的那个端口转换为容器的那个端口

-p <ip>::<containerPort>:只将那个端口做转换

-p <ip>:<hostPort>:<containerPort>

                     -P, --publish-all   # 暴露所有端口

              docker container exec

                     [root@C7-1 ~]#docker container exec -it p1 /bin/sh

       docker commit    # 制作镜像

              -a --author string:作者

              -c --change list:修改原有基础镜像的指令

              -p --pause:现将容器暂停

       docker tag         # 打标签

       docker push

       docker login

              -u,--username    用户名   registry.cn-hangzhou.aliyuncs.com   后便可以跟服务器地址

       docker logout

       docker save    导出

              -o:名字

       docker load    导入

 

docker network

              docker network ls   # 查看网络
              docker network inspect bridge        # 查看bridge网络的相关信息

              docker network create   # 创建桥

                     -d, --driver string

                     --subnet

                     --gateway

 

docker inspect

docker inspect web1

docker port             # 后边跟容器名,可以查看端口映射

 

使用例子

[root@C7-1 ~]#docker pull busybox    # 下载

[root@C7-1 ~]#docker image pull nginx:1.14-alpine

[root@C7-1 ~]#docker container run --name b1 -it busybox:latest    # latest是标签

[root@C7-1 ~]#docker container run --name web1 -d nginx:1.14-alpine    # 后台运行

[root@C7-1 ~]#docker container run --name kvstor1 -d redis:4-alpine    # 如果没有则会从网络中下载

[root@C7-1 ~]#docker container exec -it kvstor1 /bin/sh     # 进入容器的终端

 

 

 

 

 

联合挂载使用到的文件

       Aufs(advanced multi-layered unfication filesystem):高级多层统一文件系统,Aufs是之前UnionFS的重新实现,由Junjiro Okajima开发

       Storage:现在Centos7使用的就只这种文件系统,overlay2需要建立在也已经用的文件系统上,所以在Cetno7中,前端使用overlay2后端使用xfs

 

 

 

 

Registry

       由某特定的docker镜像的所有迭代版本组成的镜像仓库

       每个仓库明可以包含多个tag,每个tag对应一个镜像,每个镜像可以对应多个tag

 

 

制作镜像:docker commit

       生成途径

              dockerfile

              基于容器制作

              Docker Hub automated builds

       居于容器制作:

[root@C7-1 ~]#docker run --name b1 -it busybox    # 制作一个容器

/ # mkdir -p /data/html      # 创建目录

/ # echo "<h1>busybox httpd server.</h1>" > /data/html/index.html   # 创建主页文件

# 再开一个终端,应为如果退出的话容器就会停止

[root@C7-1 ~]#docker commit -p b1           # -p暂停容器

[root@C7-1 ~]#docker image ls   # 查看

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE

<none>                   <none>              7cfd827c15d4        6 seconds ago       1.2MB

[root@C7-1 ~]#docker tag 7cfd827c15d4 p-pp/busybox_httpd:v0.1-1    # 打标签

[root@C7-1 ~]#docker image ls   # 打完标签后查看

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE

p-pp/busybox_httpd       v0.1-1              7cfd827c15d4        2 minutes ago       1.2MB

[root@C7-1 ~]#docker tag p-pp/busybox_httpd:v0.1-1 p-pp/busybox_httpd:latest   # 打一个新的标签

[root@C7-1 ~]#docker image ls    # 再次查看,可以看到两个,Id是一样的

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE

p-pp/busybox_httpd       latest              7cfd827c15d4        4 minutes ago       1.2MB

p-pp/busybox_httpd       v0.1-1              7cfd827c15d4        4 minutes ago       1.2MB

 

[root@C7-1 ~]#docker commit  -a "Mrxuan<www.p-pp.cn>"  -c 'CMD [ "/bin/httpd","-f","-h","/data/html" ]' -p b1 p-pp/busybox_httpd:v0.2-1

[root@C7-1 ~]#docker run --name p2 p-pp/busybox_httpd:v0.2-1

 

# 再打开一个终端,使用命令查看ip

[root@C7-1 ~]#docker inspect p2

                    "Gateway": "172.17.0.1",

                    "IPAddress": "172.17.0.3",

[root@C7-1 ~]#curl 172.17.0.3

<h1>busybox httpd server.</h1>

 

 

将自己的docker镜像保存至dockerhub:docker push

申请账号:https://hub.docker.com/signup

 

 

       示例:

[root@C7-1 ~]#docker login -u dong9205   #登录,用户名为dong9205

Password:

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Configure a credential helper to remove this warning. See

https://docs.docker.com/engine/reference/commandline/login/#credentials-store

 

Login Succeeded    # 登录成功的提示

[root@C7-1 ~]#docker image ls    # 名字要和创建的仓库名一致

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE

dong9205/busybox         v0.2-1              8f6be032912d        31 minutes ago      1.2MB

dong9205/busybox         v0.1-1              7cfd827c15d4        About an hour ago   1.2MB

[root@C7-1 ~]#docker push dong9205/busybox   # 像dockerhub推送

 

 

 

 

       镜像推到阿里云仓库

注册阿里云账号,之后打开网站:https://cr.console.aliyun.com,或https://dev.aliyun.com

 

 

 

 

 

 

 

 

[root@C7-1 ~]#docker tag dong9205/busybox:v0.2-1 registry.cn-hangzhou.aliyuncs.com/dong9205/busybox:v0.2-1   #标签更改一致

[root@C7-1 ~]#docker logout   # 退出dockerhub的账号

[root@C7-1 ~]#docker login --username=socket轩 registry.cn-hangzhou.aliyuncs.com    # 登录,密码为单独设置的密码

Password:

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Configure a credential helper to remove this warning. See

https://docs.docker.com/engine/reference/commandline/login/#credentials-store

 

Login Succeeded

[root@C7-1 ~]#docker push registry.cn-hangzhou.aliyuncs.com/dong9205/busybox   # 推送

 

 

 

 

镜像的导入导出

[root@C7-1 ~]#docker save -o myimages.gz dong9205/busybox:v0.2-1 dong9205/busybox:v0.1-1

[root@C7-1 ~]#docker load -i myimages.gz

 

 

 

.           容器虚拟化网络概述

     OVS:OpenVSwitch

 

Docker的网络其实是创建了一对虚拟网卡,一半在宿主机上,一半在docker容器上,使用ifconfig可以看到

[root@C7-1 ~]#brctl show           # 可以看到绑定在虚拟网桥的接口

 

四种网络模型

       closed container:封闭式容器,只有lo接口

       Bridged container:桥接式容器,通过容器接口,连接到docker0,默认为此网络

       joined container:联盟式容器,两个容器一部分隔离,隔离:User、PID、Mount,共用同一组:UTS、Net、IPC

       Open container:直接共享物理机的,物理机有哪些,他就可以看到那些

 

ip netns:网络名称空间

Usage: ip netns list    # 查看列表

       ip netns add NAME   # 添加一个网络名称空间

       ip netns set NAME NETNSID   # 设置网络名称空间

       ip [-all] netns delete [NAME]

       ip netns identify [PID]

       ip netns pids NAME

       ip [-all] netns exec [NAME] cmd ...   # 在网络名称空间中执行命令

       ip netns monitor

       ip netns list-id

[root@C7-2 ~]#ip netns add r1     # 添加一个网络名称空间

[root@C7-2 ~]#ip netns add r2

[root@C7-2 ~]#ip netns list     # 列出

r2

r1

[root@C7-2 ~]#ip netns exec r1 ip a    # 查看网络名称空间r1的网卡,默认只有lo

 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

 

 

 

ip link:可以使用iplink创建虚拟网卡并移动到名称空间中

[root@C7-2 ~]#ip link add name veth1.1  type veth peer name veth1.2   # 创建虚拟网卡对,名字veth1.1的对端名字是veth1.2,类型是veth

 

[root@C7-2 ~]#ip link show      # 查看

3: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

    link/ether 0a:72:a0:ce:92:06 brd ff:ff:ff:ff:ff:ff

4: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

link/ether fa:d2:fc:8a:6c:df brd ff:ff:ff:ff:ff:ff

 

[root@C7-2 ~]#ip link set veth1.2 netns r1    # 将虚拟网卡移动到名称空间r1中

[root@C7-2 ~]#ip addr add 192.168.12.1/24 dev veth1.1    # 设置ip

[root@C7-2 ~]#ip netns exec r1 ip link set veth1.2 name eth0   # 修改网络空间r1中veth1.2的网卡名称

[root@C7-2 ~]#ip netns exec r1 ifconfig eth0 192.168.12.2/24 up    # 设置ip并激活

[root@C7-2 ~]#ip netns exec r1 ping 192.168.12.1     # 进行通信

PING 192.168.12.1 (192.168.12.1) 56(84) bytes of data.

64 bytes from 192.168.12.1: icmp_seq=1 ttl=64 time=0.015 ms

[root@C7-2 ~]#ip link set veth1.1 netns r2       # 将网卡移动到名称空间r2

[root@C7-2 ~]#ip netns exec r2 ifconfig veth1.1 192.168.12.3/24 up    # 设置ip并激活

[root@C7-2 ~]#ip netns exec r2 ifconfig    #查看

veth1.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

        inet 192.168.12.3  netmask 255.255.255.0  broadcast 192.168.12.255

        inet6 fe80::f8d2:fcff:fe8a:6cdf  prefixlen 64  scopeid 0x20<link>

        ether fa:d2:fc:8a:6c:df  txqueuelen 1000  (Ethernet)

        RX packets 20  bytes 1488 (1.4 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 28  bytes 2136 (2.0 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@C7-2 ~]#ip netns exec r2 ping 192.168.12.2  # 测试与r1通信

PING 192.168.12.2 (192.168.12.2) 56(84) bytes of data.

64 bytes from 192.168.12.2: icmp_seq=1 ttl=64 time=0.027 ms

 

启动时设置网络

[root@c7-3 ~]#docker container run --name p1 -it --network bridge --rm dong9205/busybox:v0.1-1  # 默认也是bridge

[root@c7-3 ~]#docker container run --name p1 -it --network none --rm dong9205/busybox:v0.1-1  # 没有网络,封闭式容器

/ # ifconfig -a

lo        Link encap:Local Loopback 

          inet addr:127.0.0.1  Mask:255.0.0.0

          UP LOOPBACK RUNNING  MTU:65536  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

 

[root@c7-3 ~]#docker container run --name p1 -it --network bridge -h p1.p-pp.cn --rm dong9205/busybox:v0.1-1  # 设置主机名

/ # hostname   # 查看主机名

p1.p-pp.cn

 

[root@c7-3 ~]#docker container run --name p1 -it --network bridge -h p1.p-pp.cn --dns 1.1.1.1 --dns-search qqq.cn --rm dong9205/busybox:v0.1-1   # 设置dbs和dns search

/ # cat /etc/resolv.conf

search qqq.cn

nameserver 1.1.1.1

[root@c7-3 ~]#docker container run --name p1 -it --network bridge -h p1.p-pp.cn --dns 1.1.1.1 --dns-search qqq.cn --add-host www.p-pp.cn:2.2.2.2 --rm dong9205/busybox:v0.1-1  # 添加hosts解析记录

/ # cat /etc/hosts

127.0.0.1       localhost

::1     localhost ip6-localhost ip6-loopback

fe00::0 ip6-localnet

ff00::0 ip6-mcastprefix

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

2.2.2.2 www.p-pp.cn

172.17.0.2      p1.p-pp.cn p1

 

暴露:-p

      

[root@c7-3 ~]#docker container run --name p1 --network bridge -p 80 --rm dong9205/busybox:v0.2-1   # 暴露80端口

[root@c7-3 ~]#iptables -t nat –vnL   # 查看nat表,docker链中定义了当访问所有端口的32769端口时,会映射为172.17.0.2的80端口

Chain DOCKER (2 references)

 pkts bytes target     prot opt in     out     source               destination        

    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0          

0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:32769 to:172.17.0.2:80

这个时候可以使用浏览器访问虚拟机的物理端口的32769端口

 

 

[root@c7-3 ~]#docker port p1   # 可以看出,将所有32769都做了映射

80/tcp -> 0.0.0.0:32769

[root@c7-3 ~]#docker container run --name p1 --network bridge -p 80:80 --rm dong9205/busybox:v0.2-1  # 80映射为容器的80端口

[root@c7-3 ~]#docker port p1  # 查看       

80/tcp -> 0.0.0.0:80

[root@c7-3 ~]#docker container run --name p1 --network bridge -p 192.168.9.73::80 --rm dong9205/busybox:v0.2-1    # 可以指定那个ip

[root@c7-3 ~]#docker port p1   # 再次查看

80/tcp -> 192.168.9.73:32768

[root@c7-3 ~]#docker container run --name p1 --network bridge -p 192.168.9.73:80:80 --rm dong9205/busybox:v0.2-1

[root@c7-3 ~]#docker port p1

80/tcp -> 192.168.9.73:80

 

 

联盟式容器(joined container):四种网络模型的一种,共享UTS、NET、IPC

[root@c7-3 ~]#docker container  run --name p1 -it --rm dong9205/busybox:v0.1-1  # 启动第一个容器

一、

/ # ls /tmp/testdir/

/ # ls /tmp/

testdir

二、

/ # wget -O - 127.0.0.1 –q  # 可以以访问本机的方式访问第二台容器启动的web

hello world

[root@c7-3 ~]#docker container run --name p2 -it --network container:p1 --rm dong9205/busybox:v0.1-1

一、

/ # ls /tmp/    # 没有在第一个容器中创建的文件夹

二、

/ # echo hello world > /tmp/index.html

/ # httpd -h /tmp

 

 

# 第四种网络模型

[root@c7-3 ~]#docker container run --name p2 -it --network host --rm dong9205/busybox:v0.1-1   # 共享宿主机的

 

 

 

 

更改docker0桥的地址

[root@c7-3 ~]#vim /etc/daemon.json

{

  "registry-mirrors": ["https://hks9tjx0.mirror.aliyuncs.com"],

  "bip": "192.168.17.1/24",    # docker0的网卡ip

  "fixed-cidr": "10.20.0.0/16", 

  "mtu": 1500,

  "default-gateway": "10.20.1.1",

  "default-gateway-v6": "2001::1",

  "dns": ["10.20.1.2","10.20.1.3"]   # dns

}

 

 

设置docker server监听地址和端口

vim /etc/docker/daemon.json

{

  "registry-mirrors": ["https://hks9tjx0.mirror.aliyuncs.com"],

  "bip": "192.168.17.1/24",

  "dns": ["192.168.9.7","1.1.1.1"],

  "hosts": ["tcp://0.0.0.0:9205","unix:///var/run/docker.sock"]     # 设置监听地址端口和sock文件                                                                 

}

[root@c7-3 ~]#docker container  run --name p1 -it --rm dong9205/busybox:v0.1-1   # 启动一台容器

[root@C7-1 ~]#docker -H 192.168.9.73:9205 ps   # 使用第一台查看

 

 

Docker 创建自定义桥

[root@c7-3 ~]#docker network create -d bridge --subnet "192.168.18.0/24" --gateway "192.168.18.1" mybr0   # 创建名字为mybr0

[root@c7-3 ~]#docker network ls   # 查看

NETWORK ID          NAME                DRIVER              SCOPE

cebd1dddba9d        mybr0               bridge              local

 

 

让两个网桥启动的容器可以通信

[root@c7-3 ~]#docker container run --name p1 --network bridge -it --rm dong9205/busybox:v0.1-1 

[root@c7-3 ~]#docker container run --name p2 --network mybr0 -it --rm dong9205/busybox:v0.1-1

[root@c7-3 ~]#iptables -R DOCKER-ISOLATION-STAGE-2 1 --out-interface br-3188dcaadacd -j ACCEP

[root@c7-3 ~]#iptables -R DOCKER-ISOLATION-STAGE-2 2 --out-interface docker0 -j ACCEPT

 

.           Dcoker存储卷(22)

写时复制COW

 

 

 

 

 

存在的的问题

  • 存储于联合文件系统中,不易于宿主机访问
  • 容器间数据共享不便
  • 删除容器其数据会丢失

结局方案:“卷(volume)”

       “卷”是容器上一个或多个“目录”,此类目录可绕过联合文件系统,于宿主机上的某目录“绑定(关联)”

 

两种存储卷

       Bind mount volume:两个已知路径进行绑定

              docker run -it -v HOSTDIR:VOLUMEDIR --name bbox2 busybox

              docker inspect -f {{.Mounts}} bbox2        # 查看bbox2容器的卷、卷标识

[root@C7-1 ~]#docker container run --name b1 -it --rm -v /data/volume/b1:/data busybox

[root@C7-1 ~]#docker inspect b1    # 查看b1的详细信息 source 代表宿主机的目录 Destination代表容器的目录

"Mounts": [

            {

                "Type": "bind",

                "Source": "/data/volume/b1",

                "Destination": "/data",

                "Mode": "",

                "RW": true,

                "Propagation": "rprivate"

            }

        ],

[root@C7-1 ~]#cd /data/volume/b1/   # 这个目录会自动创建

[root@C7-1 b1]#echo "<h1>busybox index httpd</h1>" > index.html 

[root@C7-1 b1]#docker container exec b1 /bin/cat /data/index.html

<h1>busybox index httpd</h1>

 

 

 

 

             

       Docker’-managed volume:docker daemon维护,自己在宿主机上找一个目录

              docker run –it -name bbox1 -v /data busybox

              docker inspect -f {{.Mounts}} bbox1

              例

[root@C7-1 ~]#docker container run --name b1 -it -v /data busybox

[root@C7-1 ~]#docker inspect b1    # 查看b1的详细信息 source 代表宿主机的目录 Destination代表容器的目录

"Mounts": [

            {

                "Type": "volume",

                "Name": "64c1fb31b983aabe442d0aec6c4a4a876c18604083474498b72b205fcb3554b4",

                "Source": "/var/lib/docker/volumes/64c1fb31b983aabe442d0aec6c4a4a876c18604083474498b72b205fcb3554b4/_data",

                "Destination": "/data",

                "Driver": "local",

                "Mode": "",

                "RW": true,

                "Propagation": ""

            }

        ],

[root@C7-1 ~]#cd /var/lib/docker/volumes/64c1fb31b983aabe442d0aec6c4a4a876c18604083474498b72b205fcb3554b4/_data  # 切换到宿主机的目录

[root@C7-1 _data]#echo "helow container" > test.html

[root@C7-1 _data]#docker container exec b1 /bin/cat /data/test.html    # 可以看到容器中也创建了对应的文件的内容

helow container

 

 

 

复制使用其他容器的卷,--volumes-from

[root@C7-1 ~]#docker run --name  infracon -it -v /data/infracon/volume:/data/web/html busybox   # 创建并启动第一个基础容器

[root@C7-1 ~]#docker run --name nginx --network container:infracon --volumes-from infracon -it busybox  # 创建并启动nginx容器

 

 

.           Docker File:惜字如金,一条指令,一层

FROM:FROM指令是最重要的一个且必须位于Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行与此基准镜像所提供的运行环境

 

       Syntax:

              FROM <repository>[:<tag>] 或

              FROM <repository>@[digest]

例子:FROM、COPY、ADD、WORKDIR、VOLUME、EXPOSE、ENV

[root@C7-1 image]#mkdir img1

[root@C7-1 image]#cd img1/

[root@C7-1 img1]#vim Dockerfile

# Description: test image   # 描述

FROM  busybox:latest    # 第一个非注释行一FROM开头

MAINTAINER "Xuan <www.p-pp.cn>"    # 作者的信息

# LABLE maintainer="Xuan <www.p-pp.cn>"    # 作者信息

COPY index.html /data/web/html/    # 复制文件

COPY yum.repos.d /etc/yum.repos.d/    # 复制文件夹

ADD http://nginx.org/download/nginx-1.15.12.tar.gz /usr/src/nginx.tar.gz   #添加一个tar文件,如果是网络文件不会展开

WORKDIR /usr/src/nginx    # 设置工作目录

ADD nginx-1.15.12.tar.gz ./     # 当前目录下的文件添加到./目录下,./目录为工作目录,tar文件会被自动展开

VOLUME /data/mysql         # 设置卷

EXPOSE 80/tcp 8080/tcp      # 设置映射的端口,虚拟机启动时,使用-P选项启动

[root@C7-1 img1]#cat index.html

<h1>Busybox httpd server. </h1>

<h2>Docker file.</h2>

[root@C7-1 img1]#docker build -t dockerfile:v0.1-1 ./     # 制作镜像并指定仓库和标签

[root@C7-1 img1]#docker run --name d1 --rm dockerfile:v0.1-1 /bin/cat /data/web/html/index.html   # 查看文件是否存在

<h1>Busybox httpd server. </h1>

<h2>Docker file.</h2>

[root@C7-1 img1]#docker run --name d1 --rm dockerfile:v0.1-1 /bin/ls /etc/yum.repos.d

CentOS-Media.repo

Centos-7.repo

docker-ce.repo

[root@C7-1 img1]#docker run --name d1 --rm dockerfile:v0.1-1 ls /usr/src

nginx.tar.gz

[root@C7-1 img1]#docker run --name d1 --rm dockerfile:v0.1-1 ls /usr/src/nginx/nginx-1.15.12

CHANGES

CHANGES.ru

LICENSE

README

auto

conf

configure

contrib

html

man

src

[root@C7-1 img1]#docker container run --name d1 -P --rm  dockerfile:v0.1-1 /bin/httpd -f -h  /data/web/htm

[root@C7-1 ~]#docker port d1

80/tcp -> 0.0.0.0:32769

8080/tcp -> 0.0.0.0:32768

 

 

ENV:ENV设置的环境变量在运行时也生效

[root@C7-1 img1]#cat Dockerfile

# Description: test image

FROM  busybox:latest

MAINTAINER "Xuan <www.p-pp.cn>"

ENV WEB_DIR="/data/web/html/" \ 

    WEB_PACKAGE="nginx-1.15.12"      # 定义变量

 

COPY index.html ${WEB_DIR:-/data/web/html/}    # 调用变量,如果变量存在,就用变量的值,如果不存在,就使用/data/web/html/

WORKDIR /usr/src/nginx

ADD ${WEB_PACKAGE}.tar.gz ./

 

[root@C7-1 img1]#docker build -t dockerfile:v0.1-7 ./

[root@C7-1 img1]#docker container run --name d1 --rm dockerfile:v0.1-7 cat /data/web/html/index.html                         

<h1>Busybox httpd server. </h1>

<h2>Docker file.</h2>

[root@C7-1 img1]#docker container run --name d1 --rm dockerfile:v0.1-7 printenv    # 启动容器后也生效

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

HOSTNAME=87fcd36f43b7

WEB_DIR=/data/web/html/

WEB_PACKAGE=nginx-1.15.12

HOME=/root

[root@C7-1 img1]#docker container run --name d1 -e WEB_PACKAGE=nginx-1.15 --rm dockerfile:v0.1-7 printenv   # -e设置环境变量

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

HOSTNAME=7d2ef53b2695

WEB_PACKAGE=nginx-1.15

WEB_DIR=/data/web/html/

HOME=/root

 

RUN、CMD:

[root@C7-1 image]#mkdir img2

[root@C7-1 image]#cd img2/

[root@C7-1 img2]#vim Dockerfile

FROM busybox

LABEL maintainer="www.p-pp.cn" app="httpd"

ENV WEB_DOC_ROOT="/data/web/html/"

RUN mkdir -p ${WEB_DOC_ROOT} && \

    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}index.html

 

#CMD /bin/httpd -f -h ${WEB_DOC_ROOT}   # 第一种直接写命令(dockerfile:v0.2-1 .)

#CMD ["/bin/sh","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]     # 第二种使用json数组的方式(dockerfile:v0.2-2 .)

#ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}    

CMD [ ] # 第三种ENTRYPOINT方法

# 第一种CMD方法

[root@C7-1 img2]#docker build -t dockerfile:v0.2-1 .

[root@C7-1 img2]#docker image inspect -f {{.Config.Cmd}} dockerfile:v0.2-1

[/bin/sh -c /bin/httpd -f -h ${WEB_DOC_ROOT}]

[root@C7-1 ~]#docker container run --name d1 -it --rm -P dockerfile:v0.2-1

[root@C7-1 img2]#curl 172.17.0.2

<h1>Busybox httpd server</h1>

 

# 第二种CMD方法

[root@C7-1 img2]#docker build -t dockerfile:v0.2-2 .

[root@C7-1 img2]#docker image inspect -f {{.Config.Cmd}} dockerfile:v0.2-2

[/bin/sh -c ["/bin/httpd","-f","-h",${WEB_DOC_ROOT}"]]

[root@C7-1 ~]#docker container run --name d1 --rm -P dockerfile:v0.2-2   # 直接启动会报错,因为${WEB_DOC_ROOT是一个变量

httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory

[root@C7-1 img2]#vim Dockerfile

CMD ["/bin/bash","-c","/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]    # 将这行做下修改

[root@C7-1 img2]#docker build -t dockerfile:v0.2-2 .   # 重新制作

[root@C7-1 ~]#docker container run --name d1 -it --rm -P dockerfile:v0.2-2   # 直接启动就会关闭

 

# 第三种CMD方法ENTRYPOINT

[root@C7-1 img2]#docker build -t dockerfile:v0.2-3 .

[root@C7-1 ~]#docker container run --name d1 -it --rm -P dockerfile:v0.2-3

[root@C7-1 ~]#docker container run --name d1 -it --rm -P dockerfile:v0.2-3 ls /  #这条命令会执行失败,因为ENTRYPOINT 认为后边的都是参数

[root@C7-1 ~]#docker container run --name d1 -it --entrypoint 'ls' --rm -P dockerfile:v0.2-3  # 使用--entrypoint将原有的entrypoint覆盖

bin   data  dev   etc   home  proc  root  sys   tmp   usr   var

 

#ENTRYPOINT会使用cmd后边的命令当自己的参数

[root@C7-1 img2]#vim Dockerfile

FROM busybox

LABEL maintainer="www.p-pp.cn" app="httpd"

ENV WEB_DOC_ROOT="/data/web/html/"

RUN mkdir -p ${WEB_DOC_ROOT} && \

    echo '<h1>Busybox httpd server</h1>' >${WEB_DOC_ROOT}index.html

CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]

ENTRYPOINT ["/bin/sh","-c"]

[root@C7-1 img2]#docker build -t dockerfile:v0.2-4 .

[root@C7-1 ~]#docker container run --name d1 -it  --rm -P dockerfile:v0.2-4   # 和第二种方法一样,运行后就会退出

 

Nginx可以通过环境变量接受参数来决定监听地址等(使用nginx:1.14-alpine)

[root@C7-1 image]#mkdir img3

[root@C7-1 image]#cd img3/

[root@C7-1 img3]#ls

Dockerfile  entrypoint.sh  index.html

[root@C7-1 img3]#cat entrypoint.sh

#!/bin/sh

#

cat > /etc/nginx/conf.d/www.conf << EOF

server {

        server_name ${HOSTNAME};

        listen ${IP:-0.0.0.0}:${PORT:-80};

        root ${NGX_DOC_ROOT:-/usr/share/nginx/html};

}

EOF

 

exec "$@"

[root@C7-1 img3]#cat Dockerfile

FROM nginx:1.14-alpine

LABEL maintainer="xuan <p-pp.cn>"

 

ENV NGX_DOC_ROOT="/data/web/html/"

 

ADD entrypoint.sh /bin/

ADD index.html ${NGX_DOC_ROOT}

 

CMD ["/usr/sbin/nginx","-g","daemon off;"]

 

ENTRYPOINT ["/bin/entrypoint.sh"]

[root@C7-1 img3]#cat index.html

<h1>busybox</h1>

 

验证一:

[root@C7-1 img3]#docker container run --name v1 -it --rm dockerfile:v0.3-2

[root@C7-1 img3]#docker container exec -it v1 /bin/sh

/ # wget -O - -q `echo $HOSTNAME`

验证二:

[root@C7-1 img3]#docker container run --name v1 -it -e "PORT=8080" --rm dockerfile:v0.3-2

[root@C7-1 img3]#curl 172.17.0.2:8080

<h1>busybox</h1>

 

 

HEALTHCHECK

       --interval=DURATION (default:30s)        # 每隔多长时间

       --timeout= DURATION (default:30s)      # 超时时长

       --start-period= DURATION(default:0s)  # 等待启动的时间

       --retries=N (default:3)           # 检测三次

      

[root@C7-1 img3]#cat Dockerfile

FROM nginx:1.14-alpine

LABEL maintainer="xuan <p-pp.cn>"

 

ENV NGX_DOC_ROOT="/data/web/html/"

 

ADD entrypoint.sh /bin/

ADD index.html ${NGX_DOC_ROOT}

 

EXPOSE 80/tcp

 

HEALTHCHECK --start-period=3s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/    # 健康监测,3秒后开始检测

CMD ["/usr/sbin/nginx","-g","daemon off;"]

 

ENTRYPOINT ["/bin/entrypoint.sh"]

 

 

SHELL:设置默认运行的shell,不设置为/bin/sh –c
STOPIGNAL:设置stop的信号,默认为15
ARG:用于Docker bulid向Dockerfile传值

[root@C7-1 img3]#cat Dockerfile

FROM nginx:1.14-alpine

 

ARG author="Xuan <p-pp>"

LABEL maintainer="${author}"

 

ENV NGX_DOC_ROOT="/data/web/html/"

 

ADD entrypoint.sh /bin/

ADD index.html ${NGX_DOC_ROOT}

 

EXPOSE 80/tcp

 

HEALTHCHECK  --interval=10s --retries=2 --start-period=3s CMD wget -O - -q http://${IP:-127.0.0.1}:9205/

CMD ["/usr/sbin/nginx","-g","daemon off;"]

 

ENTRYPOINT ["/bin/entrypoint.sh"]

[root@C7-1 img3]#docker build -t dockerfile:v0.3-4 ./    # 使用Dockerfile中定义了ARG变量

[root@C7-1 ~]#docker image inspect -f {{.Config.Labels}} dockerfile:v0.3-4

map[maintainer:Xuan <p-pp>]

[root@C7-1 img3]#docker build --build-arg author="XUAN董大轩Xuan" -t dockerfile:v0.3-5 .    # 使用—bulid-arg传值进行定义

[root@C7-1 ~]#docker image inspect -f {{.Config.Labels}} dockerfile:v0.3-5

map[maintainer:XUAN董大轩Xuan]

 

ONBUILD:相当于一个触发器,这个触发器在build为镜像的时候不会执行,但是当build后的镜像被用于Dockerfile FROM的基础镜像时,将会执行此触发器

[root@C7-1 img3]#cat Dockerfile    # 还是原来的文件,在最后加上ONBUILD

FROM nginx:1.14-alpine

……

ONBUILD  ADD http://172.17.0.1/centos/7/Packages/bpg-fonts-common-20120413-3.el7.noarch.rpm /usr/src

[root@C7-1 img3]#docker build -t dockerfile:v0.3-6 .    # 现将其做成镜像

[root@C7-1 img3]#cd ..

[root@C7-1 image]#mkdir img4

[root@C7-1 image]#cd img4/

[root@C7-1 img4]#vim Dockerfile

FROM dockerfile:v0.3-6

RUN mkdir /tmp/test

[root@C7-1 img4]#docker build -t dockerfile:v0.4-1 .    # 创建的时候会发现正在下载ONBUILD的包

[root@C7-1 img4]#docker run --rm --name d1 -it dockerfile:v0.4-1 /bin/sh

/ # ls usr/src/

bpg-fonts-common-20120413-3.el7.noarch.rpm

ONBUILD不能嵌套、不会触发FROM和MAINTAINER指令

 

 

 

.           私有仓库

Registry

安装:

yum -y install docker-registry.x86_64

配置文件

      

[root@C7-1 ~]#cd /etc/docker-distribution/registry/

[root@C7-1 registry]#vim config.yml

version: 0.1

log:

  fields:

    service: registry    # 启动服务

storage:

    cache:

        layerinfo: inmemory   # 缓存在内存中

    filesystem:

        rootdirectory: /var/lib/registry    # 数据放的位置

http:

addr: :5000    # 监听端口为5000

[root@C7-1 registry]#systemctl start docker-distribution.service  # 启动服务

[root@C7-1 registry]#lsof -i :5000

COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

registry 46152 root    3u  IPv6 491444      0t0  TCP *:commplex-main (LISTEN

 

# 将dockerfile:v0.3-6上传,首先需要打标

[root@C7-1 registry]#docker tag dockerfile:v0.3-6 C7-1.p-pp.cn:5000/dockerfile:v0.3-6   # 将其打标为 ip:端口/库名:标签

[root@C7-1 registry]#docker images | grep v0.3-6   # 查看打标后的镜像

C7-1.p-pp.cn:5000/dockerfile                         v0.3-6              9a6ab6a943b8        5 hours ago         16MB

dockerfile                                           v0.3-6              9a6ab6a943b8        5 hours ago         16MB

[root@C7-1 registry]#cat /etc/docker/daemon.json

{

  "registry-mirrors": ["https://registry.docker-cn.com"],    # 加速器

  "insecure-registries": ["C7-1.p-pp.cn:5000"]    # 允许使用5000端口,非SSL链接

}                     

[root@C7-1 registry]#docker push C7-1.p-pp.cn:5000/dockerfile:v0.3-6

 

# 使用另外一台进行下载镜像

[root@c7-3 ~]#vim /etc/docker/daemon.json

{

  "registry-mirrors": ["https://hks9tjx0.mirror.aliyuncs.com"],

  "bip": "192.168.17.1/24",

  "dns": ["192.168.9.7","1.1.1.1"],

  "hosts": ["tcp://0.0.0.0:9205","unix:///var/run/docker.sock"],

  "insecure-registries": ["C7-1.p-pp.cn:5000"]    # 添加非SLL可以上传下载

}

[root@c7-3 ~]#systemctl restart docker

[root@c7-3 ~]#docker pull C7-1.p-pp.cn:5000/dockerfile:v0.3-6  # 下载

[root@c7-3 ~]#docker images C7-1.p-pp.cn:5000/dockerfile   # 查看

REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE

C7-1.p-pp.cn:5000/dockerfile   v0.3-6              9a6ab6a943b8        5 hours ago         16MB

 

CNCF里边有一个HARBOR项目

Software

Software

Version

Description

Python

version 2.7 or higher

Note that you may have to install Python on Linux distributions (Gentoo, Arch) that do not come with a Python interpreter installed by default

Docker engine

version 17.03.0-ce+ or higher

For installation instructions, please refer to: https://docs.docker.com/engine/installation/

Docker Compose

version 1.18.0 or higher

For installation instructions, please refer to: https://docs.docker.com/compose/install/

Openssl

latest is preferred

Generate certificate and keys for Harbor

 

HARBOR的安装

下载地址:https://github.com/goharbor/harbor/releases
配置

[root@C7-1 src]#tar xf harbor-offline-installer-v1.8.0-rc1.tar

[root@C7-1 src]#cd harbor/

[root@C7-1 harbor]#yum install docker-compose

[root@C7-1 harbor]#vim harbor.yml

hostname: C7-1.p-pp.cn        # 监听的主机名

harbor_admin_password: dong9205    # 登录的密码,账号为admin

database:

  #The password for the root user of Harbor DB. Change this before any production use.

  password: pwd123     # 数据库的密码

[root@C7-1 harbor]#./install.sh

 

浏览器访问:

 

 

 

Docker Compose

       docker-compose pause     # 暂停

 

 

 

.           Docker资源限制

OOME:Out Of Memory Exception

       一旦发生oome,什么都与可能被杀死,包括docker daemon,因此,Docker调整了Docker daemon的OOM的优先级

Memory限制

-m,--memory=                     # 限制运行的内存,可接受k、b、m等单位

--memory-swap *                    # 限制交换分区

 

--memory-swappiness                          # 使用交换分区的倾向性0-100,0是能不用就不用

--memory-reservation                           # 预留

--kernel-memory

--oom-kill-disable                                 # 禁止oom倍kill掉

CPU限制:CFS(complete fairness scheduler完全公平调度器)

--cpus=<value>                       # Cpu可以使用几核

--cpu-period=<value>            # 时间

--cpu-quota=<value>

--cpuset-cpus                           # 设置只能用哪个CPU

--cpu-shares                             # CPU共享,按比例切分

 

测试

[root@C7-1 ~]#docker pull lorel/docker-stress-ng    # 拉去镜像

[root@C7-1 ~]#docker run --name stress -it --rm lorel/docker-stress-ng stress –help   # 获取帮助

Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10

                                           

# 内存测试

[root@C7-1 ~]#docker run --name stress -it -m 256m --rm lorel/docker-stress-ng stress -vm 2   # 分配256M,测试-vm为2个,一个默认占用256M

 

[root@C7-1 ~]#docker top stress    # 可以看到总共启动了4个进程

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD

root                12040               12022               1                   20:38               pts/0               00:00:00            /usr/bin/stress-ng stress -vm 2

root                12072               12040               0                   20:38               pts/0               00:00:00            /usr/bin/stress-ng stress -vm 2

root                12073               12040               0                   20:38               pts/0               00:00:00            /usr/bin/stress-ng stress -vm 2

root                12074               12072               91                  20:38               pts/0               00:00:02            /usr/bin/stress-ng stress -vm 2

root                12075               12073               92                  20:38               pts/0               00:00:02            /usr/bin/stress-ng stress -vm 2

[root@C7-1 ~]#docker stats stress    # 内存始终无法超过256M

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS

c6629ca1433f        stress              182.11%             255.8MiB / 256MiB   99.91%              0B / 0B             4.69GB / 86kB       5

 

 

# CPU测试

[root@C7-1 ~]#docker run --name stress -it --cpus 1 --rm lorel/docker-stress-ng stress --cpu 8   # 分配1个CPU,测试运行8个cpu

[root@C7-1 ~]#docker top stress   # 可以看到,启动了8个进程

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD

root                14391               14375               0                   20:45               pts/0               00:00:00            /usr/bin/stress-ng stress --cpu 8

root                14424               14391               12                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14425               14391               11                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14426               14391               11                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14427               14391               12                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14428               14391               12                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14429               14391               11                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14430               14391               11                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

root                14431               14391               11                  20:45               pts/0               00:00:02            /usr/bin/stress-ng stress --cpu 8

  

[root@C7-1 ~]#docker stats stress   # 因为分配了一个CPU,所以CPU 最大为100%

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS

707ee2258d18        stress              100.59%             24.91MiB / 1.922GiB   1.27%               0B / 0B             0B / 0B             9

 

 

Systemctl

 

# docker run -d -name centos7 --privileged=true centos:7 /usr/sbin/init

 

进入容器:

 

# docker exec -it centos7 /bin/bash

 

这样可以使用systemctl启动服务了。

 

 

/etc/docker/daemon.json 配置文件

[root@localhost ~]$ vim /etc/docker/daemon.json
{
    "authorization-plugins": [],
    "data-root": "",   # 设置docker运行时的根目录
    "dns": [],         # 设置容器的DNS地址
    "dns-opts": [],    # 设置容器的/etc/resolv.conf文件
    "dns-search": [],
    "exec-opts": [],
    "exec-root": "",
    "experimental": false,
    "features": {},
    "storage-driver": "",
    "storage-opts": [],
    "labels": [],
    "live-restore": true,
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "10m",
        "max-files":"5",
        "labels": "somelabel",
        "env": "os,customer"
    },
    "mtu": 0,
    "pidfile": "",    # 设置docker守护进程的PID文件
    "cluster-store": "", 
    "cluster-store-opts": {},
    "cluster-advertise": "",
    "max-concurrent-downloads": 3,
    "max-concurrent-uploads": 5,
    "default-shm-size": "64M",
    "shutdown-timeout": 15,
    "debug": true,    # 是否以debug模式启动docker
    "hosts": [],      # 设置容器的hosts
    "log-level": "",
    "tls": true,
    "tlsverify": true,
    "tlscacert": "",
    "tlscert": "",
    "tlskey": "",
    "swarm-default-advertise-addr": "",
    "api-cors-header": "",
    "selinux-enabled": false,    # 设置是否支持SELinux
    "userns-remap": "",
    "group": "",
    "cgroup-parent": "",
    "default-ulimits": {
        "nofile": {
            "Name": "nofile",
            "Hard": 64000,
            "Soft": 64000
        }
    },
    "init": false,
    "init-path": "/usr/libexec/docker-init",
    "ipv6": false,
    "iptables": false,
    "ip-forward": false,    
    "ip-masq": false,
    "userland-proxy": false,
    "userland-proxy-path": "/usr/libexec/docker-proxy",
    "ip": "0.0.0.0",
    "bridge": "",
    "bip": "",
    "fixed-cidr": "",
    "fixed-cidr-v6": "",
    "default-gateway": "",
    "default-gateway-v6": "",
    "icc": false,
    "raw-logs": false,
    "allow-nondistributable-artifacts": [],
    "registry-mirrors": [],       # 设置镜像加速地址
    "seccomp-profile": "",
    "insecure-registries": [],    # 设置docker的私有仓库地址
    "no-new-privileges": false,
    "default-runtime": "runc",
    "oom-score-adjust": -500,
    "node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"],
    "runtimes": {
        "cc-runtime": {
            "path": "/usr/bin/cc-runtime"
        },
        "custom": {
            "path": "/usr/local/bin/my-runc-replacement",
            "runtimeArgs": [
                "--debug"
            ]
        }
    },
    "default-address-pools":[{"base":"172.80.0.0/16","size":24},
    {"base":"172.90.0.0/16","size":24}]
}

 

 

 

 

 

 

 

 

 

          ip netns相关使用

随笔- 48  文章- 3  评论- 1 

ip netns 的相关使用

ip命令
       linux 的强大的网络配置命令‘ip’。

 

 

 

netns可以让一台机器上模拟多个网络设备,是网络虚拟化的重要组成,将不同类型的网络应用隔离。

一个net namespace有自己独立的路由表,iptables策略,设备管理。说来说去,它就是用来隔离的。比如将eth0加入了netns 1,那么netns 2中的应用程序就找不到eth0了。netns 1中的iptables策略,不会去影响netns 2中的iptables策略。

netns的用法

 

[root@monitor ~]# ip netns help list
Usage: ip netns list
ip netns add NAME
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd ...
ip netns monitor
ip netns list-id

 

 


先打开内核的网络转发功能。

[root@localhost ~]# vim /etc/sysctl.conf 
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1

 

添加两个namespace

[root@monitor ~]# ip netns add r1
[root@monitor ~]# ip netns add r2
[root@monitor ~]# ip netns list
r2
r1

 

查看r1的网络。

 

[root@monitor ~]# ip netns exec r1 ifconfig -a
lo: flags=8<LOOPBACK> mtu 65536
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

 

为r1的回环接口添加一个ip地址。

 

[root@monitor ~]# ip netns exec r1 ifconfig lo 127.0.0.1 up
[root@monitor ~]# ip netns exec r1 ifconfig -a
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

 

此时的r2并没有地址,因为他们是被隔离的


在网络名称空间上添加一对网卡,一个在r1,一个在r2.

 

[root@localhost ~]# ip link add veth1.1 type veth peer name veth1.2
[root@localhost ~]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT 
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br-ex state UP mode DEFAULT qlen 1000
link/ether 00:0c:29:4b:bb:d0 brd ff:ff:ff:ff:ff:ff
3: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT 
link/ether 00:0c:29:4b:bb:d0 brd ff:ff:ff:ff:ff:ff
4: br-in: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT 
link/ether 56:8d:9f:d2:96:21 brd ff:ff:ff:ff:ff:ff
5: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 7e:ea:fe:98:30:cd brd ff:ff:ff:ff:ff:ff
6: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether a2:48:54:92:c2:ed brd ff:ff:ff:ff:ff:ff

 

 


将一对网卡分别添加给2个名称空间。

[root@localhost ~]# ip link set veth1.1 netns r1
[root@localhost ~]# ip link set veth1.2 netns r2

 

查看r1的网络信息

 

[root@localhost ~]# ip netns exec r1 ifconfig -a
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
 
veth1.1: flags=4098<BROADCAST,MULTICAST> mtu 1500
ether a2:48:54:92:c2:ed txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

 


给r1的veth1.1改个名字,为eth0

[root@localhost ~]# ip netns exec r1 ip link set veth1.1 name eth0

 

为两个网卡添加ip地址。

[root@localhost ~]# ip netns exec r1 ifconfig eth0 10.0.1.1/24 up
[root@localhost ~]# ip netns exec r2 ifconfig eth0 10.0.1.2/24 up

 


ping功能

 

 

[root@localhost ~]# ip netns exec r1 ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.043 ms
^C
--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.036/0.040/0.043/0.006 ms

 

 


到目前为止,看吧,此时就好像创建了两个虚拟机一样。两个网络是互相独立的。但是在一个网段内的时候,又可以互相联通。

 

现在利用netns来创建1个虚拟网络空间。大致内容如下图。

 

 


创建桥接

 

[root@localhost ~]# brctl addbr br-ex
[root@localhost ~]# ip link set br-ex up
[root@localhost ~]# ifconfig 
br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 1e:d6:fd:9b:2a:fc txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

 


给桥设备添加IP地址。

# ip addr del 192.168.217.71/24 dev eno16777736 
# ip addr add 192.168.217.71/24 dev br-ex
# brctl addif br-ex eno16777736

 


再添加一个桥

[root@localhost ~]# brctl addbr br-in
[root@localhost ~]# ip link set br-in up

 

测试两个虚拟机之间的网络互通性。

首先先写一个脚本,自动桥接的。(/etc/qemu-ifup)

 

#!/bin/bash
 
bridge=br-in
 
if [ -n "$1" ];then
ip link set $1 up
brctl addif $bridge $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo 'Error: no interface specified'
exit 1
fi

 

 

启动一个虚拟机实例(cirros)

 

[root@localhost ~]# qemu-kvm -m 256 -smp 1 -name vm2 \
> -drive file=/images/cirros/test2.qcow2,if=virtio,media=disk \
> -net nic,macaddr=52:54:00:aa:bb:dd \
> -net tap,ifname=vif2.0,script=/etc/qemu-ifup \
> --nographic

 

再启动一个 vm1.
在真机上查看桥接状态。

[root@localhost ~]# brctl show
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
br-in    8000.0e1d0f339fc2    no    vif1.0
vif2.0

 


vif1.0 和vif2.0都是桥接在br-in上了。

好了,现在的情况相当于是vm1,vm2在一个交换机上。这个交换机就是br-in。为了这两个vm虚拟机可以和外界通信,必须要再创建一个虚拟的路由器。删去刚才的r1,r2。

添加路由器R1.

[root@localhost ~]# ip netns add r1

 

为路由器R1添加一对网卡并且启动。

[root@localhost ~]# ip link add rinr type veth peer name rins
[root@localhost ~]# ip link set rinr up
[root@localhost ~]# ip link set rins up

 

将网卡添加到桥上去。

 

[root@localhost ~]# brctl addif br-in rins
[root@localhost ~]# brctl show
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
br-in    8000.0e1d0f339fc2    no    rins
vif1.0
vif2.0

 

 

给rinr改个名字,并且启动

[root@localhost ~]# ip link set rinr netns r1 #将网卡rinr添加至r1
[root@localhost ~]# ip netns exec r1 ip link set rinr name eth0
[root@localhost ~]# ip netns exec r1 ip link set eth0 up

 

添加一个IP,作为网关。

 

[root@localhost ~]# ip netns exec r1 ifconfig eth0 10.0.1.254/24 up
[root@localhost ~]# ip netns exec r1 ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.1.254 netmask 255.255.255.0 broadcast 10.0.1.255
inet6 fe80::f8b4:bff:fee4:b12d prefixlen 64 scopeid 0x20<link>
ether fa:b4:0b:e4:b1:2d txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 16 bytes 1296 (1.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

 

 

两个虚拟机的网关都指向10.0.1.254

$ sudo su -
# ifconfig eth0 10.0.1.2/24 up
# route add default gw 10.0.1.254

 

目前来说整幅图的左半边完全好了。
开始右半边。

添加一对网卡,再把其中一个桥接

 

 

[root@localhost ~]# ip link add rexr type veth peer name rexs
[root@localhost ~]# brctl addif br-ex rexs
[root@localhost ~]# ip link set rexs up
[root@localhost ~]# brctl show 
bridge name    bridge id    STP enabled    interfaces
br-ex    8000.000c294bbbd0    no    eno16777736
rexs
br-in    8000.0e1d0f339fc2    no    rins
vif1.0
vif2.0

 

 


将另一个网卡添加到路由器的另一边,且给个另一个网络的地址

[root@localhost ~]# ip link set rexr netns r1
[root@localhost ~]# ip netns exec r1 ip link set rexr name eth1
[root@localhost ~]# ip netns exec r1 ifconfig eth1 192.168.217.77/24 up

 

利用防火墙的源地址转换,实现将内网中的地址转换。

 

[root@localhost ~]# ip netns exec r1 iptables -t nat -A POSTROUTING -s 10.0.1.0/24 ! -d 10.0.1.0/24 -j SNAT --to-source 192.168.217.77
[root@localhost ~]# ip netns exec r1 iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination 
 
Chain INPUT (policy ACCEPT)
target prot opt source destination 
 
Chain OUTPUT (policy ACCEPT)
target prot opt source destination 
 
Chain POSTROUTING (policy ACCEPT)

 

 


测试。vm1可以ping同vm2.vm1可以访问真机所在局域网的主机。

 

# hostname 
cirros
# ping 10.0.1.1
PING 10.0.1.1 (10.0.1.1): 56 data bytes
64 bytes from 10.0.1.1: seq=0 ttl=64 time=4.612 ms
# ping 192.168.217.2
PING 192.168.217.2 (192.168.217.2): 56 data bytes
64 bytes from 192.168.217.2: seq=0 ttl=127 time=4.742 ms
 
target prot opt source destination SNAT all -- 10.0.1.0/24 !10.0.1.0/24 to:192.168.217.77

 

 

当然。在左边那个网络中,还可以运行一个dhcp服务器,并且将网关自动指向10.0.1.254。 

[root@localhost ~]# yum -y install dnsmasq

 

执行命令

 

[root@localhost ~]# ip netns exec r1 dnsmasq -F 10.0.1.1,10.0.1.30 --dhcp-option=option:router,10.0.1.254

 

 

 

          Kubernetes(一)

.           DevOps

CI:持续集成

CD:持续交付,Delivery

CD:持续部署,Deployment

Borg是Google内部的工作了十几年的管理系统

 

master / node

       master:API Server,Schedule,Controller-Manager

       node:kubelet,容器引擎(docker)

Pod,Label,Label Selector

       Lable:key=value

       Label Selector:

 

Pod:

  • 自助式pod
  • 控制器管理的pod

u  ReplicationController(副本控制器)

u  ReplicaSet

u  Deployment

u  StatefulSet

u  DeamonSet

u  Job,Ctonjob

HPA控制器:

控制器,service,pod

控制器监控pod的数量,少了自动创建,多了删除

service用于转发数据,客户端请求到service后,service将流量使用莫种算法调度到pod资源

三个网络:节点网络,集群网络,Pod网络

同一Pod内的多个容器间:lo

各pod之间通信

CNI插件:

flannel:网络配置

       calico:网络配置,网络策略

       canel:前两种的集合

 

 

.           kubeadm部署Kubeernetes

 

 

部署的架构

 

 

 

 

kubeadm

       1、master,node:安装kubelet,kubeadm,docker

       2、master:kubeadm init

       3、nodes:kubadm join

       https://github.com/kubernetes/kubeadm/tree/master/docs/design             # 每个版本的安装文档

 

阿里云yum:https://mirrors.aliyun.com/kubernetes/yum/

              复制其repos路径即可,虽然里边为空

部署

[root@C7-1 docker]#yum install docker-ce kubelet kubeadm kubectl –y

[root@C7-1 harbor]#vim /usr/lib/systemd/system/docker.service

# for containers run by docker

Environment="HTTPS_PROXY=http://www.ik8s.io.10080"

Environment="NO_PROSY=127.0.0.0/8"

                                          

[root@C7-1 harbor]# vim /etc/sysctl.conf

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

[root@C7-1 harbor]#sysctl –p   # 如果提示文件不存在modprobe br_netfilter在重新执行sysctl –p

[root@C7-1 harbor]#systemctl daemon-reload

[root@C7-1 harbor]#systemctl restart docker

[root@C7-1 harbor]#systemctl enable kubelet.service

[root@C7-1 ~]#vim /etc/sysconfig/kubelet

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

[root@C7-1 ~]#kubeadm init --kubernetes-version=v1.14.1 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap        # 如果失败就手动下载,改标签

 

[root@C7-1 harbor]#docker pull mirrorgooglecontainers/kube-apiserver:v1.14.1

[root@C7-1 harbor]#docker pull mirrorgooglecontainers/kube-controller-manager:v1.14.1

[root@C7-1 harbor]#docker pull mirrorgooglecontainers/etcd:3.3.10

[root@C7-1 ~]#docker pull mirrorgooglecontainers/kube-scheduler:v1.14.1

[root@C7-1 ~]#docker pull mirrorgooglecontainers/kube-proxy:v1.14.1

[root@C7-1 ~]#docker pull mirrorgooglecontainers/pause:3.1

[root@C7-1 ~]#docker pull mirrorgooglecontainers/coredns:1.3.1

 

[root@C7-1 ~]#docker images  | grep mirrorgooglecontainers | awk '{print $1":" $2}' | while read A;do

> docker tag $A k8s.gcr.io/${A:23}

> done

[root@C7-1 harbor]#kubeadm init --kubernetes-version=1.14.1 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap   # 再次使用该命令

Your Kubernetes control-plane has initialized successfully!

 

To start using your cluster, you need to run the following as a regular user:

 

  mkdir -p $HOME/.kube

  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

  sudo chown $(id -u):$(id -g) $HOME/.kube/config

 

You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

  https://kubernetes.io/docs/concepts/cluster-administration/addons/

 

Then you can join any number of worker nodes by running the following on each as root:

 

kubeadm join 192.168.2.39:6443 --token jvpehf.6e1eiui4i2esin0g \

    --discovery-token-ca-cert-hash sha256:9c6aef93430a71da19727f4c0e8f146baeebb50dd5a81af6f907dd98c960346d

 

[root@C7-1 centos]#mkdir -p $HOME/.kube

[root@C7-1 centos]#cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

 

 

 

kubectl

 

[root@C7-1 centos]#kubectl get cs    # cs是componentstatus的缩写,也可以写成kubectl get componentstatus

NAME                 STATUS    MESSAGE             ERROR

scheduler            Healthy   ok                 

controller-manager   Healthy   ok                 

etcd-0               Healthy   {"health":"true"}

[root@C7-1 day22]#kubectl get nodes

NAME           STATUS     ROLES    AGE   VERSION

c7-1.p-pp.cn   NotReady   master   24m   v1.14.1             # NotReady  未就绪状态,部署Flannel

 

部署Flannel

https://github.com/coreos/flannel     # Github地址

 

[root@C7-1 day22]#kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

[root@C7-1 kubernetes]#kubectl get nodes        # 再次查看,已经是就绪状态

NAME           STATUS   ROLES    AGE   VERSION

c7-1.p-pp.cn   Ready    master   34m   v1.14.1    

[root@C7-1 kubernetes]#kubectl get pods -n kube-system    # 运行的pod

 [root@C7-1 ~]#kubectl get pods -n kube-system -o wide   # 查看的更加详细

[root@C7-1 kubernetes]#kubectl get ns   # 查看有多少名称空间

NAME              STATUS   AGE

default           Active   36m

kube-node-lease   Active   36m

kube-public       Active   36m

kube-system       Active   36m

 

节点加入

[root@C7-2 docker]#systemctl start docker

[root@C7-2 docker]#systemctl enable docker kubelet.service

[root@C7-2 docker]#kubeadm join 192.168.2.39:6443 --token jvpehf.6e1eiui4i2esin0g     --discovery-token-ca-cert-hash sha256:9c6aef93430a71da19727f4c0e8f146baeebb50dd5a81af6f907dd98c960346d --ignore-preflight-errors=Swap

[root@C7-1 ~]#kubectl get nodes    # 节点已经就绪了

NAME           STATUS   ROLES    AGE   VERSION

c7-1.p-pp.cn   Ready    master   61m   v1.14.1

c7-2.p-pp.cn   Ready    <none>   12m   v1.14.1

 

 

 

.           Kubernetes快速入门

kubectl

get

       get cs,get componentstatus             # 查看集群基本组件状态

   get nodes                         # 插卡节点状态

   get ns                                # 查看命名空间

get svc                              # 查看运行的容器相关信息

   get deployment               # 查看已经创建的容器

          get pods                    # 查看pod

          -l tag                          # 显示拥有tag标签pod

          -L tag                         # 显示tag标签的值

      -o wide                      # 查看的详细

      -n kube-system       # 查看kube系统相关

      -o wide                      # 查看的详细

      --show-labels          # 查看标签

 

label

   pods            # 指定为pod标签

pod-demo            # 指定pod

aaa=111         # aaa为标签的key,111为标签的值

--overwrite            # 将原有的覆盖

   node

          label node         # 指定为node添加标签

c7-2.p-pp.cn     # node的名字是c7-2.p-pp.cn

a1=1                   # 添加标签a1,值为1

delete

   delete pods nginx-deploy-55d8d67cf-vq4tv                # 删除pods

 

 

 

run

run nginx-deploy                                 # 启动后名字为nginx-deploy

--image=nginx:1.14-alpine             # 使用的镜像是nginx:1.14-alpine

--port=80                                          # 容器公开的端口为80

--replicas=1                                      #创建一个

--dry-run=true                                 #干跑一次

--restart=Neve                                     # 不重启

 

expose

   expose deployment nginx-deploy    # 指定deployment的名字是nginx-deploy

   --name=nginx                                     # 指定名字

--port=80                                            # 服务的端口

--target-port=80                                # 对应service的端口

--protocol=TCP                                   # 协议

describe

   describe svc nginx-deploy           # 查看nginx-deploy的详细信息

   delete svc nginx-deploy               # 删除暴露后的服务

explain

   explain rs

   explain pod

 

 

edit

edit svc nginx-deploy                   # 编辑nginx-deploy

 

scale

   scale                                               # 指定副本

--replicas=5                           # 指定副本为几个,可以扩展,可以缩减

deployment nginx-deploy    # 指定deploymen为nginx-deloy

set

       image                                             # 直接设置镜像

              deployment dong-httpd       # pod的名字

dong-httpd=dong9205/httpd:v2        # 容器名字=新的镜像名

exec

-it

pod-demo         # pod名字

-c dong-v1        # -c指定容器名

-- /bin/sh           # 执行的命令

rollout

          history deploy myapp-deploy    # 查看reploy的名字为myapp-deploy的信息

          undo deploy myapp-deploy        # 回滚

patch

deployment myapp-deploy -p '{"spec":{"replicas":5}}'    # 使用打补丁方法进行扩容

kubectl run:创建启动容器

 

[root@C7-1 ~]#kubectl cluster-info

[root@C7-1 ~]#kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 --dry-run=true  # 启动后名字为nginx-deploy,使用的镜像是nginx:1.14-alpine,容器公开的端口为80,--replicas=1是创建一个,--dry-run:干跑一次

[root@C7-1 ~]#kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1

[root@C7-1 ~]#kubectl get deployment   # 查看已经创建的deployment

NAME           READY   UP-TO-DATE   AVAILABLE   AGE

nginx-deploy   1/1     1            1           3m31s

[root@C7-1 ~]#kubectl get pods

NAME                           READY   STATUS    RESTARTS   AGE

nginx-deploy-55d8d67cf-vq4tv   1/1     Running   0          5m39s

[root@C7-1 ~]#kubectl get pods -o wide   # 查看更详细

[root@C7-1 ~]#kubectl delete pods nginx-deploy-55d8d67cf-vq4tv   # 删除,删除后控制器会自动重建一个

[root@C7-1 ~]#kubectl get pods   # 再次查看,可以看到新建的pod

NAME                           READY   STATUS    RESTARTS   AGE

nginx-deploy-55d8d67cf-p287q   1/1     Running   0          2m32s

[root@C7-1 ~]#kubectl describe svc nginx-deploy   # 查看详细信息

 

kubectl expose:暴露

 

[root@C7-1 ~]#kubectl expose deployment nginx-deploy  --port=80 --target-port=80 --protocol=TCP

[root@C7-1 ~]#kubectl get svc             

NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE

kubernetes     ClusterIP   10.96.0.1      <none>        443/TCP   19h

nginx-deploy   ClusterIP   10.96.33.100   <none>        80/TCP    4m45s

[root@C7-1 ~]#kubectl run client --image=busybox --replicas=1 -it --restart=Never  # 创建一个客户端名字是client,--it进入交互模式,--restart=Never不重启

/ # cat /etc/resolv.conf    # 查看搜索域

nameserver 10.96.0.10

search default.svc.cluster.local svc.cluster.local cluster.local p-pp.cn

options ndots:5            

[root@C7-1 ~]#kubectl get svc -n kube-system   # 获取dns的地址

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE

kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   22h

[root@C7-1 ~]#dig -t A nginx-deploy.default.svc.cluster.local @10.96.0.10   # 使用宿主机指定主机名和搜索域,然后@后边是DNS服务地址

[root@C7-1 ~]#kubectl get pods --show-labels   # 查看标签

NAME                           READY   STATUS    RESTARTS   AGE     LABELS

client                         1/1     Running   0          165m    run=client

nginx-deploy-55d8d67cf-8mztl   1/1     Running   0          3m10s   pod-template-hash=55d8d67cf,run=nginx-deploy

[root@C7-1 ~]#kubectl describe svc nginx-deploy   # 查看详细信息

Name:              nginx-deploy

Namespace:         default

Labels:            run=nginx-deploy

Annotations:       <none>

Selector:          run=nginx-deploy

Type:              ClusterIP

IP:                10.96.33.100

Port:              <unset>  80/TCP

TargetPort:        80/TCP

Endpoints:         10.244.1.4:80

Session Affinity:  None

Events:            <none>

[root@C7-1 ~]#kubectl edit svc nginx-deploy    编辑

……

  type: NodePort

……

[root@C7-1 ~]#kubectl get svc     # 再次查看会发现多了一个端口,这时候可以访问任意节点的改端口

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE

dong9205     NodePort    10.97.229.42    <none>        80:30302/TCP   20m

 

kubectl scale和set image实现升级

 

[root@C7-1 ~]#kubectl scale --replicas=5 deployment nginx-deploy

[root@C7-1 ~]#kubectl get pods      # 可以看到增加的deployment

[root@C7-1 ~]#kubectl set image deployment dong-httpd dong-httpd=dong9205/httpd:v2    # 升级

[root@C7-1 losthost]#kubectl rollout status deployment dong-httpd   # 查看状态

 

[root@C7-1 losthost]#kubectl rollout undo deployment dong-httpd    # 回滚

 

.           资源清单

资源:对象

  • workload:Pod、ReplicaSet,Deployment
  • 服务发现及均衡:Service,Ingress,...
  • 配置与存储:Volume,CSI

u  ConfigMap,Secret

u  DownwardAPi

  • 集群级资源

u  Namespace,Node,Role,ClusterRole,RoleBinding,ClusterRoleBinding

  • 元数据型资源

u  HPA,PodTemplate,LimitRange

 

 

大部分资源的配置清单

       apiserver:group/version

              # kubectl api-versions

       kind:资源类别

       metadata:元数据

              name

              namespace

              labels

              annotations

             

              每个资源的引用PATH

                     /api/GROUP/VERSION/namespace/NAMESPACE/type/NAME

       spec:期望的状态,disired state

      

       status:当前状态,current state,本字段由kubernetes集群维护

 

 

获取yaml格式

[root@C7-1 ~]#kubectl get pod client -o yaml     # 获取正在运行的pod的yaml

[root@C7-1 ~]# kubectl explain pods           # 获取pods的yaml怎么定义

[root@C7-1 ~]#kubectl explain pods.metadata    # 获取pod的metadata怎么定义

 

 

创建yaml

[root@C7-1 kubernetes]#mkdir manifests

[root@C7-1 manifests]#vim pod-demo.yaml

apiVersion: v1

kind: Pod

metadata:

  name: pod-demo

  namespace: default

  labels: {app:myapp, tier:frontend}    # 大括号和下边的缩进是两种方式,用一种即可

    app: myapp

    tier: frontend

spec:

  containers:

  - name: dong-v1

    image: dong9205/httpd:v1

  - name: dong-v1-command

    image: busybox:latest

    command: ["/bin/sh","-c","sleep 3600"]          # 中括号和和下边的-都是指定列表,使用一种即可

    - "/bin/sh"

    - "-c"

    - "echo $(date)>/data/index.html &&"

- "sleep 5"

[root@C7-1 manifests]#kubectl create -f pod-demo.yaml

[root@C7-1 manifests]#kubectl exec -it pod-demo -c dong-v1 -- /bin/sh

 

 

 

          kubernetes(二)

.           Kubernetes Pod控制其应用进阶

资源清单格式

一级字段:apiVersion(group/version),kind,metadata(name,namespace,lebels,annotations……)

Pod资源:

       spec.containers <[] object>

      

- name <string>

         image <string>

         imagePullPolicy <string>

                     Always, Never, IfNotPresent

         args <[ ]string>    # 相当于Dockerfile的CMD;https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

         command  <[ ]string>             # 相当于Dockerfile的entrypoint

 

 

打标签

       标签选择器:

              等值关系:=,==,!=

              集合关系:

                     KEY in (VALUE1,VALUE2)

                     KEY notin (VALUE1,VALUE2)

                     KEY

                     !KEY

为pod打标签

[root@C7-1 manifests]#kubectl label pods pod-demo aaa=111     # 打标签

[root@C7-1 manifests]#kubectl  label pods pod-demo --overwrite aaa=222    # 将原有值覆盖

[root@C7-1 manifests]#kubectl get pod -l aaa=222

[root@C7-1 manifests]#kubectl get pod -l aaa,"aaa!=222"

[root@C7-1 manifests]#kubectl get pod -l "aaa in (111,222,333)"

[root@C7-1 manifests]#kubectl get pod -l "aaa notin (111,333)"

 

为node打标签

[root@C7-1 ~]#kubectl label node c7-2.p-pp.cn a1=1

[root@C7-1 ~]#kubectl get nodes --show-labels

c7-2.p-pp.cn   Ready    <none>   2d8h   v1.14.1   a1=1

也可以使用-l和-L进行过滤和

 

 

 

pod和service与label关联

许多资源支持内嵌字段定义其使用标签选择器

       mathLabels:直接给定键值

       mathExpressions:基于给定的表达式定义使用的标签选择器,{“key”:”KEY”, operator:”OPERATOR”, values:[VAL1,VAL2]}

              操作符:

In,Notin:values字段的值必须为非空列表;

Exists,NotExists:values字段的值必须为空列表;

nodeName  <string>                # 直接指定node的名字,该yaml文件将会在改node运行

nodeSelector <map[string]string>        # 指定标签

       节点标签选择器,指定某个pod只运行在拥有某个标签的节点上

[root@C7-1 manifests]#vim pod-demo.yaml   再次编辑yaml文件

  nodeSelector:    # 添加nodeSelector标签选择器

aa: AA         # 每次创建该yaml的资源时,只在key为aa,value为AA的node上创建,如果value为数字

[root@C7-1 manifests]#kubectl get pods -owide

pod-demo                       2/2     Running   0          3m12s   10.244.1.22   c7-2.p-pp.cn   <none>           <none

 

annotations:

       与label不同的在于,他不能用于挑选资源对象,仅用于为对象提供“元数据”

[root@C7-1 manifests]vim pod-demo.yaml

  annotations:      # 在metadata里边添加

dongdaxuan: www.p-pp.cn 

[root@C7-1 manifests]#kubectl describe pods pod-demo

Annotations:        dongdaxuan: www.p-pp.cn

 

Pod的生命周期

       状态:Pending、Running、Failed、Succeeded、Unknow

      

       创建Pod:

 

       Pod生命周期的重要性为

              初始化容器

              容器探测:

                     liveness:kubectl explain pod.spec.containers.livenessProbe

                     readiness:kubectl explain pod.spec.containers.readinessProbe

restartPolicy  <string>       # 重启策略

       Always, OnFailure, Never. Default to Always

      

.           Pod控制器进阶

探针类型有三种:

       ExecAction、TCPSocketAction、HTTPGetAction

ExecAction

 [root@C7-1 manifests]#vim liveness-exec.yaml

apiVersion: v1

kind: Pod

metadata:

  name: liveness-exec-pod

  namespace: default

spec:

  containers:

  - name: liveness-exe-container

    image: busybox:latest

    command:

    - "/bin/sh"

    - "-c"

    - "touch /tmp/healthy; sleep 30;rm -f /tmp/healthy;sleep 3600"

    livenessProbe:      # 容器存货探测

      exec:

        command:

        - "test"

        - "-e"

        - "/tmp/healthy"

      initialDelaySeconds: 1     # 多久时间后开始勘测

      periodSeconds: 3         # 探测时间间隔,默认10s

[root@C7-1 manifests]#kubectl get pod –w    # 会发现重启次数过段时间会在呢个正

 

 

HTTPGetAction

[root@C7-1 manifests]#cat liveness-httpget.yaml

apiVersion: v1

kind: Pod

metadata:

  annotations:

    liveness: "HTTP-GET"

  labels:

    use: test-liveness

    liveness: http-get

  name: liveness-httpget

  namespace: default

spec:

  containers:

  - name: liveness-httpget-container

    image: dong9205/httpd:v1

    imagePullPolicy: IfNotPresent

    ports:

    - name: http

      containerPort: 80

    livenessProbe:

      httpGet:

        port: http

        path: /hostname.html

      initialDelaySeconds: 1

      periodSeconds: 3

[root@C7-1 manifests]#kubectl get pod     # 可以看懂已经启动,说明已经可以检测到http正在运行

[root@C7-1 manifests]#kubectl exec liveness-httpget -it -c liveness-httpget-container -- /bin/sh    # 进入容器

/ # ls /data

hostname.html

/ # rm -f /data/hostname.html

[root@C7-1 manifests]#kubectl get pod –w   # 发现容器重启次数哦在增加

NAME                           READY   STATUS    RESTARTS   AGE

liveness-httpget               1/1     Running   1          7m41s

[root@C7-1 manifests]#kubectl describe pod liveness-httpget

    Last State:     Terminated

 

 

lifecycle

       postStart:启动后立即执行的操作,如果操作失败,容器会被终止

[root@C7-1 manifests]#cat poststart-pod.yaml

apiVersion: v1

kind: Pod

metadata:

  name: poststart-pod

  namespace: default

spec:

  containers:

  - name: busybox-httpd

    image: busybox:latest

    imagePullPolicy: IfNotPresent

    lifecycle:

      postStart:

        exec:

          command: ["httpd","-h","/"]

    command: ["/bin/sh","-c","sleep 5"]

 

       preStop:终止前立即执行的事情

 

 

回顾Pod

       appVersoin,kind,metadata,spec,status(只读)

 

spec

containers

name

image

imagePullPolicy:Always, Never, IfNotPresent

ports

   name

   containerPort

livenessProbe:ExecAction(exec)、TcpSocketAction(tcpSocket)、HTTPGetAction(httpGet)

readinessProbe:ExecAction(exec)、TcpSocketAction(tcpSocket)、HTTPGetAction(httpGet)

lifecycle

postStart

postStop

nodeSelector:

nodenamePolicy:Always,Never,OnFailure

 

.           Pod控制器

ReplicationController

ReplicaSet:kubectl explain replicasets查看格式

Deployment

DaemonSet

Job

Cronjob

StatefulSet

创建ReplicaSet

[root@C7-1 replicasets]#cat rs-demo.yaml   # 编写yaml文件

apiVersion: apps/v1      # 版本

kind: Replicaset          #此处资源类型可以是Deployment、Job、Ingress、Service等

metadata:

  name: myapp

  namespace: default

  lables:                # 标签

    app: "app1"

  annotations:

    description: "这个是测试的realicaset"

spec:

  replicas: 2            # 创建两个副本

    mathLabels:        # 使用mathgLable匹配pod

      test: yes          # 匹配的标签,两个是and关系

      relese: test-one

  tmplate:

    metadata:

      name: myapp-pod

      labels:

        test: yes

        relese: test-one

      annotations:

        description: "这个是replcaset里边的pod"

    spec:

        containers:

        - name: myapp-container

          image: dong9205/httpd:v1

          ports:

          - name: http

            containerPort: 80

 

[root@C7-1 manifests]#kubectl create -f rs-demo.yaml

[root@C7-1 manifests]#kubectl get pod

[root@C7-1 manifests]#kubectl get rs      # rs代指replicaset

[root@C7-1 manifests]#kubectl edit replicaset myapp

spec:

  replicas: 1        # 在线修改replca实现在线扩容缩容

    spec:

      containers:

      - image: dong9205/httpd:v      # 修改containers里边的image可以实现灰度发布

 

 

 

创建reploy

[root@C7-1 deploy]#cat deploy-demo.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: myapp-deploy

  namespace: default

spec:

  replicas: 2

  selector:

    matchLabels:

      app: myapp-deploy

      release: test

  template:

    metadata:

      labels:

        app: myapp-deploy

        release: test

    spec:

      containers:

      - name: myapp

        image: dong9205/httpd:v1

        ports:

        - name: http

          containerPort: 80

[root@C7-1 deploy]#kubectl apply -f deploy-demo.yaml    # 根据文件生成reploy

[root@C7-1 deploy]#kubectl get deploy    # 查看deploy

[root@C7-1 deploy]#kubectl get rs        # 查看rs

[root@C7-1 deploy]#kubectl get po        # 查看pod

[root@C7-1 deploy]# vim deploy-demo.yaml   # 修改deploy文件

  replicas: 3

 

        image: dong9205/httpd:v2

[root@C7-1 replicasets]#kubectl get pod -l app=myapp-deploy –w   # 动态查看pod的信息

[root@C7-1 deploy]#kubectl apply -f deploy-demo.yaml     # 再次执行将会更新,动态查看的界面会看到自动更新后新生成的pod

[root@C7-1 deploy]#kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'   # 打补丁扩展

 

# 修改容器pod改变时,最多喝最少pod限制

[root@C7-1 replicasets]#kubectl explain deploy.spec.strategy.rollingUpdate   # 这里边的两个值记录了在扩容的时候最大和最小pod的限制

maxSurge:指定超出副本数有几个,两种方式:1、指定数量 2、百分比

maxUnavailable:最多有几个不可用

 

[root@C7-1 deploy]#kubectl patch deployment myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}

 

 

# 实现金丝雀发布

[root@C7-1 losthost]#kubectl get pod -l app=myapp-deploy –w    # 动态查看

[root@C7-1 deploy]#kubectl set image deployment myapp-deploy myapp=dong9205/httpd:v3 && kubectl rollout pause deploy myapp-deploy   # 设置镜像更新,但是后边直接执行暂停,所以只会更新一个

 

[root@C7-1 deploy]#kubectl rollout status deployment myapp-deploy   # 查看更新

Waiting for deployment "myapp-deploy" rollout to finish: 1 out of 5 new replicas have been updated...  5个副本中有一个被更新

 

[root@C7-1 losthost]#kubectl rollout resume deploy myapp-deploy    # 继续更新,更新完成后,上提条命令会退出

 

 

 

 

 

09-31.22

 

 

 

 

问题:

  1. pod一直处于Terminating状态,删除直接卡死

kubectl delete pod [pod name] --force --grace-period=0 -n [namespace]

 

 

 

 

 

 

 

 

          查看编译参数

1、nginx编译参数:

nginx -V(大写)
#注意:需保证nginx在环境变量中,或者使用这样的形式:/user/local/nginx/sbin/nginx -V

2、apache编译参数

cat your_apache_dir/build/config.nice

3、php编译参数:

php -i |grep configure
#或者 /user/local/php/bin/php -i |grep configure

4、mysql编译参数:

cat /user/local/mysql/bin/mysqlbug |grep configure

 

 

          Openstack(一)

.           基础

 

IaaS(Openstack、CloudStack)、Paas(Docker,Openshift)、SaaS

DBaaS

24

 

 

 

 

 

 

 

 

 

          Gatlab

.           Devops简介

Devops是Devleopment 和 Operations的组合,也就是开发和运维的简写

 

 

持续集成

       持续集成是指多名开发者再开发不同功能代码的过程中,可以频繁的将代码行合并到一起切不互相影响工作

持续部署

       是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付的高质量的产品,持续部署在某种程度代表了一个开发团队的更新迭代率

持续交付

       持续交付是在持续部署基础之上,将产品交付到线上环境,因此持续交付时产品价值的一种交付,是产品价值的一种盈利的实现

 

.           安装

rpm包下载地址:https://packages.gitlab.com/gitlab/gitlab-ce

然后直接yum安装即可

 

配置文件:/etc/gitlab/gitlab.rb

[root@c7-3 ~]#vim /etc/gitlab/gitlab.rb

(QQ邮箱)

external_url 'http://192.168.9.73'

gitlab_rails['smtp_enable'] = true

gitlab_rails['smtp_address'] = "smtp.qq.com"

gitlab_rails['smtp_port'] = 465

gitlab_rails['smtp_user_name'] = "914440859@qq.com"

gitlab_rails['smtp_password'] = "bljascenqxiobefh"

gitlab_rails['smtp_domain'] = "qq.com"

gitlab_rails['smtp_authentication'] = :login

gitlab_rails['smtp_enable_starttls_auto'] = true

gitlab_rails['smtp_tls'] = true

gitlab_rails['gitlab_email_from'] = "914440859@qq.com"

user["git_user_email"] = 914440859@qq.com

 

或(163邮箱)

 

external_url 'http://192.168.9.73'

gitlab_rails['smtp_enable'] = true

gitlab_rails['smtp_address'] = "smtp.163.com"

gitlab_rails['smtp_port'] = 25

gitlab_rails['smtp_user_name'] = "15137414715@163.com"

gitlab_rails['smtp_password'] = "Dd920506213"

gitlab_rails['smtp_domain'] = "163.com"

gitlab_rails['smtp_authentication'] = :login

gitlab_rails['smtp_enable_starttls_auto'] = true

gitlab_rails['smtp_tls'] = false

gitlab_rails['gitlab_email_from'] = "15137414715@163.com"

user["git_user_email"] = "15137414715@163.com"

[root@c7-3 ~]#gitlab-ctl reconfigure    # 等好久

 [root@c7-3 ~]#gitlab-rails console   # 进入终端

irb(main):003:0> Notify.test_email('收件人邮箱', '邮件标题', '邮件正文').deliver_now   # 发送测试邮件

然后就可以去访问浏览器了

 

 

 

 

 

 

关闭注册功能

 

 

 

 

创建用户

 

 

 

查看邮箱,有时候会在垃圾箱

 

 

 

给用户设置密码

一、管理员设置

 

 

 

 

 

 

二、用户找回密码

 

 

 

 

 

 

 

 

创建组

 

 

 

 

创建projects(项目)

 

 

 

将用户添加到组

https://docs.gitlab.com/ee/user/permissions.html (更多权限)

 

 

 

 

 

 

.           git客户端

安装:yum install git

[root@C7-1 ~]#git clone https://github.com/nginx/nginx.git   # 获取github上的nginx,不需要验证,因为是public的

克隆自己gitlab上的项目

 

 

 

 

 

然后选择项目

为项目添加内容

 

 

 

复制项目地址

 

 

[root@C7-1 ~]#git clone  http://192.168.9.73/test-group/test-project.git

Cloning into 'test-project'...

Username for 'http://192.168.9.73': xuan1_tom   # 因为是私有的,所以需要验证

Password for 'http://xuan1_tom@192.168.9.73':

remote: Enumerating objects: 3, done.

remote: Counting objects: 100% (3/3), done.

remote: Total 3 (delta 0), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.

[root@C7-1 ~]#cd test-project/    # 进入项目目录

[root@C7-1 test-project]#ls

index.html    # 默认可以看到刚才创建的文件

[root@C7-1 test-project]#vim index.html    # 对文件进行编辑

<h1>gitlab 111</h1>

<h1>gitlab 222</h1>   # 添加新的内容

[root@C7-1 test-project]#git add index.html   # 将文件添加到暂存区

 

[root@C7-1 test-project]#git commit -m "222"    # 提交文件到工作区,会提交到本地,打上标签222

[master ac78037] 222

 Committer: root <root@C7-1.p-pp.cn>

Your name and email address were configured automatically based

on your username and hostname. Please check that they are accurate.

You can suppress this message by setting them explicitly:

 

    git config --global user.name "Your Name"    # 没有配置用户名密码,会提示

    git config --global user.email you@example.com

 

After doing this, you may fix the identity used for this commit with:

 

    git commit --amend --reset-author

 

 1 file changed, 2 insertions(+), 1 deletion(-)

 

[root@C7-1 test-project]#git config --global user.name "test user"       # 可以随便配置一个名字和邮箱       

[root@C7-1 test-project]#git config --global user.email "123@qq.com"

 

[root@C7-1 test-project]#git push   # 向服务器上传

warning: push.default is unset; its implicit value is changing in

Git 2.0 from 'matching' to 'simple'. To squelch this message

and maintain the current behavior after the default changes, use:

 

  git config --global push.default matching

 

To squelch this message and adopt the new behavior now, use:

 

  git config --global push.default simple

 

See 'git help config' and search for 'push.default' for further information.

(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode

'current' instead of 'simple' if you sometimes use older versions of Git)

 

Username for 'http://192.168.9.73': xuan1_tom      # 会让输入用户名和密码

Password for 'http://xuan1_tom@192.168.9.73':

Counting objects: 5, done.

Writing objects: 100% (3/3), 256 bytes | 0 bytes/s, done.

Total 3 (delta 0), reused 0 (delta 0)

To http://192.168.9.73/test-group/test-project.git

   ad6b292..ac78037  master -> master

 

 

然后查看浏览器会发现先,新增加的内容已经上传成功

 

 

 

 

相关命令

#git config --global --list  # 列出用户全局设置

user.name=test user

user.email=123@qq.com

#git config -globalusername "name"设置全局用户名,可以非真实账户

#git config -global useremail xxx @xx.com#设置全局邮箱,可以非真实邮箱。

#git config -global Hist#例出用户全局设置git add index.html #添加文件到暂存区。

#git commit-m“11" #提交文件到工作区。gitstatus#查看工作区的状态。

#git push #提交代码到服务器。gitpull #获取代码到本地。

#git log查看操作日志

#vim .gitignore #定义忽略文件。

#git reset -ard HEADAA ^^  # 版本回滚,HEAD 为当前版本,加一个^为上一-个,为上上一个版本。

#git reflog    #获取每次提交的ID ,可以使用-hard根据提交的ID进行版本回退。

#git reset -hard 5ae4b06回退到指定id的版本。

#git branch #查看当前所处的分支。

#git checkout-- file #从服务器更新某个那文件覆盖本地的文件

 

 

.           gitlab同步github

一.GitLab上的代码库,自动同步到GitHub上

  大致需要三步

1》在GitHub上创建私有访问Token,token就是只有一部分权限的密码【和你的登录密码相比,你的登录密码拥有完全的权限】【所以本步骤可以不进行,直接使用github的登录密码也是可以的】【1-6步】

2》需要在github上创建一个空代码库,提供URL地址,供gitlab使用【7步】

3》在GitLab上配置镜像地址,完成同步【8-13步】

 

1.登录GitHub,在右上角头像处,选择setting进入

 

 

2.左侧选择Developer setting进入

 

 

3.左侧点击personal  access tokens,进入

 

 

4.右上角点击generate  new token ,进入

 

5.选择要给新token赋予的权限

想要本token拥有操作代码库的权限,应勾选“repo”

 

点击页面下方的generate token按钮

 

 

6.保存生成的新的token到其他地方,之后你就看不到它了

token记录在这里【https://www.cnblogs.com/sxdcgaq8080/p/10531172.html

 

 

7.最后需要在github上创建一个空仓库,用来接收gitlab同步过来的代码库

【注意:我这里建立的是私有的代码库,如果是公有代码库,可以自己尝试,看是否会出问题!】

【如果是共有代码库,那么可以不使用上面生成的token,而使用你GitHub的登录密码,尝试一下!】

 

 

 空的代码库生成,需要记录这个地址

https://github.com/AngelSXD/justjump.git

下面有用

 

 

 

 

8.进入gitlab,选择要同步的代码库,点击进去

 

9,光标移动到左侧设置,点击仓库

–––––––

 

10.选择镜像存储库 展开

 

 

 11.填写刚刚上面的那一串github的空代码库地址

但是注意地址需要加上username

原本的URL

https://github.com/AngelSXD/justjump.git

这里要填写的URL

https://AngelSXD@github.com/AngelSXD/justjump.git

 

username和后面的地址@隔开

 

密码处 填写的就是上面获取的token。

如果github中创建的是公有的仓库,可以尝试自己的github的登录密码填写此处,以或许更多更完整的权限!!!!

 

 

 

 

12.点击镜像存储库后,会在下侧生成

 需要点击多次,直到看到 更新按钮圈圈开始转动,并显示更新中 即开始更新【此时就可去github查看同步过去的代码了】

 

 【观察一下这里加密的URL格式:】

https://username:token或者password@github.com/AngelSXD/justjump.git

这也是之前版本的URL格式,只不过最新的gitlab版本,不需要密码写在URL中,而是填写在密码框!!!

 

 

好了 观察gitlab和github的同步情况!!!

 gitlab显示

 

 

github显示

 

 

 

13.最后,可以在IDEA修改代码并发布至gitlab,测试是否会同步到github

gitlab上看到 已经提交的更新

 

 github上面也自动同步到了【可能因为网路的问题,会慢一点,但是完全自动的,最终一定会同步的】【如果需要立即同步,一点延迟也受不了,则可以手动点击更新按钮,完成立即更新同步】

 

 

 

 

====================================================================================================================================

 二、GitHub上的代码,拉取到GitLab上

这个方向很简单,只需要上面第一模块在github上生成的token。留作备用

1.在gitlab上新建一个项目

 

 

 

2.选择Import project 导入项目,并选择从github导入

 

 

3.点击从github导入后,需要在框中填入第一模块中在github中创建的token

注意说明,gitlab要求  github提供的token所包含的权限,是需要选择【repo】权限的,而第一模块中,咱们获取的token是勾选了repo权限的!!!

 

 

 

 

4.填写以后,点击右侧List your GitHub repositories,展示你的GitHub资源库列表

那现在选择你想拉取到gitlab的项目,点击后面的导入即可

 

 

点击后,会显示进行的状态

 

 

 点击/root/swapping,可以跳转到当前拉取的项目的详情页【速度很慢,拉取很慢】

 

 

5.导入完成后,即可在gitlab上看到从github上拉取过来的项目

 

 

 6.现在,想要从gitlab拉取clone项目到本地

可以去这篇看看https://www.cnblogs.com/sxdcgaq8080/p/10509660.html

 

 

 

          jenkins

.           一、安装

1.1

官网rpm包:https://pkg.jenkins.io/redhat-stable/

       [root@C7-1 ~]#yum install jdk-8u191-linux-x64.rpm   #安装java

       [root@C7-1 ~]#yum install jenkins-2.138.3-1.1.noarch.rpm   # 安装jenkins

通用war包:http://mirrors.jenkins.io/war-stable/latest/jenkins.war

       java -jar jenkins-2.138.3.war

 

1.2:配置

主配置文件:/etc/sysconfig/jenkin

[root@C7-1 ~]#vim /etc/sysconfig/jenkins

JENKINS_HOME="/var/lib/jenkins"    # 存放代码的文件

JENKINS_USER="root"   # 启动jenkins的用户

JENKINS_PORT="8080"   # 监听端口

JENKINS_LISTEN_ADDRESS=""   # 监听地址,默认为0.0.0.0

JENKINS_DEBUG_LEVEL="5"    # 保存日志的级别,1-9

 

1.3:启动

[root@C7-1 ~]#systemctl start jenkins

[root@C7-1 ~]#systemctl enable jenkins

 

1.4:获取jenkins自动生成的key

[root@C7-1 ~]#grep -A 2 "installatio" /var/log/jenkins/jenkins.log  | tail -1   # 过滤,如果过滤不出来,可以自己查看

7000b4bc1fa74011a1d3186b1804f250   # 这个是自动生成的key

[root@C7-1 ~]#cat /var/lib/jenkins/secrets/initialAdminPassword   # 也可以查看这个文件

7000b4bc1fa74011a1d3186b1804f250

 

 

 

输入秘钥然后下一步即可,然后让装插件,选择推荐即可

 

然后一步一步的安装,设置密码,uri默认即可,我这没有截图

 

 

1.5:基本使用

 

 

 

 

 

1.6:做权限管理需要先装一个插件

 

安装完之后重启进行用户管理

 

 

 

 

 

 

 

 

 

 

1.7    角色管理

1.7.1:添加角色

 

 

 

 

 

 

 

 

 

 

 

然后保存即可

1.7.2:角色与role关联

 

 

然后验证user1和jenkinsadmin还可以进行登录,user1的权限很少

 

 

1.8:邮箱配置

 

 

 

我这里配置错了,系统管理员和下边配置的邮箱要一致

 

 

 

 

 

1.9:代码拉取

使用jenkins+gitlab免登录拉取

在gitlab上边添加jenkins的公钥内筒及可

1.9.1:查看jenkins的公钥

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCU7fx2aTz4DDjdSojeN5KIe4WnxI2Sh3bX59dgEahcPFbpNG9f+Lut6Yis46l7hoEO2jCVHpU7XysUC9PCPqUSzSex8QAAFjrJALfHF7g7tte0BiuV7dZBFLm011ML2tJtkCy3etnm7nVBUyTNLbeBysMvNULu0j+GvcnhwXqGn2BqHtDNlvcNAK/ja9nsrZdgpNBl/yKsvVGC4g0zIRNMkkBb7b4n3F7Dp+3t6r4DcuLUSopGPAbfdRHxYkyJ6hbVnjvunqBq4BzMbLVVtsGrIMYgwe69yodUnMkgA9qHo96/W6BgKlDj5SscAgQgHhHg39nQsit23EeYno5c7rUn root@C7_1.p-pp.cn

 

1.9.2:gitlab设置公钥

 

 

 

 

 

1.9.3:测试克隆不需要输入密码

[root@C7-1 gitlab]#git clone git@192.168.9.73:xuan/xuan.git   # 第一次ssh连接可能会让输入yes

Cloning into 'xuan'...

remote: Enumerating objects: 9, done.

remote: Counting objects: 100% (9/9), done.

remote: Compressing objects: 100% (3/3), done.

remote: Total 9 (delta 0), reused 0 (delta 0)

Receiving objects: 100% (9/9), done.

[root@C7-1 gitlab]#cat xuan/index.html

xuan1

xuan2

xuan3

1.9.4:开始创建任务

 

 

 

 

 

 

[root@C7-1 ~]#ll /var/lib/jenkins/workspace/xuan-demo1/   # 查看构建的目录

total 0

 

1.9.5:添加gitlab上边公钥对应的私钥,实现免密码拉取

 

查看私钥的key

[root@C7-1 ~]#cat .ssh/id_rsa

-----BEGIN RSA PRIVATE KEY-----

MIIEpAIBAAKCAQEAlO38dmk8+Aw43UqI3jeSiHuFp8SNkod21+fXYBGoXDxW6TRv

X/i7remIrOOpe4aBDtowlR6VO18rFAvTwj6lEs0nsfEAABY6yQC3xxe4O7bXtAYr

le3WQRS5tNdTC9rSbZAst3rZ5u51QVMkzS23gcrDLzVC7tI/hr3J4cF6hp9gah7Q

zZb3DQCv42vZ7K2XYKTQZf8irL1RguINMyETTJJAW+2+J9xew6ft7eq+A3Li1EqK

RjwG33UR8WJMieoW1Z477p6gauAczGy1VbbBqyDGIMHuvcqHVJzJIAPah6Pev1ug

YCpQ4+UrHAIEIB4R4N/Z0LIrdtxHmJ6OXO61JwIDAQABAoIBADfbWoj+x4Mw8lLt

FZBiv265BVP7AC4o6IXpynmZpc+SQfaNWAhiveFoaX6OlI5j0BvF8dq78bSm6P1H

wlBkNn1qvKyceyeNLtcckdD2MH8VAKngdpBw957JKy2MZPVZSPsWy+61AO0AGrI5

gOADeYQQjEw0abow2OqsW/90FYRPx927v6C02Kx2CsacQa4oIYJQR+KkAwSmCDcC

CkFlVIYNITZULo61qmoAbKr0BtCo6CZ8uepOBZKowgLja1pHLE7ZkVzgP5kYJAN3

havadmwClMQlIKD5VcZHpEDUg+kmGjTTtG+Ry5M8vPeFKHs1vEWkV/wU08tUOUit

UQt8ueECgYEAw1PzqlgvvyCHggvyc97QrYEhZjra4itloRxjqi5PmsjGwuto+0T9

+MKJWrqT89BRb5E5MS2VMI6mXLwO9V3OFwgA3UGT1B8VP0n+zAezYlMtMViHGiIC

e5CcIV9Rsh4BQLEesxTxLuBQ/b1Ek5ZYdcDFOSICCE86O4mWEQ0vcNMCgYEAwzCL

FCpJFX/BIjY4CACt92MZKLtpLor/Jx7GB1TPPifgPonqpvGn2p0l1nIyUaun1is6

q6J2mKbk59Qo6Ewz7T5Tq9ikr0lrqTBSkhNQIL6h9hznlgNz0py+g8DwGTB/oTug

mxs/2VkvxletZok1DjJYOccs856HtjA1gYLDFd0CgYAX674ZjHc8duVhfckRe6Ye

uYO3m1mW/S2TD4D9JHLHR/Nfh6jxrL9Vqa1cmSDpaQewHB7e8PAmZDHnhXhngDdv

BqHkdtV90titSYiUwBSt4/XS5z6UarnXHByi0aOVpqsMmyRhVh07WmlQyc8OLAll

UlhU6N9K2TkOdYkVSYIX1QKBgQCrP/zV3V+vsB2nwYAZbVc0dEqPlRXsUuEX1oUR

y5PkSaIR3Hj2rZCCWlvnMNv7Eaq4Wcco7Oo2dj7hMyAM50arwIIyhGnArJ77mrzn

EnC7ueVpg+SfljnZL9Jq0C0XPJjNwf3f9+Fl9TzYPPaSvpDA+uSzFI/Y0l7pNpTL

Iwm8NQKBgQCNZSX+XFt1yeI0RboY1UVJ8eX83YzSaHc4MaCkvtEOYdZOpIHtE6H1

C7GqkpZ6kU7esPrOkFh7QZJdy/kKwTjmbcTT3mxyGq9rJqcUukx2C1jWKXAnIziK

SQjglYIQh4dbut3nVyJ0fdx7FF39oquJdyNLRK7djULWyikDE4O8hw==

-----END RSA PRIVATE KEY-----

 

 

 

1.9.6:jenkins制定项目克隆地址

 

 

 

 

 

 

 

 

1.9.7:再次查看任务的文件

[root@C7-1 ~]#ll /var/lib/jenkins/workspace/xuan-demo1

total 4

-rw-r--r--. 1 root root 17 Jun 25 16:24 index.html

 [root@C7-1 ~]#cat /var/lib/jenkins/workspace/xuan-demo1/index.html

xuan1

xuan2

xuan3[root@C7-1 ~]#

 

 

1.10结合tomcat

1.10.1:首先搭建tomcat环境

软件位置:/apps/tomcat/

网页源代码位置:/data/tomcat/webapps

测试访问

[root@C7-1 xuan]#curl 192.168.9.75:8080/test/

test 192.168.9.75

[root@C7-1 xuan]#curl 192.168.9.76:8080/test/

test 192.168.9.76

 

1.10.2:实现jenkins拉取代码到tomcat

 

 

 

1.10.3:再次访问页面

[root@C7-1 xuan]#curl 192.168.9.75:8080/test/

xuan1

xuan2

xuan3

 

[root@C7-1 xuan]#curl 192.168.9.76:8080/test/

xuan1

xuan2

xuan3

 

[root@C7-1 xuan]#

 

 

.           二、phpline语法

2.1 分布式jenkins

2.1.1:jenkins-slave配置

[root@node5 ~]# yum install jdk-8u191-linux-x64.rpm -y

[root@node5 ~]# mkdir /data/jenkins/slave/jdk -p

[root@node5 ~]# ln -s /usr/bin/java /data/jenkins/slave/jdk/java

 

2.1.2 jenkins配置

 

 

 

 

 

 

 

 

 

2.1.3:丛节点查看进程

[root@node5 ~]# ps aux | grep java

root       6192  0.0  0.1 113172  1560 ?        Ss   00:41   0:00 bash -c cd "/data/jenkins/slave" && /usr/bin/java  -jar remoting.jar -workDir /data/jenkins/slave

root       6200 17.7  8.7 2331620 87748 ?       Sl   00:41   0:07 /usr/bin/java -jar remoting.jar -workDir /data/jenkins/slave

root       6382  0.0  0.0 112704   968 pts/0    R+   00:42   0:00 grep --color=auto java

 

2.2 新建phpline

 

 

 

 

 

 

 

.           三、代码质量检测

3.1:安装sonarqube

3.1.1:配置sonarqube

官网:https://www.sonarqube.org/

[root@C7-1 src]#cd /usr/src/

[root@C7-1 src]#unzip sonarqube-6.5.zip

[root@C7-1 src]#ln -s /usr/src/sonarqube-6.5 /usr/local/sonarqube

[root@C7-1 src]#cd /usr/local/sonarqube/conf/

[root@C7-1 conf]#vim sonar.properties

[root@C7-1 conf]#grep '^[a-zA-Z1-9]' sonar.properties

sonar.jdbc.username=sonar    # 数据库账号

sonar.jdbc.password=123456   # 数据库密码

sonar.jdbc.url=jdbc:mysql://192.168.9.77:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false   #  数据库地址

sonar.web.host=0.0.0.0   # 监听地址

sonar.web.port=9000     # 监听端口

 

3.1.2:安装数据库(数据库版本为5.6以上,所以不能使用yum安装)

一键安装下载地址:http://www.p-pp.cn/app/jenkins/

[root@node5 ~]# cd /usr/src/

[root@node5 src]# ls my*

my.cnf  mysql-5.6.42-linux-glibc2.12-x86_64.tar.gz  mysql-install.sh

[root@node5 src]# sh mysql-install.sh

[root@node5 src]# mysql

mysql> create database sonar character set utf8 collate utf8_general_ci;

mysql> grant all on sonar.* to 'sonar'@'192.168.%.%' identified by '123456'

;

 

3.1.3 连接测试

[root@node3 ~]# mysql -usonar -p123456 -h192.168.9.77

MySQL [(none)]> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| sonar              |

| test               |

+--------------------+

3 rows in set (0.00 sec)

3.1.4:启动sonar

[root@C7-1 conf]#/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start

然后就可以访问网页了

 

 

 

 

 

 

 

 

 

3.4.5:手动下载中文插件包并安装

[root@C7-1 ~]#cd /usr/local/sonarqube/extensions/plugins/   # 这个目录放着sonar的插件

[root@C7-1 plugins]#ll sonar-l10n-zh-plugin-1.11.jar

-rw-r--r--. 1 root root 36538 Apr 27 20:30 sonar-l10n-zh-plugin-1.11.jar    # 这时已经上传的中文包

[root@C7-1 conf]#/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart   # 重启sonar,然后登陆sonar已经是中文了

 

 

 

 

3.2:安装sonar-scanner(用于扫描)

下载地址:https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner

[root@C7-1 ~]#cd /usr/src/

[root@C7-1 src]#unzip sonar-scanner-2.6.1.zip

[root@C7-1 src]#ln -s /usr/src/sonar-scanner-2.6.1 /usr/local/sonar-scanner

[root@C7-1 src]#vim /usr/local/sonar-scanner/conf/sonar-scanner.properties

[root@C7-1 src]#grep '^[a-zA-Z1-9]' /usr/local/sonar-scanner/conf/sonar-scanner.properties

sonar.host.url=http://localhost:9000   # sonar地址

sonar.sourceEncoding=UTF-8   # 编码

sonar.jdbc.username=sonar   # 数据库用户

sonar.jdbc.password=123456   # 数据库密码

sonar.jdbc.url=jdbc:mysql://192.168.9.77:3306/sonar?useUnicode=true&amp;characterEncoding=utf8   # 数据库地址

 

3.3:扫描测试

3.3.1:官方包测试

[root@C7-1 src]#ls sonar-examples-master.zip

sonar-examples-master.zip   # 这是官方给的一个测试包

[root@C7-1 src]#unzip sonar-examples-master.zip

[root@C7-1 src]#cd sonar-examples-master/projects/languages/python/python-sonar-runner/

[root@C7-1 python-sonar-runner]#cat sonar-project.properties

# Required metadata

sonar.projectKey=org.sonarqube:python-simple-sonar-scanner    # key

sonar.projectName=Python :: Simple Project : SonarQube Scanner   # 名字

sonar.projectVersion=1.0   # 版本

 

# Comma-separated paths to directories with sources (required)

sonar.sources=src   # 扫描目录

 

# Language

sonar.language=py  # 语言

 

# Encoding of the source files

sonar.sourceEncoding=UTF-8

 

[root@C7-1 python-sonar-runner]#/usr/local/sonar-scanner/bin/sonar-scanner   # 开始扫描,扫描后可以查看sonar网页报告

 

 

3.1.2:手动创建文件测试

[root@C7-1 ~]#mkdir /data/sonar/test/python –p   # 创建测试目录

[root@C7-1 ~]#cd /data/sonar/test/python/

[root@C7-1 python]#cp /usr/src/sonar-examples-master/projects/languages/python/python-sonar-runner/sonar-project.properties /data/sonar/test/python/   # 复制名字、版本、测试目录文件

[root@C7-1 python]#mkdir src

[root@C7-1 python]#vim src/test.py

#!/usr/bin/env python                                                                                                                           

print "aaa"

[root@C7-1 python]#cat sonar-project.properties

# Required metadata

sonar.projectKey=xuan-key1   # 修改key

sonar.projectName=xuan-name1   # 修改名字

sonar.projectVersion=0.1   # 修改版本

 

# Comma-separated paths to directories with sources (required)

sonar.sources=src

 

# Language

sonar.language=py

 

# Encoding of the source files

sonar.sourceEncoding=UTF-8

[root@C7-1 python]#/usr/local/sonar-scanner/bin/sonar-scanner    # 执行后再次查看网页

 

 

 

 

 

3.4:jenkins关联sonarQube

3.4.1:安装sonarqube scannner插件

 

 

 

 

3.4.2:jenkins初始化sonarqube

 

 

 

 

 

3.4.3:构建sonarqube scanner

 

 

 

 

 

 

3.4.4:项目调用sonarqube scanner

 

 

 

 

 

sonar.projectKey=xuan-demo1

sonar.projectName=xuan-demo1

sonar.projectVersion=1.0

sonar.language=py

sonar.sources=./

sonar.sourceEncoding=UTF-8

 

 

 

 

 

 

 

.           四、实战

4.1:安装配置haproxy(两台都安装:我这里使用的jenkins的主备做haproxy+keepalived)

4.1.1:安装

[root@node5 src]# tar xf haproxy-1.8.20.tar.gz

[root@node5 haproxy-1.8.20]# yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl  openssl-devel systemd-devel net-tools vim iotop bc  zip unzip zlib-devel lrzsz tree screen lsof tcpdump wget ntpdate

[root@node5 haproxy-1.8.20]#  make  ARCH=x86_64 TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1  USE_CPU_AFFINITY=1  PREFIX=/usr/local/haproxy

[root@node5 haproxy-1.8.20]# make install PREFIX=/usr/local/haproxy

[root@node5 haproxy-1.8.20]# cp haproxy  /usr/sbin/

 

4.1.2:配置

[root@node5 haproxy-1.8.20]# mkdir -p /etc/haproxy/conf

[root@node5 haproxy-1.8.20]# vim /etc/haproxy/haproxy.cfg

global

maxconn 100000

chroot /usr/local/haproxy

stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin

uid 99

gid 99

daemon

nbproc 4

cpu-map 1 0

cpu-map 2 1

cpu-map 3 2

cpu-map 4 3

pidfile /usr/local/haproxy/run/haproxy.pid

log 127.0.0.1 local3 info

 

defaults

option http-keep-alive

option  forwardfor

maxconn 100000

mode http

timeout connect 300000ms

timeout client  300000ms

timeout server  300000ms

 

listen stats

 mode http

 bind 0.0.0.0:9999

 stats enable

 log global

 stats uri     /haproxy-status

 stats auth    admin:admin

[root@node5 haproxy-1.8.20]# vim /etc/haproxy/conf/server1.cfg

 

listen  web_port

 bind 192.168.9.110:80   # 192.168.9.110是配置keepalived的vip地址

 mode http

 log global

 server 192.168.9.75  192.168.9.75:8080  check inter 3000 fall 2 rise 5

 server 192.168.9.76  192.168.9.76:8080  check inter 3000 fall 2 rise 5

 

[root@node5 haproxy-1.8.20]# sysctl -w net.ipv4.ip_nonlocal_bind=1   # 因为飘逸ip只在一台机器上,如果不调整内核,backup无法监听自己没有的ip地址

[root@node5 haproxy-1.8.20]# sysctl -w  net.ipv4.ip_forward = 1

[root@node5 haproxy-1.8.20]# mkdir /var/lib/haproxy   # 创建存放sock文件的目录

 

 

4.1.3:配置service文件

[root@node5 haproxy-1.8.20]# vim /usr/lib//systemd/system/haproxy.service

[Unit]

Description=HAProxy Load Balancer

After=syslog.target network.target

 

[Service]

ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -c -q

ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf -p /run/haproxy.pid

ExecReload=/bin/kill -USR2 $MAINPID

 

[Install]

 

 

4.2:安装keepalived

4.2.1:主keepalived

[root@node5 ~]# cat /etc/keepalived/keepalived.conf

global_defs

{

       router_id node5.com

}

vrrp_instance VI-1 {

    state MASTER

    interface eth0

    virtual_router_id 55

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass xuan

    }

    unicast_src_ip  192.168.9.77

    unicast_peer {

         192.168.9.71

    }

    virtual_ipaddress {

        192.168.9.110

    }

}

 

 

4.2.2:备keepalived

[root@C7-1 ~]#yum install -y keepalived

global_defs

{

        router_id C7-1

}

vrrp_instance VI-1 {

    state BACKUP

    interface eth0

    virtual_router_id 55

    priority 99

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass xuan

    }

        unicast_src_ip  192.168.9.77

        unicast_peer {

            192.168.9.71

        }

                                                                                                                       

    virtual_ipaddress {

        192.168.9.110

    }

}

 

4.3:配置tomcat启动停止脚本(两台tomcat都配置)

#!/bin/bash

echo "$1 tomcat server"

command="/apps/tomcat/bin/catalina.sh $1"

function xuan_sleep() {

        for i in `echo $(seq 5)| rev`;do

                echo -e -n "\r$i"

                sleep 1

        done

}

function tomcat_check() {

        pid=$(ps -ef | grep -v "grep" | grep "tomcat" |grep "Djava" |awk '{print $2}')

        if [ ${1} "${pid}" ];then

                echo "${2}"

                exit 0

        fi

}

 

function tomcat_command() {

       xuan_sleep

       pid=$(ps -ef | grep -v "grep" | grep "tomcat" |grep "Djava" |awk '{print $2}')

       echo ${pid}

        if [ ${1} "${pid}" ];then

                echo "${2}${pid}"

        fi

 

}

case $1 in

start)

       tomcat_check "-n" "Tomcat已经启动"

       ${command}

       echo "-------------------正在启动-------------------------"

       tomcat_command "-n" 'tomcat进程id为:'

       ;;

stop)

       tomcat_check "-z" "Tomcat没有运行"

       ${command}

       echo "------------------正在停止-------------------------"

       tomcat_command "-z" "tomcat进程已停止"

        ;;

esac

 

4.4配置tomcat用户,用于管理tomcat服务

[root@node4 ~]# useradd tomcat -u 2000

[root@node4 ~]# chown tomcat. /apps/apache-tomcat-7.0.88

 

 

4.5:部署和回滚脚本

[root@C7-1 ~]#cat deploy.sh

#!/bin/bash

 

DATE=`date +%Y-%m-%d_%H-%M-%S`

GROUP_LIST=$2

 

function IP_list(){

  if [[ ${GROUP_LIST} == "online-group1" ]];then

     Server_IP="192.168.9.75"

     echo ${Server_IP}

  elif [[ ${GROUP_LIST} == "online-group2" ]];then

     Server_IP="192.168.9.76"

     ssh root@192.168.9.71 'echo "enable  server web_port/192.168.9.75" | socat stdio /var/lib/haproxy/haproxy.sock'

     ssh root@192.168.9.77 'echo "enable  server web_port/192.168.9.76" | socat stdio /var/lib/haproxy/haproxy.sock'

     echo ${Server_IP}

  elif [[ ${GROUP_LIST} == "online-all" ]];then

     Server_IP="192.168.9.75 192.168.9.76"

     echo ${Server_IP}

  fi

}

 

#function pull_code(){

#  rm -rf /home/tomcat/.jenkins/workspace/testweb

#  cd /home/tomcat/.jenkins/workspace

#  git clone git@192.168.7.202:testgroup/testweb.git

#}

 

function make_zip(){

  cd /var/lib/jenkins/workspace/xuan-demo1  && zip testweb.war.zip ./*

}

 

function down_node(){

  for node in ${Server_IP};do

    echo ${node}

    ssh root@192.168.9.71 "echo disable  server web_port/${node} | socat stdio /var/lib/haproxy/haproxy.sock"

    ssh root@192.168.9.77 "echo disable  server web_port/${node} | socat stdio /var/lib/haproxy/haproxy.sock"

    echo "${node} 关闭成功!"

  done 

}

 

function stop_tomcat(){

  for node in ${Server_IP};do

    ssh tomcat@${node} "/etc/init.d/tomcat stop"

    echo "${node} 关闭成功!"

  done

}

 

function start_tomcat(){

  for node in ${Server_IP};do

    ssh tomcat@${node} "/etc/init.d/tomcat start"

    echo "${node} 启动成功!"

  done 

}

 

function scp_codefile(){

  cd /var/lib/jenkins/workspace/xuan-demo1

  for node in ${Server_IP};do

    scp testweb.war.zip  tomcat@${node}:/data/tomcat/tomcat_appdir

    ssh tomcat@${node} "cd /data/tomcat/tomcat_appdir && unzip testweb.war.zip -d /data/tomcat/tomcat_appdir/testweb-${DATE} && rm -rf /data/tomcat/webapps/testweb && ln -sv /data/tomcat/tomcat_appdir/testweb-${DATE} /data/tomcat/webapps/testweb"

  done

}

 

function web_test(){

  #sleep 30

  for node in ${Server_IP};do

    NUM=`curl -s  -I -m 10 -o /dev/null  -w %{http_code}  http://${node}:8080/testweb/index.html`

    if [[ ${NUM} -eq 200 ]];then

       echo "${node} 测试通过,即将添加到负载"

       add_node ${node}

    else

       echo "${node} 测试失败,请检查该服务器是否成功启动tomcat"

    fi

  done

}

 

function add_node(){

   node=$1

    echo ${node},"----->"

    if [ ${node} == "192.168.8.100" ];then

       echo "192.168.8.100部署完毕,请进行代码测试!"

    else

      ssh root@192.168.9.71 ""echo enable  server web_port/${node}" | socat stdio /var/lib/haproxy/haproxy.sock"

      ssh root@192.168.9.77 ""echo enable  server web_port/${node}" | socat stdio /var/lib/haproxy/haproxy.sock"

    fi

}

 

function rollback_last_version(){

  for node in ${Server_IP};do

    NOW_VERSION=`ssh tomcat@${node} ""/bin/ls -l  -rt /data/tomcat/webapps | awk -F"->" '{print $2}'  | tail -n1 | awk -F"/data/tomcat/tomcat_appdir/" '{print $2}'""`

    NAME=`ssh tomcat@${node}  ""/bin/ls -l  -rt -d  /data/tomcat/tomcat_appdir/testweb* | grep -B 2 ${NOW_VERSION} | head -n1 | awk '{print $9}'""`

    ssh tomcat@${node} "rm -rf /data/tomcat/webapps/testweb && ln -sv ${NAME} /data/tomcat/webapps/testweb"

  done

}

 

 

main(){

   case $1  in

      deploy)

        IP_list;       

        #pull_code;

       make_zip;

       down_node;

      stop_tomcat;

      scp_codefile;

      start_tomcat;

      web_test;

         ;;

      rollback_last_version)

        IP_list;

        echo ${Server_IP}

        down_node;

        stop_tomcat;

        rollback_last_version;

        start_tomcat;

        web_test;

         ;;

    esac

}

 

main $1 $2

4.5.1:tomcat服务器需要创建的文件夹

[root@node3 ~]# mkdir /data/tomcat/{tomcat_appdir,webapps}    # 在部署和回滚脚本中指定的web目录

 

4.6、Jenkins配置

 

 

 

 

 

 

 

 

 

 

 

          命令

.           tcpdump

混杂模式(promisc):可以抓取其他人通信的包

 

-i:指定接口

-w:指定保存到那个文件,不指定则显示在屏幕

-nn:第一个n吧ip不进行反向解析,第二个n代表不把ip进行反向解析

-X:十六进制以及ASCII码显示

-XX:包括链路层

-A:ASCII

-v:详细信息

-vv:更加详细的信息

-r file:读取文件进行解码

expression:

       关键字

              type:主机(host)、网络(net)、端口(port)、端口范围(portrange)

              directioon:src, dst, src or dst, src and dst

              proto(限定协议):ether、wlan、ip、arp、tcp、udp.

       组合条件

              and

              or

              not

 

.           nc

另外一个实现:ncat,有nmap提供

 

-l:指定监听端口

-p PORT:指定连接服务端时候使用的端口

-v:显示详细信息

-w 1:指定超时时长为1秒

-z 1-1023:扫描端口1-1023

 

示例一:nc传输文件

[root@node5 ~]# yum install nc

[root@node5 ~]# nc -l 1234 > /tmp/passwd   # 监听1234端口,当有人发送连接,将连接传入的内容保存至/tmp/passwd,服务端为接收方

[root@node6 ~]#nc 1.1.1.5 1234 < /etc/passwd  # 使用另一台机器连接1234端口,并输入文件,所以客户端为传输方

 

[root@node5 ~]# cat /tmp/passwd  # 查看保存的文件

 

# 服务端也可以nc -l 1234 < /etc/passwd  这样服务端就是传输方了

# 传输目录需要先归档

 

 

 

示例二:nc作为web客户端

[root@node6 ~]#curl 1.1.1.1   # curl访问网站

 page index 1.1.1.1

[root@node6 ~]#nc 1.1.1.1 80   # nc连接1.1.1.1的80端口

GET /index.html HTTP/1.1  # GET请求index.html,使用的HTTP/1.1协议

Host: 1.1.1.1    # 主机为1.1.1.111

 

HTTP/1.1 200 OK

Server: nginx/1.12.2

Date: Fri, 21 Jun 2019 17:22:49 GMT

Content-Type: text/html

Content-Length: 22

Last-Modified: Fri, 21 Jun 2019 17:22:00 GMT

Connection: keep-alive

ETag: "5d0d1238-16"

Accept-Ranges: bytes

 

 page index 1.1.1.1

 

示例三:扫描器

 

posted @ 2019-06-29 00:17  董大轩  阅读(465)  评论(0)    收藏  举报