RHEL6 搭建LVS/NAT 负载均衡集群 案例

实验拓扑图:

未分类

操作流程:

Director Server : 192.168.4.50 pc50
安装并启用ipvsadm
创建虚拟服务器
向虚拟服务器上加入节点

Real Server : 192.168.4.51 pc51 192.168.4.52 pc52
配置WEB 服务器

Clinet : 192.168.2.253 pc253
连接虚拟服务器测试

具体步骤:

环境准备:

配置yum源

# service iptables stop            //关闭防火墙
# chkconfig iptables off            //关闭开机自启
# setenforce 0                            //设置SELinux 为宽松模式

网站服务器 pc51 / pc52 :

# yum -y install httpd
[root@pc51 ~]# echo '192.168.4.51' > /var/www/html/test.html
[root@pc52 ~]# echo "192.168.4.52" > /var/www/html/test.html
# service httpd start
# chkconfig httpd on
# yum -y install elinks
[root@pc51 ~]# elinks --dump http://localhost/test.html
  192.168.4.51
[root@pc52 ~]# elinks --dump http://localhost/test.html
  192.168.4.52

配置分发器 pc50:

# mount /dev/cdrom /mnt/
//安装 ipvsadm   rpm 包在光盘挂载文件下的LoadBalancer目录下
#cd /mnt/LoadBalancer/
#yum -y install ipvsadm-1.26-4.el6.x86_64.rpm 
//开启内核的路由转发功能
# sed -i '7s/0/1/' /etc/sysctl.conf
# sed -n '7p' /etc/sysctl.conf 
net.ipv4.ip_forward = 1

网站服务器 pc51 / pc52 :

指定网关地址 192.168.4.50

# route -n//查看路由
# route add default gw 192.168.4.50//临时配置网关 网卡重启后生效
//永久配置网关
# vim /etc/sysconfig/network-scripts/ifcfg-eth0
# sed -n '7p' /etc/sysconfig/network-scripts/ifcfg-eth0
GATEWAY=192.168.4.50
# ifdown eth0 ; ifup eth0      //重新加载网卡

客户端 192.168.2.253 配置

指定网关地址 192.168.2.50 :

# vim /etc/sysconfig/network-scripts/ifcfg-eth1
# sed -n '7p' /etc/sysconfig/network-scripts/ifcfg-eth1
GATEWAY=192.168.2.50
# ifdown eth1 ; ifup eth1
# ping -c 2 192.168.4.51
PING 192.168.4.51 (192.168.4.51) 56(84) bytes of data.
64 bytes from 192.168.4.51: icmp_seq=1 ttl=63 time=0.322 ms
64 bytes from 192.168.4.51: icmp_seq=2 ttl=63 time=0.503 ms

--- 192.168.4.51 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.322/0.412/0.503/0.092 ms
# yum -y install elinks

配置分发器 pc50 :

# yum -y install ipvsadm-1.26-4.el6.x86_64.rpm
# rpm -q ipvsadm
ipvsadm-1.26-4.el6.x86_64

添加虚拟服务

        # ipvsadm -L  //查看 IPVS
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port Scheduler Flags
          -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
        # ipvsadm -A -t 192.168.2.50:80 -s rr//添加虚拟服务 调度算法为Round Robin
        # ipvsadm -L
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port Scheduler Flags
          -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
        TCP  192.168.2.50:http rr
        # ipvsadm -Ln   //- n  数字显示
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port Scheduler Flags
          -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
        TCP  192.168.2.50:80 rr
                //向虚拟服务器中加入节点
        # ipvsadm -a -t 192.168.2.50:80 -r 192.168.4.51:80 -m
        # ipvsadm -a -t 192.168.2.50:80 -r 192.168.4.52:80 -m
        # ipvsadm -Ln
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port Scheduler Flags
          -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
        TCP  192.168.2.50:80 rr
          -> 192.168.4.51:80              Masq    1      0          0         
          -> 192.168.4.52:80              Masq    1      0          0   
        # /etc/init.d/ipvsadm save//使配置永久生效
        ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm:      [确定]
        # cat /etc/sysconfig/ipvsadm
        -A -t 192.168.2.50:80 -s rr
        -a -t 192.168.2.50:80 -r 192.168.4.51:80 -m -w 1
        -a -t 192.168.2.50:80 -r 192.168.4.52:80 -m -w 1

客户端测试

        # elinks --dump http://192.168.2.50/test.html
           192.168.4.51
        # elinks --dump http://192.168.2.50/test.html
           192.168.4.52
        //客户端 轮询到不同的后端真实服务器        

        [root@pc50 ~]# ipvsadm -Ln --stats
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
          -> RemoteAddress:Port
        TCP  192.168.2.50:80                 2       10       10      846     1098
          -> 192.168.4.51:80                     1        5        5        423      549
          -> 192.168.4.52:80                     1        5        5        423      549

        模拟pc51 web服务故障:
        [root@pc51 ~]# service httpd stop
        [root@pc50 ~]# ipvsadm -Z

         //客户端测试
        # elinks --dump http://192.168.2.50/test.html
           192.168.4.52
        # elinks --dump http://192.168.2.50/test.html
           192.168.4.52

        [root@pc50 ~]# ipvsadm -Ln --stats
        IP Virtual Server version 1.2.1 (size=4096)
        Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
          -> RemoteAddress:Port
        TCP  192.168.2.50:80                 3       11       11      906     1138
          -> 192.168.4.51:80                     1        1        1         60       40
          -> 192.168.4.52:80                     2       10       10      846     1098

