yarn使用cgroup隔离资源

yarn默认只管理内存资源,虽然也可以申请cpu资源,但是在没有cpu资源隔离的情况下效果并不是太好.在集群规模大,任务多时资源竞争的问题尤为严重.
还好yarn提供的LinuxContainerExecutor可以通过cgroup来隔离cpu资源

cgroup

cgroup是系统提供的资源隔离功能,可以隔离系统的多种类型的资源,yarn只用来隔离cpu资源

安装cgroup

默认系统已经安装了cgroup了,如果没有安装可以通过命令安装

CentOS 6

yum install -y libcgroup

CentOS 7

yum install -y libcgroup-tools

然后通过命令启动

CentOS 6

/etc/init.d/cgconfig start

CentOS 7

systemctl start cgconfig.service

查看/cgroup目录,可以看到里面已经创建了一些目录,这些目录就是可以隔离的资源

drwxr-xr-x 2 root root 0 3月  19 20:56 blkio
drwxr-xr-x 3 root root 0 3月  19 20:56 cpu
drwxr-xr-x 2 root root 0 3月  19 20:56 cpuacct
drwxr-xr-x 2 root root 0 3月  19 20:56 cpuset
drwxr-xr-x 2 root root 0 3月  19 20:56 devices
drwxr-xr-x 2 root root 0 3月  19 20:56 freezer
drwxr-xr-x 2 root root 0 3月  19 20:56 memory
drwxr-xr-x 2 root root 0 3月  19 20:56 net_cls

如果目录没有创建可以执行

cd /
mkdir cgroup
mount -t tmpfs cgroup_root ./cgroup
mkdir cgroup/cpuset
mount -t cgroup -ocpuset cpuset ./cgroup/cpuset/
mkdir cgroup/cpu
mount -t cgroup -ocpu cpu ./cgroup/cpu/
mkdir cgroup/memory
mount -t cgroup -omemory memory ./cgroup/memory/

通过cgroup隔离cpu资源的步骤为

1、在cpu目录创建分组

cgroup以组为单位隔离资源,同一个组可以使用的资源相同
一个组在cgroup里面体现为一个文件夹,创建分组直接使用mkdir命令即可.
组下面还可以创建下级组.最终可以形成一个树形结构来完成复杂的资源隔离方案.
每当创建了一个组,系统会自动在目录立即创建一些文件,资源控制主要就是通过配置这些文件来完成

--w--w--w- 1 root root 0 3月  19 21:09 cgroup.event_control
-rw-r--r-- 1 root root 0 3月  19 21:09 cgroup.procs
-rw-r--r-- 1 root root 0 3月  19 21:09 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 3月  19 21:09 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 3月  19 21:09 cpu.rt_period_us
-rw-r--r-- 1 root root 0 3月  19 21:09 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 3月  19 21:09 cpu.shares
-r--r--r-- 1 root root 0 3月  19 21:09 cpu.stat
-rw-r--r-- 1 root root 0 3月  19 21:09 notify_on_release
-rw-r--r-- 1 root root 0 3月  19 21:09 tasks

yarn默认使用hadoop-yarn组作为最上层,任务运行时yarn会为每个container在hadoop-yarn里面创建一个组
yarn主要使用cpu.cfs_quota_us cpu.cfs_period_us cpu.shares3个文件
yarn使用cgroup的两种方式来控制cpu资源分配

  • 严格按核数隔离资源
    可使用核数 = cpu.cfs_quota_us/cpu.cfs_period_us
    在yarn中cpu.cfs_quota_us被直接设置为1000000(这个参数可以设置的最大值)
    然后根据任务申请的core来计算出cpu.cfs_period_us

  • 按比例隔离资源
    按每个分组里面cpu.shares的比率来分配cpu
    比如A B C三个分组,cpu.shares分别设置为1024 1024 2048,那么他们可以使用的cpu比率为1:1:2

2、将进程id添加到指定组的tasks文件
创建完分组后只需要将要限制的进程的id写入tasks文件即可,如果需要解除限制,在tasks文件删除即可

yarn配置

启动cgroup需要配置几个配置文件

etc/hadoop/yarn-site.xml配置

可以参考http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/NodeManagerCgroups.html 配置
这些配置大部分都是固定配置

<property>
    <name>yarn.nodemanager.container-executor.class</name>
  <value>org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor</value>
</property>
<property>
    <name>yarn.nodemanager.linux-container-executor.resources-handler.class</name>
    <value>org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler</value>
