2015年2月25日 星期三

Linux at 使用

at和crontab差異
at 是個可以處理僅執行一次就結束排程的指令,不過要執行 at 時, 必須要有 atd 這個服務 (第十八章) 的支援才行。
crontab 這個指令所設定的工作將會循環的一直進行下去!

直接使用
$ at now + 1 minutes
warning: commands will be executed using /bin/sh
at> touch /tmp/bear003 
at> <EOT>   <==這裡輸入 [ctrl] + d 就會出現 <EOF> 的字樣!代表結束!
job 26 at Wed Feb 25 16:52:00 2015

一分鐘後執行
$ echo "touch /tmp/bear001" | at now + 1 minutes
特定時間執行
$ echo "touch /tmp/bear002" |at 16:39 2015-02-25

檢查
$ ls /tmp/bear*

在php用exec執行
$time = time();
exec("echo \"touch /tmp/bear$time\" | at now + 1 minutes");

參考資料:
http://linux.vbird.org/linux_basic/0430cron/0430cron-fc4.php#at

2015年2月16日 星期一

MySQL權限管理

在連docker container ( IP: 172.17.0.2 )的mysql時發現抓不到newdatabase的資料
mysql.php:
mysql_connect("172.17.0.2", "root", "password");
mysql_select_db("newdatabase");

$result = mysql_query("SELECT database();");

while ($row = mysql_fetch_array($result,  MYSQL_ASSOC)) {
    echo $row['database()'];
}

mysql_free_result($result);
結果:
$ php mysql.php
(空)

連進去檢查( 注意,下面每次更改權限後,必須重新登錄才有效 )
$ mysql -u root -p -h 172.17.0.2
然後發現找不到table ( 但是在172.17.0.2上直接連正常 )
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+

檢查權限
mysql> SHOW GRANTS FOR 'root'@'localhost';
+--------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                        |
+--------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD 'xxx' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION                                     |
+--------------------------------------------------------------------------------------------------+
mysql> SHOW GRANTS FOR 'root'@'%';
+----------------------------------------------------------------+
| Grants for root@%                                              |
+----------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*xxx' |
+----------------------------------------------------------------+

原來是newdatabase表沒開放權限給其他ip

開放(GRANT)權限
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' ;
這樣Grants for root@% 就會變成:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*xxx'

亦可以通過特定的權限
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'root'@'%';

移除權限
mysql> REVOKE ALL PRIVILEGES ON *.* FROM 'root'@'%' ;
這樣Grants for root@% 就會變成:
GRANT USAGE ON *.* TO 'root'@'%' IDENTIFIED BY PASSWORD '*xxx'

秀出系統現在有哪些 user
mysql> SELECT User,Host FROM mysql.user;

參考資料:
http://blog.longwin.com.tw/2009/06/query-mysql-show-grant-permission-2009/


2015年2月15日 星期日

ubuntu 安裝 php-pear

環境:docker ubuntu 14.04

# apt-get install libssl-doc libssl-dev php-pear php5-dev
報錯:
...
The following packages have unmet dependencies:
 libssl-dev : Depends: libssl1.0.0 (= 1.0.1f-1ubuntu2) but 1.0.1f-1ubuntu2.4 is to be installed
E: Unable to correct problems, you have held broken packages.

解法:
移除libssl1.0.0 重裝( apt-get upgrade 無效 )
# dpkg --purge --force-all libssl1.0.0
# apt-get install -f libssl1.0.0



MySQL Master Slave Replication

我使用使用docker 的ubuntu 14.04 image產生的container來實做

我們為什麼要使用Master/Slave模式?
1.物理服务器增加,负荷增加
2.主从只负责各自的写和读,极大程度的缓解X锁( insert, update, delete )和S锁(select)争用
3.从库可配置myisam引擎,提升查询性能以及节约系统开销
4.从库同步主库的数据和主库直接写还是有区别的,通过主库发送来的binlog恢复数据,但是,最重要区别在于主库向从库发送binlog是异步的,从库恢复数据也是异步的
5.读写分离适用与读远大于写的场景,如果只有一台服务器,当select很多时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能不高。 对于写和读比例相近的应用,应该部署双主相互复制
6.MySQL复制另外一大功能是增加冗余,提高可用性,当一台数据库服务器宕机后能通过调整另外一台从库来以最快的速度恢复服务,因此不能光看性能,也就是说1主1从也是可以的。