会发现 LVS/NAT 单点故障时 并不能健康性检查

可以 编写一个脚本 监测两台Real Server 的服务 是否正常 如果监测到故障 将对应的服务在调度服务器 停掉

使用周期性计划任务 定时运行监测脚本 到达 健康检查的目的

RHEL6 搭建 keepalived + lvs/DR 集群

使用Keepalived为LVS调度器提供高可用功能,防止调度器单点故障,为用户提供Web服务:

  • LVS1调度器真实IP地址为192.168.4.50
  • LVS2调度器真实IP地址为192.168.4.55
  • 服务器VIP地址设置为192.168.4.252
  • 真实Web服务器地址分别为192.168.4.51、192.168.4.52

实验拓扑图:

未分类

实验步骤:

实验准备:

配置yum源

# service iptables stop            //关闭防火墙
# chkconfig iptables off            //关闭开机自启
# setenforce 0                            //设置SELinux 为宽松模式 

配置WEB服务器 pc51 / pc52

#yum -y install httpd  
#service httpd start 
#chkconfig httpd on
[root@pc51 ~] #echo " 192.168.4.51  " > /var/www/html/test.html
[root@pc52 ~] #echo " 192.168.4.52 " > /var/www/html/test.html

本次实验有些步骤就不详细介绍了,具体有关 keepalived 和 ipvsadm 的相关配置 可以参考

keepalived 配置高可用集群 : http://blog.51cto.com/13558754/2060950

ipvsadm 配置LVS/DR 负载均衡集群:http://blog.51cto.com/13558754/2060405

1、在web服务上 配置 VIP地址 pc51 / pc52

# ifconfig lo:1 192.168.4.252/32    //只拥有ip 就可以
# ifconfig lo:1
lo:1      Link encap:Local Loopback  
         inet addr:192.168.4.252  Mask:0.0.0.0
         UP LOOPBACK RUNNING  MTU:65536  Metric:1
# cd /proc/sys/net/ipv4/conf/
# echo 1 > lo/arp_ignore
# echo 2 > lo/arp_announce 
# echo 1 > all/arp_ignore 
# echo 2 > all/arp_announce 

2、配置分发器 50(主) 55(备) 分别安装keepalived软件 装包 ipvsadm

# rpm -q ipvsadm keepalived
ipvsadm-1.26-4.el6.x86_64
keepalived-1.2.13-5.el6_6.x86_64

3、修改配置文件

[root@pc50 ~]# vim /etc/keepalived/keepalived.conf 
 vrrp_instance VI_1 {
      state MASTER                 // 描述信息  MASTER为主服务器
      interface eth0                 // 定义网络接口
      virtual_router_id 51           //主 备VRID号必须一致 
      priority 150                   //服务器优先级
      advert_int 1
      authentication {
          auth_type PASS           //验证方式
          auth_pass 1111           //验证密码     主  备服务器密码必须一致 
      }
      virtual_ipaddress {
          192.168.4.252            //VIP地址
      }   
  }

  virtual_server 192.168.4.252 80 {        //配置 VIP为192.168.0.252  80 端口
      delay_loop 6
      lb_algo rr                            //设置LVS调度算法为RR
      lb_kind DR                            //设置LVS的模式为DR
      nat_mask 255.255.255.0
      persistence_timeout 50
      protocol TCP
      connect_timeout 3
      nb_get_retry 3
      delay_before_retry 3

     real_server 192.168.4.51 80 {
          weight 1                        //设置权重为1
     }   
     real_server 192.168.4.52 80 {
          weight 1                        //设置权重为1
      }   

  }

使用第一个虚拟服务的模版

其余的都删除

主机55

[root@pc55 ~]# vim /etc/keepalived/keepalived.conf 
  vrrp_instance VI_1 {
      state BACKUP                // 描述信息 BACKUP为备用服务器
      interface eth0
      virtual_router_id 51
      priority 100
      advert_int 1
      authentication {
          auth_type PASS
          auth_pass 1111
      }
      virtual_ipaddress {
          192.168.4.252
      }
  }

  virtual_server 192.168.4.252 80 {
      delay_loop 6
      lb_algo rr
      lb_kind DR
      nat_mask 255.255.255.0
      persistence_timeout 50
      protocol TCP
      connect_timeout 3
      nb_get_retry 3
      delay_before_retry 3

      real_server 192.168.4.51 80 {
          weight 1
      }
      real_server 192.168.4.52 80 {
          weight 1
      }
  }

4、启动服务

    # service keepalived start
    [root@pc50 ~]# ipvsadm -Ln
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    TCP  192.168.4.252:80 rr persistent 50
      -> 192.168.4.51:80              Route   1      0          0         
      -> 192.168.4.52:80              Route   1      0          0     
    [root@pc50 ~]# ip addr show | grep 192.168.4
        inet 192.168.4.50/24 brd 192.168.4.255 scope global eth0
        inet 192.168.4.252/32 scope global eth0

    [root@pc55 ~]# ipvsadm -Ln --stats
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
      -> RemoteAddress:Port
    TCP  192.168.4.252:80               0        0        0        0        0
      -> 192.168.4.51:80                     0        0        0        0        0
      -> 192.168.4.52:80                     0        0        0        0        0
    [root@pc55 ~]# ip addr show | grep 192.168.4
        inet 192.168.4.55/24 brd 192.168.4.255 scope global eth0