</property>
<property>
    <description>yarn使用的cgroup组,默认为/hadoop-yarn</description>
    <name>yarn.nodemanager.linux-container-executor.cgroups.hierarchy</name>
    <value>/hadoop-yarn</value>
</property>
<property>
    <description>是否自动挂载cgroup</description>
    <name>yarn.nodemanager.linux-container-executor.cgroups.mount</name>
    <value>true</value>
</property>
<property>
    <description>cgroup挂载目录, /sys/fs/cgroup 或者是 /cgroup,目录和系统有关</description>
    <name>yarn.nodemanager.linux-container-executor.cgroups.mount-path</name>
    <value>/cgroup</value>
</property>
<property>
    <name>yarn.nodemanager.linux-container-executor.group</name>
    <value>hadoop</value>
</property>
<property>
    <description>配置nodemanager使用多少物理cpu资源,比如24核服务器配置90的话,最近使用21.6核</description>
    <name>yarn.nodemanager.resource.percentage-physical-cpu-limit</name>
    <value>90</value>
</property>
<property>
    <description>是控制是否严格限制cpu,即按任务申请的core限制,还是非严格限制,即按core的比率限制</description>
    <name>yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage</name>
    <value>true</value>
</property>
<property>
    <description>非安全模式将会以这里设置的用户运行container,比如配置hadoop用户则以hadoop运行container</description>
    <name>yarn.nodemanager.linux-container-executor.nonsecure-mode.local-user</name>
    <value>hadoop</value>
</property>

etc/hadoop/container-executor.cfg配置

这个配置文件每项都需要填,要不然会报错

yarn.nodemanager.linux-container-executor.group=hadoop
banned.users=root
min.user.id=1000
allowed.system.users=hadoop

权限设置

在配置中文件的权限有特殊要求

chown root:hadoop bin/container-executor
chmod 6050 bin/container-executor

系统还要求etc/hadoop/container-executor.cfg 的所有父目录(一直到/ 目录) owner 都为 root
这个路径是默认${HADOOP_HOME}/etc/hadoop/container-executor.cfg,如果不方便修改所有父级目录为root权限,可以重新编译代码到其他目录,比如/etc/hadoop/目录

mvn clean package -Dcontainer-executor.conf.dir=/etc/hadoop/ -DskipTests -Pnative

配置好以后检测是否配置成功

./bin/container-executor --checksetup

如果没有任何输出表示配置成功
如果一切顺利就可以启动集群了

测试cgroup

可以运行测试脚本测试系统

./bin/spark-submit   
--class org.apache.spark.examples.SparkPi   
--master yarn-cluster   
--deploy-mode cluster   
--num-executors 5 
--executor-cores 3 
--executor-memory 4G 
--driver-memory 4G 
--driver-cores 2 
lib/spark-examples-1.6.0-hadoop2.6.0.jar   10000

查看系统是否生效只能登录到服务器查看
通过top查看信息

未分类

查看是否创建了cgroup分组,ll /cgroup/hadoop-yarn/

--w--w--w- 1 root root 0 3月  17 15:44 cgroup.event_control
-rw-r--r-- 1 root root 0 3月  17 15:44 cgroup.procs
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000011
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000026
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000051
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000076
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000101
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000123
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000136
drwxr-xr-x 2 root root 0 3月  17 16:06 container_1489736876249_0003_01_000155
drwxr-xr-x 2 root root 0 3月  17 16:30 container_1489736876249_0004_01_000008
-rw-r--r-- 1 root root 0 3月  17 15:47 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 3月  17 15:47 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 3月  17 15:44 cpu.rt_period_us
-rw-r--r-- 1 root root 0 3月  17 15:44 cpu.rt_runtime_us
-rw-r--r-- 1 root root 0 3月  17 15:44 cpu.shares
-r--r--r-- 1 root root 0 3月  17 15:44 cpu.stat
-rw-r--r-- 1 root root 0 3月  17 15:44 notify_on_release
-rw-r--r-- 1 root root 0 3月  17 15:44 tasks

查看container_*目录下 cpu.cfs_period_us,计算cpu.cfs_quota_us/cpu.cfs_period_us即可知道分配的核数

[root@- ~]# cat /cgroup/cpu/hadoop-yarn/container*/cpu.cfs_period_us
462962
462962
462962
462962
462962
462962
462962
462962
308641

问题处理