基本安裝套件:
# apt-get install vim screen bash-completion openssh-server openssh-client wget
安裝MySQL:
# apt-get install mysql-server mysql-client

commit後分別run兩個container來實做,Master IP:172.17.0.2,Slave IP:172.17.0.5

一、設定Master Database

1. 編輯 /etc/mysql/my.cnf
bind-address = 127.0.0.1 => 改成你的Master IP
bind-address = 172.17.0.2
server-id = 1 # 移除註解
log_bin            = /var/log/mysql/mysql-bin.log # 移除註解
binlog_do_db = newdatabase # 移除註解,並設定你須要同步的db名字

2. 重啟MySQL,並登錄設定
# service mysql restart
# mysql -u root -p
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'password'; #記得改slave_user 和password
mysql> FLUSH PRIVILEGES;
mysql> USE newdatabase;
mysql> FLUSH TABLES WITH READ LOCK; # lock資料庫,避免新的更變
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |     1882 | newdatabase  |                  |
+------------------+----------+--------------+------------------+
在另一個tty上備份資料庫
# mysqldump -u root -p --opt newdatabase > newdatabase.sql
mysql> UNLOCK TABLES; # unlock資料庫,讓他再度能寫入

二、設定Slave Database

1. 建立資料庫
mysql> CREATE DATABASE newdatabase;
2. 匯入剛剛在Master Database的資料庫
# mysql -u root -p newdatabase < /path/to/newdatabase.sql
3. 編輯 /etc/mysql/my.cnf
server-id = 2 # 必須與Master不一樣
relay-log = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = newdatabase
4. 重啟資料庫
# service mysql restart
5. 設定Slave Database的Master DB
mysql> CHANGE MASTER TO 
MASTER_HOST='172.17.0.2',MASTER_USER='slave_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS= 1882;  # 請參考在Master Database執行 SHOW MASTER STATUS; 的結果設定
mysql> START SLAVE; # 啟動Slave
mysql> SHOW SLAVE STATUS\G #檢查slave 狀態
如果遇到連線問題,試著用下面指令啟動Slave(我沒做這步)
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; SLAVE START;

檢測:
在Master上,insert, update, delete後,Slave的資料庫也會跟著同步

後記:
我用docker container去實做,基本上沒遇到什麼問題,貼貼指令就結束了。如何讓php讀寫分離,和檢測是否真的讀寫分離,之後再測試。

參考資料:
https://www.digitalocean.com/community/tutorials/how-to-set-up-master-slave-replication-in-mysql
http://segmentfault.com/q/1010000000304576 # 為什麼要使用M/S 架構
http://blog.longwin.com.tw/2008/03/mysql_replication_master_slave_set_2008/ # Master/Slave 設定方法 中文版
http://blog.wu-boy.com/2008/12/mysql-%E5%AF%A6%E5%81%9A-mysql-master-master-replication-%E5%90%8C%E6%AD%A5/ # Master/Slave 設定方法 中文版

2015年2月11日 星期三

linkedin 詐騙

相信不少人有在用linkedin,最近收到一封詐騙的訊息,寫在這邊請大家小心

2015/2/5下午有個叫 marlowe william 的傢伙,他的title是 Accountant at Lloyds TSB Bank,connet了我後傳了封訊息跟我要email要提供business proposal給我

後來他寄了business proposal 來,大意是說他有個客戶死掉了,因為我的姓跟他一樣,想要我幫他處理遺產,說有900萬英鎊,事成之後一人一半。中間還說他是個誠實的人,會附上他的國際護照ID。

因為看起來就像是詐騙,所以我沒回應他

過了兩天這傢伙的linkedin 檔案已經找不到了,我們在linkedin的訊息也被linkedin刪除了

參考資料:
http://jatoy2002.pixnet.net/blog/post/20485339-%5B%E7%97%85%E6%AF%92%5D-%E6%8A%97%E9%80%9A%E8%86%A8%EF%BC%8C%E9%A7%AD%E5%AE%A2%E9%8E%96%E5%AE%9A%E7%A4%BE%E4%BA%A4%E7%B6%B2%E7%AB%99linkedin-

2015年2月9日 星期一

docker 指令自動完成


https://github.com/docker/docker/blob/master/contrib/completion/bash/docker (採用)

https://gist.github.com/felixbuenemann/5605854
的內容複製貼上到
/etc/bash_completion.d/docker 
然後重新登錄