5、客户端访问

# elinks --dump 192.168.4.252
   192.168.4.52
[root@room1pc32 桌面]# elinks --dump 192.168.4.252
   192.168.4.51
[root@room1pc32 桌面]# elinks --dump 192.168.4.252
   192.168.4.52
[root@room1pc32 桌面]# elinks --dump 192.168.4.252
   192.168.4.51
[root@room1pc32 桌面]# elinks --dump 192.168.4.252
   192.168.4.52

# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  192.168.4.252:80               5       25        0     2075        0
  -> 192.168.4.51:80                     2       10        0      830        0
  -> 192.168.4.52:80                     3       15        0     1245        0

[root@pc55 ~]# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  192.168.4.252:80               0        0        0        0        0
  -> 192.168.4.51:80                     0        0        0        0        0
  -> 192.168.4.52:80                     0        0        0        0        0

模拟50 故障 验证Keepalived 高可用

[root@pc50 ~]#  service keepalived stop

[root@pc50 ~]# ip addr show | grep 192.168.4
    inet 192.168.4.50/24 brd 192.168.4.255 scope global eth0

[root@pc55 ~]# ip addr show | grep 192.168.4
    inet 192.168.4.55/24 brd 192.168.4.255 scope global eth0
    inet 192.168.4.252/32 scope global eth0

客户端访问

# elinks --dump 192.168.4.252
   192.168.4.52
# elinks --dump 192.168.4.252
   192.168.4.51
# elinks --dump 192.168.4.252
   192.168.4.52
# elinks --dump 192.168.4.252
   192.168.4.51
# elinks --dump 192.168.4.252
   192.168.4.52

# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  192.168.4.252:80               5       25        0     2075        0
  -> 192.168.4.51:80                     2       10        0      830        0
  -> 192.168.4.52:80                     3       15        0     1245        0

centos7 kvm和设置桥接br0

一、kvm

1、查cpu是否支持VT

egrep '(vmx|svm)' --color=always /proc/cpuinfo

2、检查内核模块是否加载

lsmod | grep kvm

3、查看Selinux状态

sestatus

如果是启用状态

# vi /etc/sysconfig/selinux

SELINUX=disabled 

reboot

4、安装 KVM(在centos7里面有些软件包已经没有了)

yum install kvm libvirt python-virtinst qemu-kvm virt-viewer tunctl bridge-utils avahi dmidecode qemu-kvm-tools virt-manager qemu-img virt-install net-tools libguestfs-tools -y

5、启动libvirt服务

systemctl start libvirtd

systemctl enable libvirtd

6、查看kvm服务是否正常,目前没任何虚拟机,所以没有内容显示

virsh -c qemu:///system list

二、桥接(eth0网卡是代称,我实际弄机器时是em1)

服务器上弄kvm,装虚拟机什么的,需要弄桥接,所以

需要用到brctl这个命令、centos7上默认已经有了,
前面他们让我弄的时候,只是给了我一个文本,ifcfg-br0里面的内容,没有说要用brctl这个命令,我搞了好久都没搞定

1、

brctl  addbr  br0    #创建网桥
brctl  addif  br0 eth0  #把br0和eth0网卡绑定
brctl  stp   br0 on    #有关stp协议的

2、在/etc/sysconfig/network-scripts/创建 ifcfg-br0

内容如下:

DEVICE=br0  
TYPE=Bridge
BOOTRPOTO=static
IPADDR=192.168.1.108
NETMASK=255.255.255.0
GATEWAY= 192.168.12.2
DNS1=192.168.211.103
ONBOOT=yes

修改ifcfg-eth0文件

BOOTRPOTO=none

追加 BRIDGE=br0

完整的如下所示:注释部分是没弄br0前弄得

未分类

都弄好后service network restart

正常情况下就好了

我在弄第二台机器是就不行了,一旦执行 service network restart 它会在/etc/sysconfig/network-scripts/ 下生成ifcfg-br0-1,或者ifcfg-eth0-1 不知道这是什么原因

我一直没搞定,不得不重启
在重启机器前我已经把br0删除了

删除如下:

brctl delif br0 eth0    #解除绑定
ifconfig br0 down     #关闭br0,不关闭删不掉
brctl delbr br0       #删除br0

重启后我按照上面的步骤重做了一遍,发现网络还是不通,但是ifconfig 可以看到br0的ip已经设置成功了,/etc/sysconfig/network-scripts/没有产生新文件

后面发现前面br0与eth0的绑定消失了,在过程中自动取消了绑定
重新绑定:

brctl addif br0 eth0
service network restart

网络就正常了

Kubernetes之利用prometheus监控K8S集群

prometheus它是一个主动拉取的数据库,在K8S中应该展示图形的grafana数据实例化要保存下来,使用分布式文件系统加动态PV,但是在本测试环境中使用本地磁盘,安装采集数据的agent使用DaemonSet来部署,DaemonSet的特性就是在每个node上部署一个服务进程,这一切都是自动的部署。

此处只讲如何用prometheus来监控K8S集群,关于prometheus的知识参考官方文档。