配置的过程中免不了会碰上一些问题,以下是我碰到的问题

spark任务申请了core,node manager分配不正确,都是分配1个核

这个是由于目前使用的capacity scheduler的资源计算方式只考虑了内存,没有考虑CPU
这种方式会导致资源使用情况统计不准确,比如一个saprk程序启动命令资源参数如下

--num-executors 1 --executor-cores 3 --executor-memory 4G --driver-memory 4G --driver-cores 1

DefaultResourceCalculator 统计占2核
DominantResourceCalculator 统计占4核
修改配置文件即可解决

  <property>
    <name>yarn.scheduler.capacity.resource-calculator</name>
    <value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
    <description>
      The ResourceCalculator implementation to be used to compare
      Resources in the scheduler.
      The default i.e. DefaultResourceCalculator only uses Memory while
      DominantResourceCalculator uses dominant-resource to compare
      multi-dimensional resources such as Memory, CPU etc.
    </description>
  </property>

container-executor运行时报缺少GLIBC_2.14库

container-executor: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by bin/container-executor)

这个和系统版本有关,只能通过重新编译container-executor来解决

mvn clean package -Dcontainer-executor.conf.dir=/etc/hadoop/ -DskipTests -Pnative

centos 7系统container启动报错,不能写入/cgroup/cpu

这个是yarn在centos 7下的一个bug,hadoop 2.8以后的版本才会解决
这个bug主要是因为centos 7下cgroup的目录和centos 6不一致导致,centos 7 cpu目录合并成cpu,cpuacct, 这个,导致的错误,需要打补丁后编译https://issues.apache.org/jira/browse/YARN-2194

 private String findControllerInMtab(String controller,
                                      Map<String, List<String>> entries) {
    for (Entry<String, List<String>> e : entries.entrySet()) {
//      if (e.getValue().contains(controller))
//        return e.getKey();

      if (e.getValue().contains(controller)) {
        String controllerKey = e.getKey();
        // In Redhat7, the controller is called "/sys/fs/cgroup/cpu,cpuacct"
        controllerKey = controllerKey.replace("cpu,cpuacct", "cpu");
        if (new File(controllerKey).exists()) {
          return controllerKey;
        }
      }
    }

    return null;
  }

升级的风险

由于改变了资源的隔离方式,升级可能有几个方面的影响

任务资源分配问题

升级cgroup后单个任务如果以前资源分配不合理可能会出现计算延时情况,出现资源问题时需要调整任务资源
在集群规模小的时候可能没有资源可以调整,那么可以修改为非严格模式,非严格模式不能按配置限制资源,只能保证资源不被少数进程全部占用

<property>
    <name>yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage</name>
    <value>false</value>
</property

spark driver资源问题

spark任务的driver在集群模式deploy-mode cluster时,如果没有配置driver-cores的话默认分配1核,1核在任务规模大时有可能资源会紧张.采用deploy-mode client模式的不受cgroup限制

CentOS 7安装bbr教程

未分类

Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据以往的传统,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
根据实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。

安装

CentOS 7.3

1、yum系统更新(更新到CentOS 7.3)

yum update

2、查看系统版本

cat /etc/redhat-release

输出如下(release数值大于7.3即可),则表示已升级到7.3

CentOS Linux release 7.3.1611 (Core)

3、安装elrepo并升级内核

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-ml -y

正常情况下将输出如下信息:

Transaction Summary
================================================================================
Install  1 Package
Total download size: 39 M
Installed size: 169 M
Downloading packages:
kernel-ml-4.9.0-1.el7.elrepo.x86_64.rpm                    |  39 MB   00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Warning: RPMDB altered outside of yum.
  Installing : kernel-ml-4.9.0-1.el7.elrepo.x86_64                          1/1
  Verifying  : kernel-ml-4.9.0-1.el7.elrepo.x86_64                          1/1
Installed:
  kernel-ml.x86_64 0:4.9.0-1.el7.elrepo
Complete!

4、更新grub文件并重启(reboot后,ssh会断开,稍等一会儿重新连接)

egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d '
grub2-set-default 0
reboot

5、开机后查看内核是否已更换为4.9

uname -r

输出如下内容则表示内核4.9已经启动了(数值大于4.9即可)

4.9.0-1.el7.elrepo.x86_64

CentOS 7.4

导入 elrepo 软件源的 GPG 公钥

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

导入 elrepo 软件源

说明:该地址可以自动下载该源的最新的软件列表,无需修改地址。

rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

下载并安装新的内核

启用软件源并下载安装最新稳定版内核

yum -y --enablerepo=elrepo-kernel install kernel-ml

设定 Grub 默认启动新内核

说明:如果手动修改过 Grub 的配置文件,以下命令可能无法执行成功。请自行修改 Grub 配置文件。

grub2-set-default 0

使用新的内核重启

reboot

检查设置 & 删除旧的内核

查看当前系统的内核版本号

uname -r

如果输出是 4.10 以上的版本,说明安装成功。

4.14.13-1.el7.elrepo.x86_64

删除旧内核

说明:删除旧内核的目的是为了防止 yum 更新旧版内核之后覆盖了 grub 默认启动项

yum -y remove kernel kernel-tools

开启bbr

vim /etc/sysctl.conf

添加如下内容

net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr

加载系统参数(正常情况下会输出我们之前加入的内容)

sysctl -p

验证bbr是否已经开启

a.若

sysctl net.ipv4.tcp_available_congestion_control

返回

net.ipv4.tcp_available_congestion_control = bbr cubic reno

则成功

b.若

lsmod | grep bbr

返回形如如下形式的信息即成功。

tcp_bbr                16384  1
tcp_bbr                20480  0

Ubuntu 16.04 mysql安装配置

安装mysql

sudo apt-get install mysql-server mysql-client

测试是否安装成功

sudo netstat -tap | grep mysql

相关操作

  • 登录 mysql -uroot -p
  • 检查MySQL服务器占用端口 netstat -nlt|grep 3306
  • 检查MySQL服务器系统进程 ps -aux|grep mysql
  • 查看数据库的字符集编码 show variables like ‘%char%’;

让MySQL服务器被远程访问

  • 打开mysql配置文件
# 注意:不同 mysql 版本此配置文件位置和名字可能不同
sudo vim /etc/mysql/my.cnf
#找到将bind-address = 127.0.0.1注销​
#bind-address            = 127.0.0.1
  • 修改后,重启MySQL服务器
sudo /etc/init.d/mysql restart
  • 重新登录mysql -uroot -p
grant all privileges on *.* to 'root'@'%' identified by 'xxxxxx';
flush privileges;
  • 检查MySQL服务器占用端口
~ netstat -nlt|grep 3306
  tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN

我们看到从之间的网络监听从 127.0.0.1:3306 变成 0 0.0.0.0:3306,表示MySQL已经允许远程登陆访问。

将字符编码设置为UTF-8

默认情况下,MySQL的字符集是latin1,因此在存储中文的时候,会出现乱码的情况,所以我们需要把字符集统一改成UTF-8。
打开mysql配置文件

sudo vim /etc/mysql/my.cnf
a) 打开mysql配置文件:

                vim/etc/mysql/my.cnf

b) 在[client]下追加:

                default-character-set=utf8

c) 在[mysqld]下追加:

                character-set-server=utf8

d) 在[mysql]下追加:

                default-character-set=utf8

修改后,重启MySQL服务器,并登录

mysql -uroot -p

再次查看字符串编码

mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

Ubuntu下配置nginx反向代理服务器

Nginx是一个高性能的Web服务器并且也是一个高性能反向代理服务器,多种测试结果表面Nginx在处理静态文件的速度以及性能要优于Apache,而在一些项目中我们可能需要使用Apache搭配nginx做反代,以获得良好的性能提升

今天本教程主要讲如何使用nginx做反向代理服务器.

最基本要求是你的服务器已经安装了Apache作为web,并且运行于80端口.首先我们修改apache默认端口号:

vim /etc/apache2/ports.conf

找到下面行:

NameVirtualHost *:80
Listen 80

我们修改为:

NameVirtualHost *:8080
Listen 8080

修改后我们虚拟主机或默认主机配置文件也要相应修改一下:

#这里默认端口80咱改为8080

现在我们接着禁用一些不需要的模块:

vim /etc/apache2/apache2.conf
KeepAlive Off

接着继续使用命令禁用下列模块:

a2dismod deflate
a2dismod cgi
a2dismod autoindex
a2dismod negotiation
a2dismod ssl

接着我么安装一个转发模块:

apt-get install libapache2-mod-rpaf
#此模块作用是将访客真实ip转发给后面应用层的apache,不然web无法货取到真实访客ip

安装好后我们重启apache:

/etc/init.d/apache2 restart