或( 於上面第一個網址內容註解中的教學 )
#  - copy this file to e.g. ~/.docker-completion.sh and add the line
#    below to your .bashrc after bash completion features are loaded
#    . ~/.docker-completion.sh

Docker's process的attach 和 detach
detach - Ctrl-p  + Ctrl-q
attach - docker attach -sig-proxy=false container_id ( ex. docker attach -sig-proxy=false 304f5db405ec )

參考資料:
http://stackoverflow.com/questions/19688314/how-do-you-attach-and-detach-from-dockers-process

在VPS上跑docker

VPS: linode
OS: CentOS 6.6

CentOS 系列安装 Docker
$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum install docker-io
( 如果報錯:
...
error: Couldn't fork %pre(libcgroup-0.40.rc1-15.el6_6.x86_64): Cannot allocate memory
代表記憶體不夠,我先把apache關掉再裝)

然後照 docker 使用心得 登錄docker hub帳號並pull下你的repository

執行時報錯 - failed to find the cgroup root
# docker run -t -i kalecgos0616/bear-test:latest bash
FATA[0000] Error response from daemon: Cannot start container 9292dac26b4d594b1e8ebea10e16f4f17a5b6bf52d3da45d233ce96c8237e275: failed to find the cgroup root
解法:
1. 停用docker
2. 編輯 /etc/cgconfig.conf ,把 memory  = /cgroup/memory; 這行註解掉
3. 重啟cgconfig
# /etc/init.d/cgconfig restart
4. 啟用docker並執行

參考資料:
http://yeasy.gitbooks.io/docker_practice/content/install/centos.html # CentOS 系列安装 Docker
https://forum.linode.com/viewtopic.php?t=10993&p=64060 # linode執行docker錯誤時的解法

arch linux安裝yaourt

編輯 /etc/pacman.conf 添加:
[archlinuxcn]
SigLevel = Optional TrustAll
#Server  = http://repo.archlinuxcn.org/$arch
Server = http://mirrors.ustc.edu.cn/archlinuxcn/$arch # 依你國家而異使用速度較快的鏡像,我使用中國的鏡像
同步
# pacman -Sy
安裝
# pacman -S yaourt

開新user
# groupadd bear
# useradd -r -g bear bear
# mkdir -p /home/bear
# chown bear:bear -R /home/bear
查詢group
# vi /etc/group
刪除新增錯誤的group
# groupdel beaer

PKGBUILD 安裝( 因makepkg 不能使用root執行,所以我先開了一個bear 的user )
$ curl -O https://aur.archlinux.org/packages/pa/package-query/package-query.tar.gz
$ tar zxvf package-query.tar.gz
$ cd package-query
$ makepkg -si 
==> ERROR: Cannot find the strip binary required for object file stripping.
( 解決方放: pacman -S binutils,但是仍然會報錯:
make: error while loading shared libraries: libunistring.so.2: cannot open shared object file: No such file or directory
==> ERROR: A failure occurred in build().
    Aborting...
看起來是docker的問題... https://github.com/runtimejs/runtime/issues/30
)
$ cd ..
$ curl -O https://aur.archlinux.org/packages/ya/yaourt/yaourt.tar.gz
$ tar zxvf yaourt.tar.gz
$ cd yaourt
$ makepkg -si
$ cd ..


參考資料:
https://wiki.archlinux.org/index.php/Yaourt_(%E6%AD%A3%E9%AB%94%E4%B8%AD%E6%96%87) # Yaourt (正體中文)
https://archlinux.fr/yaourt-en #安裝方法
https://bbs.archlinux.org/viewtopic.php?id=140055 # ERROR: Cannot find the strip binary required for object file stripping 解決方式
https://github.com/archlinuxcn/mirrorlist-repo # Arch Linux CN Community repo mirrors list

docker 使用心得


查docker資訊

# docker info

下載archlinux 的docker images
# docker pull base/archlinux

查有哪些images
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
base/archlinux      latest              dce0559daa1b        6 months ago        282.9 MB

執行容器
# docker run -t -i base/archlinux:latest bash
[root@b42626ce6a25 /]#
進入容器後,因為root家目錄是/,直接設定HOME環境變數即可 。相關issue:https://github.com/docker/docker/issues/2968
[root@b42626ce6a25 /]# HOME=/root