部署前提: 准备好所需要的文件

$ ls -l 
Prometheus/prometheus#:/data/Prometheus/prometheus# ls -l 
total 28
drwxr-xr-x 2 root root 4096 Jan 15 02:53 grafana
drwxr-xr-x 2 root root 4096 Jan 15 03:11 kube-state-metrics
-rw-r--r-- 1 root root   60 Jan 14 06:48 namespace.yaml
drwxr-xr-x 2 root root 4096 Jan 15 03:22 node-directory-size-metrics
drwxr-xr-x 2 root root 4096 Jan 15 03:02 node-exporter
drwxr-xr-x 2 root root 4096 Jan 15 02:55 prometheus
drwxr-xr-x 2 root root 4096 Jan 15 02:37 rbac

$ ls grafana/
grafana-configmap.yaml  grafana-core-deployment.yaml  grafana-import-dashboards-job.yaml  grafana-pvc-claim.yaml  grafana-pvc-volume.yaml  grafana-service.yaml

$ ls prometheus/
configmap.yaml  deployment.yaml  prometheus-rules.yaml  service.yaml

grafana和 prometheus 都是部署文件,node-exporter、kube-state-metrics、node-directory-size-metrics这三个是采集器,相当于prometheus的agent

文件准备好了,现在开始一步一步来部署:

1、创建所需Namespace

因为prometheus 部署的所有的deploy、pod、svc都是在monitoring完成的,所以需要事先创建之。

 $ cat namespace.yaml 
 apiVersion: v1
 kind: Namespace
 metadata:
  name: monitoring

 $ kubectl create -f namespace.yaml 
 namespace "monitoring" created

2、创建grafana的pv、 pvc

grafana# cat grafana-pvc-volume.yaml 
kind: PersistentVolume
apiVersion: v1
metadata:
  name: grafana-pv-volume
  labels:
    type: local
spec:
  storageClassName: grafana-pv-volume
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath:
    path: "/data/volume/grafana"

grafana# cat grafana-pvc-claim.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: grafana-pvc-volume
  namespace: "monitoring"
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: grafana-pv-volume

$ kubectl create -f grafana/grafana-pvc-volume.yaml -f grafana/grafana-pvc-claim.yaml 
persistentvolume "grafana-pv-volume" created
persistentvolumeclaim "grafana-pvc-volume" created

$ kubectl get pvc -n monitoring
NAME          STATUS           VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS     AGE
grafana-pvc-volume   Bound     grafana-pv-volume   10Gi       RWO     grafana-pv-volume   52s

状态bound已绑定到了 grafana-pv-volume

3、创建grafana应用,这些应用都是第三方的,都会有自已的配置,通过configmap来定义

grafana# ls
grafana-configmap.yaml  grafana-core-deployment.yaml  grafana-import-dashboards-job.yaml  grafana-pvc-claim.yaml  grafana-pvc-volume.yaml  grafana-service.yaml
grafana# kubectl create -f ./    #grafana目录下所有文件都创建
configmap "grafana-import-dashboards" created
deployment "grafana-core" created
job "grafana-import-dashboards" created
service "grafana" created 


grafana# kubectl get deployment,pod -n monitoring 
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/grafana-core   1         1         1            0           1m

NAME                              READY     STATUS              RESTARTS   AGE
po/grafana-core-9c7f66868-7q8lx   0/1       ContainerCreating   0          1m
运行po/grafana-core 容器时会下载镜像: grafana/grafana:4.2.0

grafana创建的应用 简单的自已描述了下:

      grafana-pv-volume=/data/volume/grafana =10G    
      grafana-pvc-volume=5G--->grafana-pv-volume
      ---configmap=grafana-import-dashboards     
      Job=grafana-import-dashboards

      Deployment=grafana-core     replicas: 1  containers=grafana-core   mount:  grafana-pvc-volume:/var
      service=grafana     port: 3000  = nodePort: 30161     (3000是grafana服务的默认端口)

4、现在grafana的核心应用已部署好了,现在来部署prometheus的RBAC

prometheus/rbac# ls
grant_serviceAccount.sh  prometheus_rbac.yaml
#先创建RBAC文件:
prometheus/rbac# kubectl create -f prometheus_rbac.yaml 
clusterrolebinding "prometheus-k8s" created
clusterrolebinding "kube-state-metrics" created
clusterrole "kube-state-metrics" created
serviceaccount "kube-state-metrics" created
clusterrolebinding "prometheus" created
clusterrole "prometheus" created
serviceaccount "prometheus-k8s" created
prometheus/rbac#

5、创建prometheus的deloyment,service

prometheus/prometheus# ls
configmap.yaml  deployment.yaml  prometheus-rules.yaml  service.yaml
prometheus/prometheus# 
在configmap.yaml中要注意的是在1.7以后,获取cadvsion监控pod等的信息时,用的是kubelet的4194端口,
注意以下这段:这是采集cadvision信息,必须是通过kubelet的4194端口,所以Kubelet必须监听着,4194部署了cadvsion来获取pod中容器信息
prometheus/prometheus#cat configmap.yaml
 # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L37
      - job_name: 'kubernetes-nodes'
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
          - role: node
        relabel_configs:
          - source_labels: [__address__]
            regex: '(.*):10250'
            replacement: '${1}:10255'
            target_label: __address__
      - job_name: 'kubernetes-cadvisor'
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
          - role: node
        relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
        - target_label: __address__
          replacement: kubernetes.default.svc.cluster.local:443
        - source_labels: [__meta_kubernetes_node_name]
          regex: (.+)
          target_label: __metrics_path__
          replacement: /api/v1/nodes/${1}:4194/proxy/metrics

      # https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml#L79