然后接着设置nginx你用apache想必一定没安装nginx,现在我们先安装一下.

apt-get install nginx
rm -rf /etc/nginx/sites-enabled/*
#然后我们要删掉默认的web项目站点,这里主要是防止产生冲突

删除后我们新建一个默认web主机

cat >/etc/nginx/sites-available/000-default <

并且修改或新建一个项目使请求转发到后面 apachecat >/etc/nginx/sites-available/youdomain.com < 然后我们重启 nginx/etc/init.d/nginx restart #service nginx restart 发起一个请求看看,若后端出现无法获取真实ip问题,记得检查下前面我们提到的转发模块是否安装加载正常.若没问题,恭喜你,配置成功啦.

Ubuntu的apt-file解决依赖问题

1. 背景

平常我们在安装应用时,经常会碰到缺少各种文件、依赖等问题,例如缺少.so文件。Ubuntu中提供了一个强大的工具apt-file来查找依赖。最适合的场景是在Docker中使用,因为Docker Image的系统通常是Ubuntu。

2. 安装

apt-file的安装命令如下:

# Install
$ apt-get update
$ apt-get install apt-file
# Update apt-file
$ apt-file update

3. 搜索缺少的文件

如果缺少cv.py文件,则搜索cv.py文件,apt-file会列出包含cv.py的包,发现需要的包是python-opencv,然后安装ython-opencv。

# 命令格式
$ apt-file seach [filename]
# Demo
$ apt-file search cv.py
gnuradio: /usr/lib/python2.7/dist-packages/gnuradio/analog/wfm_rcv.py
gnuradio: /usr/share/gnuradio/examples/uhd/usrp_am_mw_rcv.py
gnuradio: /usr/share/gnuradio/examples/uhd/usrp_nbfm_rcv.py
gnuradio: /usr/share/gnuradio/examples/uhd/usrp_tv_rcv.py
gnuradio: /usr/share/gnuradio/examples/uhd/usrp_wfm_rcv.py
gnuradio: /usr/share/gnuradio/examples/uhd/usrp_wxapt_rcv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/db_recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/direct_recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/messenger/recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/reactor/recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/selected_recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/simple_recv.py
libqpid-proton2-dev-examples: /usr/share/proton-0.10/examples/python/tx_recv.py
lowpan-test-tools: /usr/lib/x86_64-linux-gnu/lowpan-tools/test_recv.py
python-kivy: /usr/lib/python2.7/dist-packages/kivy/core/camera/camera_opencv.py
python-mvpa2-doc: /usr/share/doc/python-mvpa2-doc/examples/nested_cv.py
python-opencv: /usr/lib/python2.7/dist-packages/cv.py
python-pyavm: /usr/lib/python2.7/dist-packages/pyavm/cv.py
python-pysnmp4: /usr/lib/python2.7/dist-packages/pysnmp/entity/rfc3413/ntfrcv.py
python-pysnmp4: /usr/share/pyshared/pysnmp/entity/rfc3413/ntfrcv.py
python-pysnmp4-doc: /usr/share/doc/python-pysnmp4-doc/examples/v1arch/manager/ntfrcv.py
python-scapy: /usr/lib/python2.7/dist-packages/scapy/sendrecv.py
python-scapy: /usr/share/pyshared/scapy/sendrecv.py
python3-kivy: /usr/lib/python3/dist-packages/kivy/core/camera/camera_opencv.py
python3-pyavm: /usr/lib/python3/dist-packages/pyavm/cv.py
python3-pysnmp4: /usr/lib/python3/dist-packages/pysnmp/entity/rfc3413/ntfrcv.py

4. 列出包中的文件

查看python-opencv中的文件。

# 命令格式
$ apt-file list [package name]
# Demo
$ apt-file list python-opencv
python-opencv: /usr/lib/python2.7/dist-packages/cv.py
python-opencv: /usr/lib/python2.7/dist-packages/cv2.x86_64-linux-gnu.so
python-opencv: /usr/share/doc/python-opencv/changelog.Debian.gz
python-opencv: /usr/share/doc/python-opencv/copyright
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/__init__.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/CamShiftConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/ContourMomentsConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/ConvexHullConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/EdgeDetectionConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/FBackFlowConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/FaceDetectionConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/FindContoursConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/GeneralContoursConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/GoodfeatureTrackConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/HoughCirclesConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/HoughLinesConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/LKFlowConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/PeopleDetectConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/PhaseCorrConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/SegmentObjectsConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/SimpleFlowConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/WatershedSegmentationConfig.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/cfg/__init__.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Circle.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_CircleArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_CircleArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Contour.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_ContourArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_ContourArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Face.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_FaceArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_FaceArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Flow.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_FlowArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_FlowArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_FlowStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Line.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_LineArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_LineArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Moment.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_MomentArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_MomentArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Point2D.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Point2DArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Point2DArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Point2DStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Rect.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RectArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RectArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RotatedRect.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RotatedRectArray.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RotatedRectArrayStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_RotatedRectStamped.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/_Size.py
python-opencv-apps: /usr/lib/python2.7/dist-packages/opencv_apps/msg/__init__.py
python-opencv-apps: /usr/share/doc/python-opencv-apps/changelog.Debian.gz
python-opencv-apps: /usr/share/doc/python-opencv-apps/copyright

5. 其它系统

在其它系统中,例如CentOS中,可以用yum whatprovides命令来查询命令所在的包。

【Ubuntu】修改Ubuntu的apt-get源为国内镜像源的方法

1、原文件备份

sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

2、编辑源列表文件

sudo vim /etc/apt/sources.list

3、将原来的列表删除,添加如下内容(中科大镜像源)

deb http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-proposed main restricted universe multiverse
deb-src http://mirrors.ustc.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse

4、运行sudo apt-get update

在阿里云的CENTOS上搭建GIT服务器

最近突然想把一些原来在本机的代码用git管理起来,本来想再windows上搭一个服务器,转而一想反正有一个阿里云的centos,干脆用起来吧,于是说干就干。

一、检查服务器版本是否自带git

[root@~]# rpm -qa git
git-1.8.3.1-6.el7_2.1.x86_64
language-shell hljs

如果现实git-版本号这种说明已经安装过了,如果没有使用下面的命令安装

yum install git 
language-shell hljs

二、创建git用户并设置密码

[root@]# useradd my2017
[root@]# passwd my2017
Changing password for user my2017.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

三、生成ssh公钥

[root@]# su my2017
[my2017@]$ cd ~
[my2017@ ~]$ ls
[my2017@ ~]$ pws
bash: pws: command not found
[my2017@ ~]$ pwd
/home/my2017
[my2017@ ~]$ mkdir .ssh
[my2017@ ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/my2017/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/my2017/.ssh/id_rsa.
Your public key has been saved in /home/my2017/.ssh/id_rsa.pub.
The key fingerprint is:
0e:b0:b2:b2:4e:8d:a6:08:12:ea:cb:55:6b:f5:64:e2 my2017@iZ2ze3jauhy9b4gdjn!2s2w1
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|    .            |
|     o           |
|. . ...oSo       |
|..oo. +o=        |
|=+.o o E..       |
|Xo. .            |
|==.              |
+-----------------+
[my2017@ ~]$ cd .ssh/
[my2017@ .ssh]$ cat id_rsa.pub >> ~/.ssh/authorized_keys
[my2017@ .ssh]$ exit
exit

四、创建git仓库

[root@ gitrepository]# mkdir mygit.git
[root@ gitrepository]# cd mygit.git/
[root@ mygit.git]# git --bare init
Initialized empty Git repository in /data/gitrepository/mygit.git/

五、修改权限

[root@ data]# chown -R my2017:my2017 gitrepository/
[root@ data]# cd gitrepository/
[root@ gitrepository]# ls -al
total 12
drwxr-xr-x 3 my2017 my2017 4096 Oct 29 23:14 .
drwxr-xr-x 6 root      root      4096 Oct 29 22:54 ..
drwxr-xr-x 7 my2017 my2017 4096 Oct 29 23:15 mygit.git
[root@ gitrepository]# cd mygit.git/
[root@ mygit.git]# ls -al
total 40
drwxr-xr-x 7 my2017 my2017 4096 Oct 29 23:15 .
drwxr-xr-x 3 my2017 my2017 4096 Oct 29 23:14 ..
drwxr-xr-x 2 my2017 my2017 4096 Oct 29 23:15 branches
-rw-r--r-- 1 my2017 my2017   66 Oct 29 23:15 config
-rw-r--r-- 1 my2017 my2017   73 Oct 29 23:15 description
-rw-r--r-- 1 my2017 my2017   23 Oct 29 23:15 HEAD
drwxr-xr-x 2 my2017 my2017 4096 Oct 29 23:15 hooks
drwxr-xr-x 2 my2017 my2017 4096 Oct 29 23:15 info
drwxr-xr-x 4 my2017 my2017 4096 Oct 29 23:15 objects
drwxr-xr-x 4 my2017 my2017 4096 Oct 29 23:15 refs

配置SSH key

六、本地测试

安装git.exe

https://git-for-windows.github.io/

有时候不好下,多刷新几遍。

安装 TortoiseGit

https://tortoisegit.org/

我的一贯宗旨是能鼠标点的绝逼不敲代码。。。。

tortoisegit报错提示:

Disconnected:No supported authentication methods available
(server sent:publickey,gssapi-keyex,gssapi-with-mic)

直接用git客户端报错:

Warning: Permanently added (ECDSA) to the list of known hosts.
my@: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
fatal: Could not read from remote repository.

解决方法:

禁止git用户登录

禁用git用户shell登陆

出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。

vim /etc/passwd

找到类似下面的一行:

git:x:1001:1001:,,,:/home/git:/bin/bash

改为:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。

CentOS 7 安装pure-ftp

安装约定

  • 虚拟用户 www_user_name

  • 虚拟路径 /www/html/www

1、给/www/html/www 赋apache 权限

chown -R apache:apache /www/html/www

2、安装pure-ftpd

yum -y install pure-ftpd

3、下载配好的 pure-ftpd.conf

wget -P /etc/pure-ftpd/ http://www.kglan.com/soft/pure-ftp/pure-ftpd.conf

4、创建 虚拟用户 生成用户数据 db

pure-pw useradd www_user_name -u apache -d /www/html/www
pure-pw mkdb /etc/pure-ftpd/pureftpd.pdb

5、开启服务 设置开机启动

systemctl start  pure-ftpd.service
systemctl enable pure-ftpd.service

CentOS 7.2 搭建内网ntp时间服务器

时间服务器说明

前面在系统的基础优化里说到了时间同步需要同步aliyun的时间,这样我们所有的服务器都需要到公网去同步时间,浪费很多网络资源,这里我们来搭建一下内网的时间服务器。

环境说明

1、时间服务器环境介绍

# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

# uname -r
3.10.0-327.el7.x86_64

# hostname -I
192.168.56.100 172.16.1.100

2、内网需要同步时间的服务器环境介绍

# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core) 

[root@linux-node2 ~]# uname -r
3.10.0-327.el7.x86_64

[root@linux-node2 ~]# hostname -I
192.168.56.12 172.16.1.12

yum安装ntp时间服务

# yum install -y ntp
# rpm -qa ntp        #下载后验证
ntp-4.2.6p5-25.el7.centos.2.x86_64

修改配置文件

[root@web01 ~]# grep -n "^[a-z]" /etc/ntp.conf    #过滤配置文件
4:driftfile /var/lib/ntp/drift       #默认的
9:restrict default nomodify      #注释掉地8行,添加这行,表示nomodify客户端可以同步时间。
14:restrict 127.0.0.1          #默认的
15:restrict ::1                     #默认的
26:server ntp1.aliyun.com       #添加时间源
27:server time.nist.gov            #添加时间源
39:includefile /etc/ntp/crypto/pw      #以下都是默认的
43:keys /etc/ntp/keys
61:disable monitor

启动时间服务器

# systemctl start ntpd
# netstat -lnuto|grep 123           #查看端口
udp        0      0 172.16.1.100:123        0.0.0.0:*                           off (0.00/0/0)
udp        0      0 192.168.56.100:123      0.0.0.0:*                           off (0.00/0/0)
udp        0      0 127.0.0.1:123           0.0.0.0:*                           off (0.00/0/0)
udp        0      0 0.0.0.0:123             0.0.0.0:*                           off (0.00/0/0)
udp6       0      0 fe80::20c:29ff:fe31:123 :::*                                off (0.00/0/0)
udp6       0      0 fe80::20c:29ff:fe31:123 :::*                                off (0.00/0/0)
udp6       0      0 ::1:123                 :::*                                off (0.00/0/0)
udp6       0      0 :::123                  :::*                                off (0.00/0/0)

启动后确认:

# ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 time5.aliyun.co 10.137.38.86     2 u   11   64    1    5.414   -0.946   0.000
 time-c-wwv.nist .STEP.          16 u    -   64    0    0.000    0.000   0.000
发现有两个可用的时间源

稍等几分钟后,在客户端同步时间

客户端如果有同步时间的定时任务需要取消掉。

1、到客户端查看当前时间

# date
Fri Jan 12 21:06:00 CST 2018

2、与时间服务器同步时间

# ntpdate -d 192.168.56.100
12 Jan 22:12:00 ntpdate[6677]: ntpdate [email protected] Wed Apr 12 21:24:06 UTC 2017 (1)
Looking for host 192.168.56.100 and service ntp
host found : linxu-node4
transmit(192.168.56.100)
receive(192.168.56.100)
transmit(192.168.56.100)
receive(192.168.56.100)
transmit(192.168.56.100)
receive(192.168.56.100)
transmit(192.168.56.100)
receive(192.168.56.100)
server 192.168.56.100, port 123
stratum 3, precision -24, leap 00, trust 000
refid [192.168.56.100], delay 0.02617, dispersion 0.00076
transmitted 4, in filter 4
reference time:    de02c1e5.530e0c26  Fri, Jan 12 2018 13:11:01.324
originate timestamp: de02c227.63d8db0f  Fri, Jan 12 2018 13:12:07.390
transmit timestamp:  de0340b6.c05f3381  Fri, Jan 12 2018 22:12:06.751
filter delay:  0.02617  0.02634  0.02634  0.02635 
         0.00000  0.00000  0.00000  0.00000 
filter offset: -32399.3 -32399.3 -32399.3 -32399.3
         0.000000 0.000000 0.000000 0.000000
delay 0.02617, dispersion 0.00076
offset -32399.360102

12 Jan 22:12:06 ntpdate[6677]: step time server 192.168.56.100 offset -32399.360102 sec

3、此时再查看客户端的时间

# date
Fri Jan 12 22:13:01 CST 2018

4、设置定时任务同步时间即可

# crontab -l
# tine rsync   time:2018/1/12
*/5 * * * * ntpdate 192.168.56.100 >/dev/null 2>&1