查docker的環境變數
# docker run -i -t bear-test env|grep HOME
HOME=/

修改Arch的 Mirrors
編輯:/etc/pacman.d/mirrorlist
去 https://www.archlinux.org/mirrorlist/ 選擇你的國家,直接貼上產生的mirrorlist,然後更新
# pacman -Sy

安裝wget
# pacman -S wget

保存目前的容器更變

在主機系統上開一個新的終端機
查看目前正在運行的容器狀態
# docker ps   # -a tag: Show all containers.不加只會顯示在跑的containers
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS               NAMES
b42626ce6a25        base/archlinux:latest   "bash"              17 minutes ago      Up 17 minutes                           elated_fermi

commit更變
# docker commit -m "Add wget!" -a "Bear" b42626ce6a25 bear-test

查commit messages
# docker inspect image_id | grep Comment
ex. 
# docker inspect d98d54bb671a | grep Comment
   "Comment": "Add wget!",

docker logs
# docker logs b42626ce6a25
( 會顯示你的console 畫面的紀錄 )

查docker comment message
# docker images --no-trunc -a | awk '{print $3}' | xargs docker inspect | less

保存到https://hub.docker.com ( 需先去該docker hub註冊帳號 )
# docker login 
Username: username
Password: 
Email: your@email
Login Succeeded

push
# docker push bear-test
FATA[0000] You cannot push a "root" repository. Please rename your repository in <user>/<repo> (ex: kalecgos0616/bear-test)
所以當初在命名repository名字時,要以<user>/<repo> 的格式命名

複製且重新命名docker images
# docker tag image_id username/repository_name
ex.
# docker tag d98d54bb671a kalecgos0616/bear-test