prometheus-rules.yaml 这是它的发现规则文件

deployment.yaml service.yaml 这两个是部署的文件, deployment部署中资源限制建议放大一点

现在部署prometheus目录下所有文件:

prometheus/prometheus# kubectl create -f ./
configmap "prometheus-core" created
deployment "prometheus-core" created
configmap "prometheus-rules" created
service "prometheus" created
prometheus/prometheus# 

prometheus/prometheus# kubectl get deployment,pod -n monitoring 
NAME                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/grafana-core      1         1         1            1           16m
deploy/prometheus-core   1         1         1            1           1m

NAME                                  READY     STATUS    RESTARTS   AGE
po/grafana-core-9c7f66868-wm68j       1/1       Running   0          16m
po/prometheus-core-6dc6777c5b-5nc7j   1/1       Running   0          1m
prometheus应用的部署,简单描述下创建的内容:
1
2
    Deployment= prometheus-core   replicas: 1    containers=prometheus   image: prom/prometheus:v1.7.0    containerPort: 9090(webui)
    Service    name: prometheus   NodePort-->port: 9090 -webui

6、prometheus部署完了现在来部署它的agent,也就是采集器:

Prometheus/prometheus# ls node-directory-size-metrics/
daemonset.yaml
Prometheus/prometheus# ls kube-state-metrics/
deployment.yaml  service.yaml
Prometheus/prometheus# ls node-exporter/
exporter-daemonset.yaml  exporter-service.yaml
Prometheus/prometheus# 
#其中两个用的是daemonset

Prometheus/prometheus# kubectl create -f node-exporter/ -f kube-state-metrics/ -f node-directory-size-metrics/
daemonset "prometheus-node-exporter" created
service "prometheus-node-exporter" created
deployment "kube-state-metrics" created
service "kube-state-metrics" created
daemonset "node-directory-size-metrics" created
Prometheus/prometheus# 

Prometheus/prometheus# kubectl get deploy,pod,svc -n monitoring 
NAME                        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/grafana-core         1         1         1            1           26m
deploy/kube-state-metrics   2         2         2            2           1m
deploy/prometheus-core      1         1         1            1           11m

NAME                                     READY     STATUS    RESTARTS   AGE
po/grafana-core-9c7f66868-wm68j          1/1       Running   0          26m
po/kube-state-metrics-694fdcf55f-bqcp8   1/1       Running   0          1m
po/kube-state-metrics-694fdcf55f-nnqqd   1/1       Running   0          1m
po/node-directory-size-metrics-n9wx7     2/2       Running   0          1m
po/node-directory-size-metrics-ppscw     2/2       Running   0          1m
po/prometheus-core-6dc6777c5b-5nc7j      1/1       Running   0          11m
po/prometheus-node-exporter-kchmb        1/1       Running   0          1m
po/prometheus-node-exporter-lks5m        1/1       Running   0          1m

NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
svc/grafana                    NodePort    10.254.231.25   <none>        3000:30161/TCP   26m
svc/kube-state-metrics         ClusterIP   10.254.156.51   <none>        8080/TCP         1m
svc/prometheus                 NodePort    10.254.239.90   <none>        9090:37318/TCP   10m
svc/prometheus-node-exporter   ClusterIP   None            <none>        9100/TCP         1m
Prometheus/prometheus#

--------
Prometheus/prometheus# kubectl get pod -o wide -n monitoring 
NAME                                  READY     STATUS    RESTARTS   AGE       IP             NODE
prometheus-node-exporter-kchmb        1/1       Running   0          4m        10.3.1.16      10.3.1.16
prometheus-node-exporter-lks5m        1/1       Running   0          4m        10.3.1.17      10.3.1.17

#这两个是exporter,用的是daemonset 分别在这两个node上运行了。这样就可以采集到所有数据了。

如上部署完成,以下是用自已的话简单描述下:

 node-exporter/exporter-daemonset.yaml 文件:
       DaemonSet=prometheus-node-exporter   
          containers: name: prometheus-node-exporter    image: prom/node-exporter:v0.14.0
          containerPort: 9100   hostPort: 9100  hostNetwork: true    #它用的是主机的9100端口

        Prometheus/prometheus/node-exporter# kubectl get  daemonset,pod -n monitoring 
        NAME                             DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
        ds/node-directory-size-metrics   2         2         2         2            2           <none>          16h
        ds/prometheus-node-exporter      2         2         2         2            2           <none>          16h
           因为它是daemonset,所以相应的也会运行着两个Pod: prometheus-node-exporter

      Service=prometheus-node-exporter   clusterIP: None   port: 9100  type: ClusterIP   #它没有clusterIP

    # kubectl get  service -n monitoring 
    NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    prometheus-node-exporter   ClusterIP   None            <none>        9100/TCP         16h
