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

ansible fetch 批量下载服务器文件

今天使用 ansible 进行批量巡检操作。

思路是写一个 Playbooks,将巡检脚本上传到所有服务器 /tmp 目录下,然后执行,并取回输出的文件。输出的文件路径为:/tmp/log/ip.txt 。ip 为本机 ip 。

Playbooks 内容如下:

---
- hosts:  test
  remote_user: toptea

  tasks:
  - name: transfer file to server
    copy: src=/root/xunjian.sh dest=/tmp/xunjian.sh mode=755

  - name: zhixing 
    become: yes
    become_method:  su
    shell:  /bin/bash -x /tmp/pswd.sh 

上传文件使用 copy 模块,执行文件用 shell 模块都没问题。

取回文件出了问题,每台服务器的文件名都是不一样的。

取回文件使用 fetch 模块。测试了如下语句,行不通:

ansible all -m fetch -a "src=/tmp/log/* dest=/tmp/"

疯子哥让我去看官方文档。

http://docs.ansible.com/ansible/latest/fetch_module.html#examples
 fetch:
      src: /tmp/{{ inventory_hostname }}.txt
      dest: /tmp/ss-{{ inventory_hostname }}
      flat: yes

使用这个就可以从所有服务器上下载文件。解释一下:

//fetch 是调用这个模块
 fetch:
 //src 是远程服务器的路径,这里的 inventory_hostname 就是填在 /etc/ansible/hosts 文件里面的内容。比如说 hosts 文件你填的是 192.168.1.3
// 那这里的 {{inventory_hostname}}.txt 就是 192.168.1.3.txt
      src: /tmp/{{ inventory_hostname }}.txt
      dest: /tmp/ss-{{ inventory_hostname }}
      flat: yes

发现问题了吗?对,这个脚本要求你的文件名必须包含 inventory_hostname ,

如果没有怎么办呢?使用下面的脚本:

  tasks:
    - name: fucking
      find:
        paths: /tmp/log/
        patterns: "*"
        recurse: no
      register: file_2_fetch

    - name: fuck your bitch
      fetch:
        src: "{{ item.path }}"
        dest: /tmp/
        flat: yes
      with_items: "{{ file_2_fetch.files }}"

解释一下:

首先调用 find,paths 即你存放文件的路径。 patterns 即你要跟的关键字,这里是 *,即通配符,匹配所有文件。你可以写为 *.txt ,匹配所有 txt 文件。
第二行调用 fetch ,ansible 的 Fetches a file from remote nodes ,
src 即上面的find 查到出来的结果。

执行结果如下:

[root@master ~]# ansible-playbook main.yaml 

PLAY [test] ************************************************************************************

TASK [Gathering Facts] *************************************************************************
ok: [192.168.153.22]

TASK [fucking] *********************************************************************************
ok: [192.168.153.22]

TASK [fuck your bitch] *************************************************************************
ok: [192.168.153.22] => (item={u'uid': 0, u'woth': False, u'mtime': 1516180038.2560008, u'inode': 34964981, u'isgid': False, u'size': 0, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': False, u'islnk': False, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/tmp/log/192.168.153.22.txt', u'xusr': False, u'atime': 1516181632.1700034, u'isdir': False, u'ctime': 1516181291.6150029, u'isblk': False, u'wgrp': False, u'xgrp': False, u'dev': 64768, u'roth': True, u'isfifo': False, u'mode': u'0644', u'rusr': True})
ok: [192.168.153.22] => (item={u'uid': 0, u'woth': False, u'mtime': 1516182493.8110049, u'inode': 1762530, u'isgid': False, u'size': 0, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': False, u'islnk': False, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/tmp/log/1.txt', u'xusr': False, u'atime': 1516182504.3540049, u'isdir': False, u'ctime': 1516182493.8110049, u'isblk': False, u'wgrp': False, u'xgrp': False, u'dev': 64768, u'roth': True, u'isfifo': False, u'mode': u'0644', u'rusr': True})
changed: [192.168.153.22] => (item={u'uid': 0, u'woth': False, u'mtime': 1516182519.4070048, u'inode': 1762531, u'isgid': False, u'size': 0, u'isuid': False, u'isreg': True, u'gid': 0, u'ischr': False, u'wusr': True, u'xoth': False, u'islnk': False, u'nlink': 1, u'issock': False, u'rgrp': True, u'path': u'/tmp/log/2.pdf', u'xusr': False, u'atime': 1516182519.4070048, u'isdir': False, u'ctime': 1516182519.4070048, u'isblk': False, u'wgrp': False, u'xgrp': False, u'dev': 64768, u'roth': True, u'isfifo': False, u'mode': u'0644', u'rusr': True})

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

[root@master ~]# ls /tmp/
192.168.153.22.txt  1.txt  2.pdf

docker-compose中启动镜像失败的问题

正常的docker run启动

java:8u111-jdk是java官方镜像,如下命令可以成功启动一个该镜像的容器:

docker run --name test001 -idt java:8u111-jdk

以上命令创建的容器,可用docker exec -it test001 /bin/bash进入容器,执行我们所需的操作;

docker-compose启动失败

这里写个最简单的docker-compose.yml,然后用docker-compse,内容如下:

master:
  image: java:8u111-jdk

在此文件所在目录下执行docker-compose up -d启动容器,再执行docker ps -a查看容器状态,信息如下所示:

root@rabbitmq:/usr/local/work/test# docker-compose up -d
Creating test_master_1 ... done
root@rabbitmq:/usr/local/work/test# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
bb433fe9984d        java:8u111-jdk      "/bin/bash"         About a minute ago   Exited (0) About a minute ago                       test_master_1

信息显示我们启动的容器状态为Exited (0) About a minute ago,也就是说虽然创建了容器,但是该容器并未正常运行;

控制终端缺失

启动失败是因为缺失了控制终端的配置,这里有两种方式修复;

使用tty参数(推荐使用)

修改docker-compose.yml,增加一个配置tty:true,如下:

master:
  image: java:8u111-jdk
  tty: true

先执行docker-compose down将之前的容器删除,再执行docker-compose up -d启动,可以发现启动成功,并且可以成功进入容器进行操作:

root@rabbitmq:/usr/local/work/test# docker-compose up -d
Creating test_master_1 ... done
root@rabbitmq:/usr/local/work/test# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f51debaa26ec        java:8u111-jdk      "/bin/bash"         2 seconds ago       Up 2 seconds                            test_master_1
root@rabbitmq:/usr/local/work/test# docker exec -it test_master_1 /bin/bash
root@f51debaa26ec:/# java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

使用exec重新创建容器(不推荐)

这种方式并不推荐,因为这样做虽然可以启动容器,但是只能重新创建一个容器,具体方法如下:

  1. 使用docker-compose up -d命令启动后,由于没有tty:true的配置,容器就退出了;

  2. 这时候执行命令docker-compose run master /bin/bash,会创建一个容器,并且进入这个容器;

  3. 在当前电脑再打开一个控制台,执行docker ps命令,发现新建了一个容器,状态正常;