再次push到docker hub
# docker push kalecgos0616/bear-test
The push refers to a repository [kalecgos0616/bear-test] (len: 1)
Sending image list
Pushing repository kalecgos0616/bear-test (1 tags)
511136ea3c5a: Image already pushed, skipping 
9b0516337e5a: Image already pushed, skipping 
dce0559daa1b: Image already pushed, skipping 
d98d54bb671a: Image successfully pushed 
Pushing tag for rev [d98d54bb671a] on {https://cdn-registry-1.docker.io/v1/repositories/kalecgos0616/bear-test/tags/latest}

這時候你上docker hub ( https://hub.docker.com/u/kalecgos0616/ ),就會看到你剛剛推上去的docker Repository

移除images
# docker rmi base/archlinux
如果報錯
# docker rmi bear-test    
Error response from daemon: Conflict, cannot delete debdf1ba8b30 because the container 113b1d60ffe1 is using it, use -f to force
FATA[0000] Error: failed to remove one or more images
則使用-f 強制刪除
# docker rmi -f bear-test

pull docker hub上的repository
# docker pull kalecgos0616/bear-test

容器使用host的ip和port
# docker run -t -i -p <hostPort>:<containerPort> REPOSITORY:TAG bash
例:
# docker run -t -i -p 5566:80 base/archlinux:latest bash

將容器的80 port 發布到 host的5566 port,假設host 的ip 是 192.168.1.2 ,即可以 http://192.168.1.2:5566 訪問容器的網頁伺服器


centos:6.6 安裝執行screen會報錯
Cannot access '/7': No such file or directory
解法:
改使用centos:latest ( CentOS 7)

下載官方的repos
https://registry.hub.docker.com/repos/library/ 找你要下載的repos,假設要下載ubuntu最新版
# docker pull ubuntu
如要下載centos 6.6(Tag)版,可以指定Tags
# docker pull centos:6.6

參考資料:
https://wiki.archlinux.org/index.php/Docker
http://www.codedata.com.tw/social-coding/docker-layman-abc/ # 門外漢的 Docker 小試身手
http://stackoverflow.com/questions/19035358/how-to-copy-and-rename-a-docker-container # 複製且重新命名docker container

2015年2月5日 星期四

Arch 安裝docker

安裝docker ( 必須是64位元電腦,用 file /bin/bash 檢查 )
# pacman -S docker

運行docker
# systemctl start docker

檢查運行狀態
# systemctl status docker

如果運行失敗,則將依賴的包,安裝更新成最新板
bridge-utils
device-mapper
iproute2
lxc
sqlite

設置網路環境
IPv4数据包转发在缺省值的情况下是禁用的,所以容器可能是不起作用的,
需要开启转发,作为root用户运行在主机系统上
# sysctl net.ipv4.ip_forward=1
允许IPv4修改主机的/etc/sysctl.d/docker.conf,需要重新启动:
net.ipv4.ip_forward=1

參考資料:
https://github.com/widuu/docker_course/blob/master/install/docker-arch.md

Arch swap心得

某天裝完docker後忽然發現我電腦沒有配置swap,所以來研究一下如何配置swap

查swap狀態:
$ swapon -s  # 因為swap不是 filesystem( 如ext3 ),因此不能用df -h查到他
$ free -mh

Swap partition

# mkswap /dev/sda2 16777216
mkswap: /dev/sda2: warning: wiping old swap signature.
Setting up swapspace version 1, size = 16777216 KiB
no label, UUID=81b2c757-50c8-4ef3-919f-ca9f94be77ba
警告:所有在/dev/sda2 partition的資料將會遺失

ps.
swap 大小要設多大?
通常是2倍的記憶體大小,或 [(2 x RAM) + 1 MB] = Swap File Size。
Red Hat建議的最小設定
物理内存交换分区(SWAP)
<= 4G至少2G
4~16G至少4G
16G~64G至少8G
64G~256G至少16G
ps 我的電腦RAM是8GB,所以swap 設16777216 是1024*1024*16( 16 GB)

UUID會自動產生,或 使用-U flag去指定UUID
# mkswap -U custom_UUID /dev/sda2
ex.
# mkswap -U 81b2c757-50c8-4ef3-919f-ca9f94be77ba /dev/sda2 16777216
啟用swap
# swapon /dev/sda2

啟用swap當開機後
1. 編輯 /etc/fstab
2. 在最後面加入這行
/dev/sda2 none swap defaults 0 0

Swap file creation

例:產生一個512MB的swap檔案
# fallocate -l 512M /swapfile

# dd if=/dev/zero of=/swapfile bs=1M count=512 #我用這個
設定正確的權限
# chmod 600 /swapfile
設成swap格式
# mkswap /swapfile
啟用swap檔案
# swapon /swapfile
啟用swap當開機後
1. 編輯 /etc/fstab
2. 在最後面加入這行
/swapfile none swap defaults 0 0
注意:
我原本參考鳥哥的方式把swapfile放到 /tmp/swapfile這 ,但是swapon時出現錯誤。
swapon: swapfile: swapon failed: Invalid argument
原因:
So "Invalid argument" should be read as "Your filesystem do not support swap file"
檢查:
# df -h -T  # -T, --print-type print file system type
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda1      ext4       30G   22G  6.5G  77% /
dev            devtmpfs  3.9G     0  3.9G   0% /dev
run            tmpfs     3.9G  960K  3.9G   1% /run
tmpfs          tmpfs     3.9G   49M  3.9G   2% /dev/shm
tmpfs          tmpfs     3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs          tmpfs     3.9G  136K  3.9G   1% /tmp
/dev/sda5      ext4       15G  3.0G   11G  22% /srv
/dev/sda7      ext4      200G   93G   97G  50% /home
tmpfs          tmpfs     789M  4.0K  789M   1% /run/user/1001
tmpfs大概不支持swap file ,所以把他放在根目錄的ext4下面

移除swap

關掉swap
# swapoff -a
移除swap 檔案
# rm -f /swapfile

liunx(btrfs,ext3,ext4,jfs,reiserfs,xfs)文件系统比较
結論:
linux中比较推荐的文件系统是ext4, xfs两种。大量文件存储用xfs小规模文件密集使用用ext4。在特定情况下,可以使用btrfs(它的特性非常全)或者jfs(小文件操作慢,但是随机读写快)。兼容考量下,可以用ext3。不推荐使用reiser4。

參考資料:
https://wiki.archlinux.org/index.php/swap
http://linux.vbird.org/linux_basic/0230filesystem.php#swap
http://superuser.com/questions/16280/swap-partition-size-for-4gb-ram #swap要設多大
http://www.cyberciti.biz/tips/linux-swap-space.html # Red Hat建議swap最小要設多大
http://superuser.com/questions/539287/swapon-failed-invalid-argument-on-a-linux-system-with-btrfs-filesystem # Invalid argument 錯誤解釋
http://wenku.baidu.com/view/4c18863543323968011c92f7.html # liunx(btrfs,ext3,ext4,jfs,reiserfs,xfs)文件系统比较