kube-state-metrics/deployment.yaml 文件:
      Deployment=kube-state-metrics replicas: 2   containers-->name: kube-state-metrics  image: gcr.io/google_containers/kube-state-metrics:v0.5.0 
                 containerPort: 8080

      Service     name: kube-state-metrics   port: 8080  #没有映射
                                 #kubectl get deployment,pod,svc -n monitoring                               
            NAME                        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
            deploy/kube-state-metrics   2         2         2            2           16h

            NAME                                     READY     STATUS    RESTARTS   AGE
            po/kube-state-metrics-694fdcf55f-2mmd5   1/1       Running   0          11h
            po/kube-state-metrics-694fdcf55f-bqcp8   1/1       Running   0          16h

            NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
            svc/kube-state-metrics         ClusterIP   10.254.156.51   <none>        8080/TCP         16h
node-directory-size-metrics/daemonset.yaml 文件:
        #因为是daemonset,所以未定义replicas数量,直接运行在每个node之上,但是它没有创建service
      DaemonSet : name: node-directory-size-metrics  
                  containers-->name: read-du  image: giantswarm/tiny-tools   mountPath: /mnt/var   mountPath: /tmp
                  containers--> name: caddy    image: dockermuenster/caddy:0.9.3 containerPort: 9102
                               mountPath: /var/www   hostPath /var

        kubectl get daemonset,pod,svc -n monitoring 
        NAME                             DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
        ds/node-directory-size-metrics   2         2         2         2            2           <none>          16h


        NAME                                     READY     STATUS    RESTARTS   AGE
        po/node-directory-size-metrics-n9wx7     2/2       Running   0          16h
        po/node-directory-size-metrics-ppscw     2/2       Running   0          16h

        NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
                     没有node-directory-size-metrics的service

到此 prometheus算是部署完成了,最后来看下它暴露的端口:

Prometheus/prometheus# kubectl get svc -o wide -n monitoring 
NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE       SELECTOR
grafana                    NodePort    10.254.231.25   <none>        3000:30161/TCP   31m       app=grafana,component=core
kube-state-metrics         ClusterIP   10.254.156.51   <none>        8080/TCP         6m        app=kube-state-metrics
prometheus                 NodePort    10.254.239.90   <none>        9090:37318/TCP   16m       app=prometheus,component=core
prometheus-node-exporter   ClusterIP   None            <none>        9100/TCP         6m        app=prometheus,component=node-exporter
Prometheus/prometheus#

7、访问、使用prometheus

如上可以看到grafana的端口号是30161,NodeIP:30161 就可以打开grafana,默认admin/admin

未分类

登录后,添加数据源:

未分类

添加Prometheus的数据源:

将Prometheus的作为数据源的相关参数如下图所示:

未分类

添加完后,导入模板文件:

未分类

未分类

未分类

部署完成。

iptables+Denyhost抵御暴力破解

1、使用iptables 现在每分钟连接ssh的次数

允许本地环回接口访问

iptables -A INPUT -i lo -j ACCEPT

对已经建立的所有链接都放行

iptables -A INPUT -m state –state ESTABLISHED -j ACCEPT

每分钟对ssh的新连接只允许两个,已建立的连接不限制

iptables -A INPUT -p tcp –dport 22 -m limit –limit 2/minute –limit-burst 2 -m state –state NEW -j ACCEPT

添加默认策略拒绝所有

iptables -P INPUT DROP

2、使用Denyhost 对错误的ssh密码的ip进行拒绝访问

下载denyhost http://sourceforge.net/projects/denyhosts/files/

安装denyhost

tar -zxvf DenyHosts-2.6.tar.gz
cd DenyHosts-2.6
python setup.py install #安装DenyHosts
cd /usr/share/denyhosts/ #默认安装路径
cp denyhosts.cfg-dist denyhosts.cfg #denyhosts.cfg为配置文件
cp daemon-control-dist daemon-control #daemon-control为启动程序
chown root daemon-control #添加root权限
chmod 700 daemon-control #修改为可执行文件
ln -s /usr/share/denyhosts/daemon-control /etc/init.d #对daemon-control进行软连接,方便管理
/etc/init.d/daemon-control start #启动denyhosts
chkconfig daemon-control on #将denghosts设成开机启动

配置denyhost

vim /usr/share/denyhosts/denyhosts.cfg
HOSTS_DENY = /etc/hosts.deny #控制用户登陆的文件
PURGE_DENY = 30m #过多久后清除已经禁止的,设置为30分钟;
BLOCK_SERVICE = sshd #禁止的服务名,当然DenyHost不仅仅用于SSH服务
DENY_THRESHOLD_INVALID = 1 #允许无效用户失败的次数
DENY_THRESHOLD_VALID = 5 #允许普通用户登陆失败的次数
DENY_THRESHOLD_ROOT = 5 #允许root登陆失败的次数
DAEMON_LOG = /var/log/denyhosts #DenyHosts日志文件存放的路径,默认

更改DenyHosts的默认配置之后,重启DenyHosts服务即可生效:

/etc/init.d/daemon-control restart #重启denyhosts

docker部署Elasticsearch集群

安装 docker

安装docker 查看官方文档:针对每个系统版本进行安装。

https://docs.docker.com/installation/#installation

启动 docker

$ sudo service docker start

编写Dockerfile

FROM     debian:jessie
MAINTAINER Sunny "[email protected]"
RUN apt-get update

RUN apt-get install -y vim wget curl
ENV Elasticsearch_version elasticsearch-1.7.0
RUN echo "root:root" |chpasswd