至此,内网的时间服务器就安装完成了,所有的内网服务器都可以到时间服务器来同步时间,不需要到公网上去同步时间了。

ansible任务的异步执行

ansible方便在于能批量下发,并返回结果和呈现。简单、高效。
但有的任务执行起来却不那么直接,可能会花比较长的时间,甚至可能会比ssh的超时时间还要长。这种情况任务是不是没法执行了?
ansible考虑到了这种情况,官方文档介绍了这个问题的解决方法,就是让下发的任务执行的连接变为异步:任务下发之后,长连接不再保持,而是每隔一段时间轮询结果,直到任务结束。

这是官网相关的介绍: http://docs.ansible.com/ansible/latest/playbooks_async.html

他们在playbook的任务中加入两个参数:async和poll。

  • async参数值代表了这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。此参数若未设置,则为同步执行。
  • poll参数值代表了任务异步执行时轮询的时间间隔。

官方给出例子:

  ----
    hosts: all
    remote_user: root
    tasks:
      - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
        command: /bin/sleep 15
        async: 45
        poll: 5

这时候已经不怕任务超时了。可以执行一个45s的任务,当然也可以根据需要自己设置。另外,如果poll为0,就相当于一个不关心结果的任务。

如果还想要更方便地看轮询结果,ansible还提供了这个模块async_status。

  ---
    # Requires ansible 1.8+
    - name: 'YUM - fire and forget task'
      yum: name=docker-io state=installed
      async: 1000
      poll: 0
      register: yum_sleeper

    - name: 'YUM - check on fire and forget task'
      async_status: jid={{ yum_sleeper.ansible_job_id }}
      register: job_result
      until: job_result.finished
      retries: 30

第一个job执行异步任务,并且注册了一个名字叫yum_sleeper,用于提供给第二个job作为轮询对象,并且poll设为0,它自己不再轮询。

第二个job使用async_status模块,进行轮询并返回轮询结果。准备检查30次。结果如下:

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [cloudlab001]

TASK [YUM - fire and forget task] **********************************************
ok: [cloudlab001]

TASK [YUM - check on fire and forget task] *************************************
FAILED - RETRYING: TASK: YUM - check on fire and forget task (29 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (28 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (27 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (26 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (25 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (24 retries left).
changed: [cloudlab001]

PLAY RECAP *********************************************************************
cloudlab001                : ok=3    changed=1    unreachable=0    failed=0