RUN 
  echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list && 
  echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list && 
  apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && 
  apt-get update

RUN 
  echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && 
  apt-get install -y oracle-java8-installer &&
  apt-get clean

RUN echo "JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> /etc/environment

RUN mkdir /usr/es
WORKDIR /usr/es
RUN wget https://download.elastic.co/elasticsearch/elasticsearch/$Elasticsearch_version.tar.gz
RUN tar -zxf $Elasticsearch_version.tar.gz
WORKDIR $Elasticsearch_version/config
RUN mv elasticsearch.yml elasticsearch.yml.bak
WORKDIR /usr/es
EXPOSE 9200 9300

根据Dockerfile制作 images

Dockerfile文件路径:docker/

sudo docker build -t debian/elasticsearch .
编译完成后查看镜像
$ sudo docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
debian/elasticsearch         latest              5f0668a6b9k0        About an hour ago   899.1 MB

安装weave

sudo wget -O /usr/local/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
sudo chmod a+x /usr/local/bin/weave
weave launch && weave launch-dns && weave launch-proxy
sudo weave launch
sudo weave ps 查看weave的路由状态
sudo weave status 查看weave状态
sudo weave expose <addr> 添加IP,能够使主机访问container

weave 启动container

在物理机A(192.168.1.135)上启动Container

sudo weave run 10.0.0.1/24 --name "dataNode1" -m 4g -v /opt/conf/data_node_1:/usr/tomcat/conf -v /opt/data/data_node_1:/usr/tomcat/data debian/tomcat

在物理机B(192.168.1.136)上启动Container

sudo weave run 10.0.0.2/24 --name "dataNode2" -m 4g -v /opt/conf/data_node_2:/usr/tomcat/conf -v /opt/data/data_node_2:/usr/tomcat/data debian/tomcat

在物理机A(192.168.1.135)上执行

sudo weave launch

在物理机B(192.168.1.136)上执行

sudo weave launch 192.168.1.136
sudo weave connect 192.168.1.135

weave实现container跨主机互联需要注意的地方

注意:

1、weave 的应用隔离功能

不同子网的container之间是默认隔离的,即使他们在同一台机器上面也不能ping通,不同物理机之间的容器也是默认隔离的。 所以在weave启动container的时候 集群应用的IP必须在同一个字网下面。10.0.0.1,10.0.0.2,而不能是10.0.0.1,10.0.1.1.

2、当container关闭需要重新启动的时候

建议用weave启动container。
这时候必须制定addr,否则ip会改变。

sudo weave start 10.0.0.1/24 node1
sudo weave start 10.0.0.2/24 node2
sudo weave start 10.0.0.3/24 node3
sudo weave start 10.0.0.4/24 node4

3、宿主机器与container通信的时候,需要执行下面的语句:

sudo weave expose <addr> 添加IP,能够使主机访问container
此处的addr必须是没有被使用的addr。
比如:
sudo weave expose 10.0.0.254/24
这个10.0.0.254/24地址必须是没有被使用的。

4、使用sudo weave expose 10.0.0.254/24 这种方式能够使宿主机和container通信,但是当宿主机重新启动的时候这个值就不存在了,建议开机启动的时候就设置这个值。

weave 数据传输图

(此图是转载的)

未分类

从图中可以看到容器之间是怎么跨主机通信的,性能问题可能就住要集中在weave Router上面了

配置Elasticsearch

elasticsearch.yml 内容如下

cluster.name: aaaaaaa-name
node.name: nade_01
index.number_of_shards: 8
index.number_of_replicas: 2
network.host: 10.0.0.1
transport.tcp.port: 9300
transport.tcp.compress: true
path.data: /usr/es/data
path.logs: /usr/es/logs
http.port: 9200
http.enabled: true
node.master: true
node.data: true
index.store.type: mmapfs
discovery.zen.minimum_master_nodes: 2
discovery.zen.ping.timeout: 90s
indices.fielddata.cache.size: 40%
bootstrap.mlockall: true
gateway.expected_nodes: 4
indices.recovery.max_size_per_sec: 100mb
index.cache.field.type: soft
node.rack_id: 101150
cluster.routing.allocation.awareness.attributes: rack_id

配置事项:

1、indices.fielddata.cache.size 这个值如果不用doc_values的话最好设置一下,默认是无上限的。 不过最好启用doc_values ,Elasticsearch官方也说明在以后的版本中doc_values会成为默认值。

2、因为只有两台物理机,并且配置也不一样所以设置了一下分片规则。

关闭swap

由于swap会影响Elasticsearch的性能,所以应该关闭swap

请看Es官方提供的方法: https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html

注意:官网上说的方法不能在容器里面执行,因为swap是系统功能,应该在宿主机上禁用swap。 docker 容器里面的root的用户如果不是特权容器是没有办法修改这些参数的。还有就是容器最好不要用特权启动,那样容器里面的root和外面的root权限就一样了,很危险。

修改fd 参数

和swap修改的方式一样,需要在宿主机上修改, sysctl -w vm.max_map_count=262144 这个事官网修改的值(没有测试),要想彻底修改这个值需要修改/etc/sysctl.conf这个文件,在里面加上vm.max_map_count=262144

启动容器

因为要用weave实现cluster,所以容器用weave启动

sudo weave run 10.0.0.1/24 --name "dataNode1" -m 9g -v /opt/conf/data_node_1:/usr/es/elasticsearch-1.7.0/config -v /opt/data/data_node_1:/usr/es/data -v /opt/logs/data_node_1:/usr/es/logs debian/elasticsearch /usr/es/elasticsearch-1.7.0/bin/elasticsearch -D

注意:要把es三个目录挂在外面,配置文件目录、数据目录、日志目录。

这样用docker结合weave 就能实现跨主机的cluster。

正则表达式之awk

  • awk兼具sed所有的功能,并且更加强大。它也是流式编辑器,针对文档中的行来操作。一行一行的执行。

(1)截取文档中的某个字段

head -n2   test.txt  |awk  -F  ': '   '{print  $1}'  //-F用来指定分隔符。不加-F选项,默认使用空格或者tab为分隔符,print为打印的意思。 $1表示打印第1字段   $0表示整行  

未分类

如果需要截取多个字段,可以在{ }中用“,”来分隔

(2)指定分隔符号

awk -F ':' '{print $1"#"$5"#"$6}' test.txt //将之前的:分隔符号替换为#,必须使用双引号引起来。

未分类

(3)匹配功能

awk '/oo/' test.txt //匹配出现oo的行

未分类

(4)匹配某段中出现的字符

awk -F ':' '$1 ~ /oo/' test.txt

未分类

awk命令可以直接使用特殊符号而不用使用转义字符

(5)支持多个条件匹配

awk -F ':' '/oo/ {print $1,$4} /user1/ {print $1,$6}' test.txt

未分类

(6)条件操作符

awk -F ':' '$3==0'  test.txt  //这里表示打印第3段等于0的行,要想等于必须使用2个=,不然就是赋值了。

未分类

也可以这样来打印

awk -F ':' '$3>=500 {print $0}' test.txt

未分类

这里写图片描述在和数字进行比较时,若把比较的数字用双引号括起来,那么awk不会认为是数字,而会认为是字符,那么就会按ASCII码表来排序,得不到想要的结果

(7)打印出某段不等于xx的行

awk -F ':' '$7!="/sbin/nologin"  {print $0} ' test.txt //字符作为判断条件则是要使用双引号括起来的   !=表示不等于

未分类

(8)2字段之间比较

awk -F ':'  '$3<$4' test.txt  //打印第3段小于第4段的行,比较的是数字

未分类

awk -F ':'  '$3==$4' test.txt //打印第3段与第4段相同的行。

未分类

(9)在2个字符之间查找

awk -F ':' '$3>"4" && $3<"8"' test.txt //第3段大于某个字符并且小于某个字符 。这里数字使用了双引号,所以表示字符 

未分类

2个条件满足一个的也打印出来

未分类

  • awk的内置变量

(1)OFS和-F选项有类似的功能,也是用来定义分隔符的,但是它是在输出的时候定义的

未分类

未分类

(2)变量NR的用法 表示行号

未分类

(3变量NF表示用分隔符分隔后一共有多少段

未分类

(4)使用NR打印前多少行

未分类

(5)打印2个条件同时满足的行

未分类

(6)2个变量的应用

未分类

(7)赋值

未分类

赋值后没有了分隔符号了,使用OFS重新定义

(8)求和

未分类

使用awk分析nginx访问日志access.log的ip

access.log为nginx的访问日志,默认路径在

/var/log/nginx/access.log

分析access.log的ip命令如下:

awk '{print $1}' access.log |sort|uniq -c|sort -n
  1. 命令里使用awk过滤出访问的ip

  2. 使用sort对ip排序

  3. 对排序后的ip进行统计,统计每一个ip访问数

  4. 最后使用sort 对访问数进行排序,排序为升序。

awk 赋值多个Shell变量

需求

将文件夹中的两个目录分别赋值给两个变量
文件夹名:test_dev、test_release

实现

#! /bin/bash
FOLDERS=$(ls | grep -v '.sh')

echo $FOLDERS

if [[ $FOLDERS =~ "dev" && $FOLDERS =~ "release" ]]; then
        eval $(echo $FOLDERS | awk -F' ' '{printf("DEV_PATH=%s;RELEASE_PATH=%s",$1,$2);}')
fi
echo "DEV_PATH: " $DEV_PATH
echo "RELEASE_PATH: " $RELEASE_PATH

结果

test_dev test_release
DEV_PATH:  test_dev
RELEASE_PATH:  test_release

NGINX 使用HTTP2

部署

使用HTTP2 首先必须部署SSL,走HTTPS协议 可参考NGINX服务器网站升级HTTPS

首先查看下nginx支持不支持http2,我是使用yum 安装的默认已经安装了模块,使用下面命令查看

nginx -V

查看下是否有下面的模块

--with-http_v2_module

修改虚拟主机配置

server {
    # listen 80;
    listen  443 ssl http2;
    #....
}

重启服务器,restart 而不是reload

service nginx restart

验证

第一种方法

在谷歌浏览器上打开你使用http2的站点,在浏览器地址栏输入chrome://net-internals/#http2,看下HTTP/2 sessions 里面有没有你的主机地址

第二种方法

在谷歌浏览器上打开你使用http2的站点,打开调试工具(F12),进入Network,刷新页面,然后在右键导航栏,勾选下’Protocol’,就可以看到在那一栏,显示h2