0%

docker-vs-vms

Deploy

Linux部署

(由于Linux发行版众多,本文以RHEL7.2为例)

单机版环境docker部署

通过yum源安装docker,yum install docker

安装完成后,使用docker version查看docker客户端和服务端版本号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ docker version
Client:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:23:59 2016
OS/Arch: linux/amd64

Server:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 02:23:59 2016
OS/Arch: linux/amd64

分布式环境docker部署

详细请见:docker官网关于linux环境安装部分

MacOS部署

从Docker官网上下载Docker.dmg(下载地址:https://www.docker.com/products/docker#/mac),并安装。

安装完成后,使用docker version查看docker客户端和服务端版本号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ docker version
Client:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 06:14:34 2016
OS/Arch: darwin/amd64

Server:
Version: 1.12.5
API version: 1.24
Go version: go1.6.4
Git commit: 7392c3b
Built: Fri Dec 16 06:14:34 2016
OS/Arch: linux/amd64

Container

容器创建&删除

docker create

使用docker create {选项} {镜像ID/镜像名称} {COMMAND}创建容器,返回容器ID

1
2
$ docker create -i -t --name=ubu my_ubuntu_03 /bin/bash
1af8ed9b04f8b16d264418038e1f4004b1f5512f229059646a5c9b1d20ed8404

docker run

使用docker run {选项} {镜像ID/镜像名称} {COMMMAND}创建并运行容器,run = create + start。

1
docker run -i -t ubuntu /bin/bash

docker rm

使用docker rm {容器ID/容器名称}删除已经停止的容器,使用-f参数,可删除正在运行中的容器。

容器查询

docker ps

使用docker ps列出所有运行中的容器,带-a参数,可列出所有容器(包括非运行状态的容器)

1
2
3
4
5
6
7
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1af8ed9b04f8 my_ubuntu_03 "/bin/bash" 2 minutes ago Up 3 seconds ubu
ebe0ce381aaf my_ubuntu_03 "/usr/sbin/sshd -D" 42 hours ago Up 42 hours 0.0.0.0:50022->22/tcp ubu_03_sshd
e69e9d4cdfa3 my_ubuntu_01 "/bin/bash" 43 hours ago Exited (0) 42 hours ago ubu_01
0fa200a32e8e ceph/daemon "/entrypoint.sh osd" 47 hours ago Up 47 hours ceph-osd
be0583fade06 ceph/daemon "/entrypoint.sh mon" 4 days ago Up 47 hours ceph-mon

docker inspect

使用docker inspect {容器ID/容器名称}查看容器详细信息(容器详细信息以JSON格式返回)

1
2
3
4
5
6
7
8
9
10
11
$ docker inspect ubu_03_sshd
[
{
"Id": "ebe0ce381aafa73ec679ec0dc38e8d54291378693146a65d3655dd574c76ec01",
"Created": "2016-12-26T08:00:56.73955094Z",
"Path": "/usr/sbin/sshd",
"Args": [
"-D"
],
......
]

容器启停

使用docker start/stop {容器ID/容器名称}启动或停止容器运行。

容器访问

在容器内执行命令

1
2
3
4
$ docker exec ubu ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:01 ? 00:00:00 /bin/bash
root 10 0 0 07:02 ? 00:00:00 ps -ef

Attach/Detach容器

1
2
$ docker attach ubu
root@1af8ed9b04f8:/#

Detach容器时,只要在command line中输入exit即可,但detach时,会导致容器停止运行。所以若不想导致容器停止运行可以使用docker exec -it ubu /bin/bash

Image

镜像创建

创建新镜像(Dockerfile)

使用Dockerfile创建镜像,首先需要选择基础镜像,然后撰写dockerfile,最后使用docker build -t {new image name}:{new image tag} [-f {dockerfile}] .创建Image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ docker build -t new_image_ubu03:v1 -f ./dockerfile/tmp.docker .
Sending build context to Docker daemon 317.7 MB
Step 1 : FROM my_ubuntu_03
---> 28b69113a240
Step 2 : MAINTAINER xxx xx "x.xxx@xxxx.com"
---> Running in ae3004ef2bd2
---> 68ab9a056fbf
Removing intermediate container ae3004ef2bd2
Successfully built 68ab9a056fbf

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_image_ubu03 v1 68ab9a056fbf 14 seconds ago 304.4 MB
my_ubuntu_01 v1 e1aace2f9532 46 hours ago 304.4 MB
my_ubu base 31184d4c3c2c 47 hours ago 317.7 MB
my_ubuntu_03 latest 28b69113a240 3 days ago 304.4 MB
my_ubuntu_01 latest 800c37009cde 3 days ago 270 MB
ubuntu latest 104bec311bcd 2 weeks ago 128.9 MB
ceph/daemon latest c06ccf521c4e 6 weeks ago 1.078 GB

关于dockerfile的撰写请见《Dockerfile》

基于已有镜像创建新镜像

使用docker commit {容器名称/容器ID} {RESPOSITORY}<TAG>用已有容器创建镜像。

1
2
$ docker commit ubu_01 my_ubuntu_01:v1
sha256:e1aace2f953280326b96f31708ddf8f9f02289845e997736fcb1d0342777c72f

从docker hub上下载新镜像

在docker hub上有很多镜像,供使用者下载,用户可以使用docker search查询要下载的镜像,然后使用docker pull下载镜像。

1
2
3
4
5
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Image is up to date for hello-world:latest

镜像查询

查询本地镜像

1
2
3
4
5
6
7
8
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my_ubu base 31184d4c3c2c 7 seconds ago 317.7 MB
my_ubuntu_03 latest 28b69113a240 47 hours ago 304.4 MB
my_ubuntu_01 latest 800c37009cde 2 days ago 270 MB
ubuntu latest 104bec311bcd 12 days ago 128.9 MB
ceph/daemon latest c06ccf521c4e 5 weeks ago 1.078 GB
hello-world latest c54a2cc56cbb 5 months ago 1.848 kB

查询镜像详细信息

使用docker inspect {IMAGE ID/REPOSITORY}<:{TAG}>查询镜像库的详细信息,TAG默认为“latest”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ docker inspect my_ubu:base
[
{
"Id": "sha256:31184d4c3c2cbbc56e087dfff68cad2d2d89d628a260f6789baf108345cd6c9b",
"RepoTags": [
"my_ubu:base"
],
"RepoDigests": [],
"Parent": "",
"Comment": "Imported from -",
"Created": "2016-12-28T07:30:31.500350508Z",
"Container": "",
"ContainerConfig": {
......
]

查询hub上的镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ docker search ceph
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ceph/daemon Image containing all the Ceph daemons 29 [OK]
ceph/demo 10 [OK]
ceph/osd Ceph OSD (object storage daemon) 6 [OK]
ceph/base Ceph base image 5 [OK]
ceph/radosgw Ceph RADOSGW (S3/Swift-like service for Ceph) 4 [OK]
cdxvirt/ceph-daemon All-in-one container for cdxvirt ceph core... 2 [OK]
ceph/config Ceph bootstrap (configuration) 2 [OK]
ceph/rbd Ceph rbd (RADOS block device) CLI tool 2 [OK]
ceph/mds Ceph MDS (metadata server) 2 [OK]
ulexus/ceph-osd DEPRECATED: development is now at ceph/osd 2 [OK]
ceph/mon Ceph MON (monitor daemon) 1 [OK]
h0tbird/ceph Containerized Ceph distributed file system 1 [OK]
ceph/rados Ceph rados (reliable autonomic distributed... 1 [OK]
cdxvirt/ceph-base Ceph base container image 1 [OK]
qnib/ceph-base QNIBTerminal ceph base image 0 [OK]
qnib/ceph-mono Monolithic approach of an CEPH cluster + r... 0 [OK]
fernandosanchez/ceph-dash ceph-dash 0 [OK]
ceph/install-utils Install wrappers for common Ceph utility p... 0 [OK]
qnib/ceph-mon QNIBTerminal CEPH monitoring Image 0 [OK]
cephbuilder/ceph Docker image for building custom Ceph daem... 0 [OK]
qnib/d-ceph-fuse QNIBTerminal image (debian) mounting /ceph... 0 [OK]
ulexus/ceph-mon DEPRECATED: development is now at ceph/mon 0 [OK]
fmeppo/ceph-daemon Main container for Ceph in Docker. 0 [OK]
fmeppo/ceph-base Base container for Ceph in Docker. 0 [OK]
xenopathic/ceph-keystone Automated full-stack Ceph environment with... 0 [OK]

镜像删除

使用docker rmi {REPOSITORY/IMAGE ID}删除镜像。

1
2
3
4
5
$ docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Deleted: sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc
Deleted: sha256:a02596fdd012f22b03af6ad7d11fa590c57507558357b079c3e8cebceb4262d7

镜像导出导入

save & load

只用于镜像(image)的导入导出文件

export & import

  • export用于容易导出成文件
  • import用于文件导入成镜像(image)

关系图

import_export

Volume

数据卷创建、删除、查询、权限

创建&权限

*** docker在创建容器时,可以创建数据卷;一旦容器运行后,就不能动态添加数据卷。若想添加需要重新创建容器。***

私有数据卷创建

docker run/create时,使用-v {容器内路径}参数在容器内创建指定的目录,并映射到其宿主机/var/lib/docker/volumes/{ID}/_data的路径下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 数据卷创建
$ docker run -it --name=ubu2 -v=/home/zhoub/docker/data ubuntu /bin/bash
# 数据卷查询
$ dccker inspect ubu2
...
"Mounts": [
{
"Name": "95868b7e6fd47927cfb7f54b35057545f4302d69ed92aa73425dffc289527b6b",
"Source": "/var/lib/docker/volumes/95868b7e6fd47927cfb7f54b35057545f4302d69ed92aa73425dffc289527b6b/_data",
"Destination": "/home/zhoub/docker/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...

共享数据卷创建

docker run/create时,使用-v {宿主机路径:容器内路径:访问权限(ro/rw,默认是RW)}参数挂载数据目录或文件到容器内,宿主机与容器共享该目录,无论宿主机还是容器修改该目录后,另一方也能看到改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 数据卷创建
$ docker run -it --name=ubu -v=/home/zhoub/docker/data:/data ubuntu /bin/bash
# 数据卷查询
$ docker inspect ubu
...
"Mounts": [
{
"Source": "/home/zhoub/docker/data",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...

数据卷删除

  • 仅使用docker rm删除容器,会导致数据卷无法删除,仍占用硬盘空间
  • 使用docker rm -v删除容器和数据卷

数据卷容器

创建数据卷容器

1
$ docker run -v /vol --name voldata ubuntu echo "Data Container"

1
$ docker create -v /vol --name voldata ubuntu echo "Data Container"

注:

  • 数据卷容器不需要运行,运行会白浪费系统资源
  • 不要下载微小镜像创建数据卷容器,只使用本机所带的镜像即可,不需要咱用额外的存储空间。

使用数据卷容器

docker run中使用--volumes-from参数为新建的容器挂载voldata数据卷容器中的/vol目录

1
$ docker run --volumes-from voldata -it --name testContainer ubuntu /bin/bash

数据卷备份

将数据卷容器中数据卷里的数据备份到指定目录中

步骤:

  1. 创建备份目录
  2. 创建容器映射备份目录到容器内,并挂载数据卷容器
  3. 在容器中将数据卷容器中的数据copy到映射的备份目录内
1
2
3
$ mkdir /tmp/backup

$ docker run --rm --volumes-from voldata -v /tmp/backup:/backup ubuntu tar cvf /backup/voldata.tar /vol

看到此处估计你已经要骂娘了,什么破Docker,连个卷管理接口都没有!以上是老版本中docker对卷的管理方法。接下来说一下新版本中docker对卷的管理。
** 一条华丽的分割线… **

新的数据卷管理

  • 卷创建
    docker volume create {options},创建卷,可指定卷名称和访问卷所使用的驱动。目前docker volume plugin支持的驱动包括:blockbridge、convoy、flocker、glusterfs、horcrux、ipfs、netshare、openstorage、quobyte
  • 卷查询
    docker volume ls,显示卷列表
    docker volume inspect {volume name},显示指定卷的详细信息
  • 卷删除
    docker rm {volume name},删除指定卷,若卷已经被容器所加载,无论容器是否出于运行状态,删除都会失败。

*** 很可惜docker新版本中还是不支持动态加载卸载数据卷 ***

Network

docker 有三种网络bridge、host、none。

  • bridge 桥接网络
  • host 复制宿主机网络
  • none 无网络,容器只有一个回环地址

网络管理

网络创建

bridge

可通过docker network create --subnet {CIDR} {network name}创建bridge网络

host

默认docker会提供一个host网络,用户不能再手动创建该网络Error response from daemon: only one instance of "host" network is allowed

none

该网络不可自创建

网络删除

可使用docker network rm {network name}删除指定网络

网络查询

使用docker network ls查看网络列表

1
2
3
4
5
6
$ docker network ls
ETWORK ID NAME DRIVER SCOPE
852c90cb4a48 bridge bridge local
bebda2efe6dc host host local
6a69c0cd935e my_net bridge local
09cf35b0a2fe none null local

使用docker network inspect {network name}查看指定网络信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ docker network inspect my_net
[
{
"Name": "my_net",
"Id": "6a69c0cd935ef315d143f1253634b8cce2b20e8e330ce791d53d26a6a08c387f",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.100.0/24",
"Gateway": "192.168.100.1"
}
]
},
"Internal": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.name": "my_net"
},
"Labels": {}
}
]

网络使用

with ‘–network’

docker create/run时,指定--network {network name}参数,默认网络使用bridge

1
$ docker run -it --name net_1 --network my_net my_ubuntu_03 /bin/bash

container复制

使用--network container:{容器名称/容器ID}将指定容器的网络及主机名复制到新容器内。

创建‘net_4’容器,并复制‘net_1’的network

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ docker run -it --name net_4 --network container:net_1 my_ubuntu_03 /bin/bash
root@5eb98cff1ec6:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:c0:a8:64:02
inet addr:192.168.100.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:c0ff:fea8:6402/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

容器‘net_1’的网卡信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ docker exec -it net_1 /bin/bash
root@5eb98cff1ec6:/# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:c0:a8:64:02
inet addr:192.168.100.2 Bcast:0.0.0.0 Mask:255.255.255.0
inet6 addr: fe80::42:c0ff:fea8:6402/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:16 errors:0 dropped:0 overruns:0 frame:0
TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1395 (1.3 KB) TX bytes:1284 (1.2 KB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:375 (375.0 B) TX bytes:375 (375.0 B)
  • 复制主机名
  • 复制MAC地址
  • 复制IP地址

Docker Remote API

开启Remote API

以RHEL7.2为例,开启Docker Remote API服务

  1. 修改systemd中的docker.server
    找到ExecStart项,增加-H tcp://0.0.0.0:2375允许任意客户端访问;增加-H unix:///var/run/docker.sock保证docker命令能正常使用。
    若需要使用HTTPS证书,可以增加--tls=true --tlscert=cert.pem --tlskey=key.pem详细请见
  2. 增加防火墙规则/关闭防火墙
    RHEL7.2中防火墙服务为firewalld
    eg: sudo systemctl stop firewalld
  3. 重启docker服务
    重载配置sudo systemctl daemon-reload
    重启服务sudo systemctl restart docker

API使用说明

详细请见:《Docker Remote API v1.24》

参考&鸣谢

Class

Python中也有类的概念,类中的成员函数不支持重载(overloading method),但支持重写(overiding method)。Python Class中还有很多隐含的成员函数,这些函数的首尾都是“__”开头结尾的。

隐藏的用法

构造与析构

new

创建对象时调用,返回当前对象的一个实例。

1
__new__(cls, *args, **kwargs)

init

对象建立后,第一个被调用的函数,相当于c++中的构造函数

1
__init__(self, *args, **kwargs)

del

对象销毁前,最后调用的函数,相当于c++中的析构函数

1
__del__(self, *args, **kwargs)

call

重写__call__方法后,对象当函数来使用,相当于重载了括号运算符

1
__call__(self, *args, **kwargs)

属性操作

getattr

获取属性

1
__getattr__(self, key)

setattr

创建或设置属性

1
__setattr__(self, key, value)

delattr

删除属性

1
__delattr__(self, key)

str

对象转换字符串函数

1
__str__(self)

repr

str()出来的是给人看的,repr()出来的是给Python看的,可以通过eval()重新变回一个Python对象。

1
__repr__(self)

参考&鸣谢

背景

在 *nix 环境下,若要对http server提供的RESTful接口进行测试,往往需要安装一些HTTP Client工具,然后在输入URL、参数、Method等,组成HTTP协议后发送测试。这种HTTP Client工具大都以浏览器插件形式提供。今天介绍一些curl使用方法,来替代HTTP Client。此处只是一个应用举例,关于curl更多操作请参考man手册

curl简介

curl命令是一个功能强大的网络工具,它能够通过http、ftp等方式下载文件,也能够上传文件。curl命令使用了libcurl库来实现,libcurl库常用在C程序中用来处理HTTP请求,curlpp是libcurl的一个C++封装,这几个东西可以用在抓取网页、网络监控等方面的开发,而curl命令可以帮助来解决开发过程中遇到的问题。

环境

Mac环境

  • OS : os x 10.11.6
  • curl : url 7.43.0 (x86_64-apple-darwin15.0) libcurl/7.43.0 SecureTransport zlib/1.2.5
  • openssl : OpenSSL 0.9.8zh 14 Jan 2016

Linux环境

  • OS : Red Hat Enterprise Linux Server release 7.2 (Maipo)
  • curl : curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.16.2.3 Basic ECC zlib/1.2.7 libidn/1.28 libssh2/1.4.3
  • openssl : OpenSSL 1.0.1e-fips 11 Feb 2013

Usage

HTTP请求命令格式

HTTP命令

** curl {URL}?{参数} -X {Http Method} -H “{Header信息}” -d “{body信息}” -v **

eg:

1
curl http://127.0.0.1:80/test?param=help -X PUT -H "Connection:keep-alive" -d "Hello world" -v

HTTPS请求命令格式

导入HTTPS需要的证书

*** 此处以pkcs12证书为例 ***

Mac

双击证书文件,按提示步骤导入证书文件

Linux

Linux下证书存在于/etc/pki/nssdb中,可使用certutil -d sql:/etc/pki/nssdb -L命令查询数据库中的证书,使用certutil -d sql:/etc/pki/nssdb -D -n <证书名>删除证书,使用certuil -d sql:/etc/pki/nssdb -A -t "C,," -n <证书名> -i <cer证书文件路径>添加cer证书,如果是p12证书其添加方法为p12util -d sql:/etc/pki/nssdb -i <p12证书文件>
本文中用到的证书正是p12证书,所以可用p12util去添加证书。

HTTPS命令

Mac

** curl {URL}?{参数} -k –cert {证书.p12}:{证书密码} -X {Http Method} -H “{Header信息}” -d “{body信息}” -v **
eg:

1
curl https://127.0.0.1:8787/test?param=help -k --cert cert.p12:pasword -X PUT -H "Connection:keep-alive" -d "Hello world" -v

Linux

** curl {URL}?{参数} -k -X {Http Method} -H “{Header信息}” -d “{body信息}” -v **
eg:

1
curl https://127.0.0.1:8787/test?param=help -k -X PUT -H "Connection:keep-alive" -d "Hello world" -v

参考&鸣谢

背景

  • XenServer7
  • Ceph Jewel
  • RBDSR

集成原理

rbdsr-xenserver7-integration

应用层客户端i/o通过XenServer将i/o传递给fuse或nbd内核模块,nbd通过文件socket,将i/o请求传递给rbd-nbd。rbd-nbd通过ceph-common(包括librbd和librados)将读写请求发送给Ceph集群。(fuse内部通信方式及协议目前不清楚,待后续调研清楚再更新)

安装配置步骤

依赖库安装

snappy leveldb gdisk gperftools-libs fuse fuse-libs安装

rpm列表:

  • snappy-1.1.0-3.el7.x86_64.rpm
  • leveldb-1.12.0-11.el7.x86_64.rpm
  • gdisk-0.8.6-5.el7.x86_64.rpm
  • gperftools-libs-2.4-5.el7.x86_64.rpm
  • fuse-2.9.2-6.el7.x86_64.rpm
  • fuse-libs-2.9.2-6.el7.x86_64.rpm

安装:

1
yum -y localinstall *.rpm

python-argparse 安装

python-argparse依赖rpm列表:

  • libunwind-1.1-5.el7.x86_64.rpm
  • python-backports-ssl_match_hostname-3.4.0.2-4.el7.noarch.rpm
  • python-backports-1.0-8.el7.x86_64.rpm
  • python-setuptools-0.9.8-4.el7.noarch.rpm

安装:

1
yum -y localinstall *.rpm

tar列表:
argparse-1.4.0.tar.gz
python-argparse安装:

1
2
3
tar -xzvf ./argparse-1.4.0.tar.gz
cd argparse-1.4.0
python setup.py install

ceph-common rbd-fuse rbd-nbd安装

rpm列表:

  • boost-iostreams-1.53.0-25.el7.x86_64.rpm
  • ceph-common-10.2.3-0.el7.x86_64.rpm
  • librados2-10.2.3-0.el7.x86_64.rpm
  • lttng-ust-2.4.1-1.el7.x86_64.rpm
  • python-rbd-10.2.3-0.el7.x86_64.rpm
  • rbd-fuse-10.2.3-0.el7.x86_64.rpm
  • rbd-nbd-10.2.3-0.el7.x86_64.rpm
  • python-requests-2.6.0-1.el7_1.noarch.rpm
  • python-cephfs-10.2.3-0.el7.x86_64.rpm
  • libradosstriper1-10.2.3-0.el7.x86_64.rpm
  • fcgi-2.4.0-25.el7.x86_64.rpm
  • boost-program-options-1.53.0-25.el7.x86_64.rpm
  • boost-random-1.53.0-25.el7.x86_64.rpm
  • libbabeltrace-1.2.4-3.el7.x86_64.rpm
  • librbd1-10.2.3-0.el7.x86_64.rpm
  • python-chardet-2.2.1-1.el7_1.noarch.rpm
  • python-six-1.9.0-2.el7.noarch.rpm
  • userspace-rcu-0.7.16-1.el7.x86_64.rpm
  • python-urllib3-1.10.2-2.el7_1.noarch.rpm
  • python-rados-10.2.3-0.el7.x86_64.rpm
  • librgw2-10.2.3-0.el7.x86_64.rpm
  • libcephfs1-10.2.3-0.el7.x86_64.rpm
  • boost-regex-1.53.0-25.el7.x86_64.rpm

安装:

1
yum -y localinstall *.rpm

RBDSR安装

获取RBDSR

可通过git获取或svn获取
Git事例:

1
git clone https://github.com/zhoubofsy/RBDSR-1.git

安装RBDSR

1
./install

Ceph配置

copy Ceph集群里的配置文件(/etc/ceph/ceph.conf)和 Keyring文件(/etc/ceph/ceph.client.admin.keyring)到XenServer节点的/etc/ceph/目录下
完成copy工作后,可通过ceph -s命令来确认ceph访问能力是否正常

重启XAPI

1
xe-toolstack-restart

主节点挂载

*** 注:在XenServer Master节点上需要按下述步骤挂载Ceph存储,其他非Master节点只需要执行45步 ***

1. 在ceph集群上创建链接XenServer需要的存储池

首先使用uuidgen生成uuid,然后创建存储池,存储池命名规则为“RBD_XenStorage-”前缀加uuid的方式。
eg:ceph osd pool create RBD_XenStorage-ffc44a2c-7de2-49e7-a621-8ecabdb357f4 128 128 replicated

2. 创建SR

eg:

1
# xe sr-introduce name-label="CEPH RBD Storage" type=rbd uuid=ffc44a2c-7de2-49e7-a621-8ecabdb357f4 shared=true content-type=user
  • name-label,可根据需要随意填写
  • uuid,为创建ceph存储池时使用的uuid

3. 获取host uuid

1
2
3
4
5
6
7
8
9
# xe host-list
uuid ( RO) : 267cb56e-983f-48fb-a50a-7bcb7bbbee85
name-label ( RW): xenserver-88
name-description ( RW): Default install


uuid ( RO) : 11e7e849-fd19-470e-9cb8-0c6c6781531f
name-label ( RW): xenserver90
name-description ( RW): Default install

取本机的uuid做为host uuid

4. 创建PBD

使用xe pbd-create创建PBD,默认创建方式为rbd-nbd方式,若想以rbd-fuse方式创建PBD,需要在rbd-mode参数中指定fuse。创建成功则返回PBD uuid
rbd-nbd eg:

1
2
# xe pbd-create sr-uuid=ffc44a2c-7de2-49e7-a621-8ecabdb357f4 host-uuid=11e7e849-fd19-470e-9cb8-0c6c6781531f
c51c8000-ad5f-190e-5a6c-dc12cc8f8733

rbd-fuse eg:

1
2
# xe pbd-create sr-uuid=ffc44a2c-7de2-49e7-a621-8ecabdb357f4 host-uuid=11e7e849-fd19-470e-9cb8-0c6c6781531f device-config:rbd-mode=fuse
c51c8000-ad5f-190e-5a6c-dc12cc8f8733

5. 挂载PBD

使用xe pbd-plug挂载PBD,需要指定PBD uuid。
eg:

1
# xe pbd-plug uuid=c51c8000-ad5f-190e-5a6c-dc12cc8f8733

参考&鸣谢

原理

rbd通过内核的NBD驱动映射成网络设备,用户可以通过读写nbd0…等网络设备,来实现对rbd设备的读写。

优点:

  • nbd设备成功将客户端和rbd隔离开,不再依赖以往的内核rbd驱动;
  • nbd与librbd的读写在应用层完成,可使用rbd cache提高性能;
  • rbd的数据保护,可通过ceph命令完成,不需要nbd支持。

缺点:

  • 要求系统必须支持nbd驱动;
  • 内核nbd与librbd通信,需要通过文件socket通信,增加数据拷贝,会影响性能;

架构

rbd-nbd_frame

  • 客户端直接读写nbd设备(同步)
  • 内核nbd驱动,将客户端的读写信息转化成nbd_request,并通过socket发送给NBDServer(rbd-nbd实现)
  • NBDServer是守护进程,一个快设备对应一个nbd设备,对应一个守护进程
  • NBDServer收到内核nbd驱动的nbd_reqeust后,向librbd发起同步读写请求
  • librbd 向 Ceph集群读写数据
  • NBDServer接收到librbd同步读写结果后,向内核nbd驱动发送reply
  • 内核nbd驱动收到reply,向客户端return

关键数据结构

Reqeust & Reply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct nbd_request {
u32 magic;
u32 type; /* == READ || == WRITE */
char handle[8];
u64 from;
u32 len;
}
#ifdef __GNUC__
__attribute__ ((packed))
#endif
;

struct nbd_reply {
u32 magic;
u32 error; /* 0 = ok, else error */
char handle[8]; /* handle you got from reqeust */
};

参考&鸣谢

搜索引擎

搜索引擎对于每一个码农来说都是一个互联网数据库,在这个数据库中有很多信息,我们在这个数据库中检索数据不需要指定数据库,也不需要数据表,只需要指定你需要检索的关键字即可。但这种搜索方式虽然搜索范围大,无漏网之鱼,可也搜到了很多于我们需要无关的内容。为了精确查找,筛选掉不需要的信息。搜索引擎还有如下用法,接下来,就让我们一探究竟吧。

特殊用法

由于天朝屏蔽Google,所以以下可在baidu搜索输入框中操作实现。

指定标题搜索

语法

1
intitle:"<网页title内容(标签上显示的内容)>"

举例

搜索title中含有“Bolog”的网页

1
intitle:"Bolog"

指定URL搜索

语法

1
inurl:<全部或部分URL信息>

举例

搜索url中包含nginx-1-11-6的网页

1
inurl:nginx-1-11-6

指定正文内容搜索

语法

1
intext:"<搜索关键字>"

此方法也是搜索引擎默认使用方法(猜的)

举例

搜索正文内容含有“python” 和“golang”关键字的网页

1
intext:"<python golang>"

指定网站(站点)搜索

语法

1
site:<网站域名> <搜索关键字>

举例

在oschina上搜索python关键字

1
site:oschina.net python

指定文件类型搜索

语法

1
filetype:<文件类型> <搜索关键字>

举例

搜索所有带有python关键字的PDF文档

1
filetype:pdf python

参考&鸣谢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# -*- coding: utf-8 -*-
import argparse
args = "-f hello.txt -n 1 2 3 -x 100 -y b -z a -q hello @args.txt i_am_bar -h".split()

# 使用@args.txt要求fromfile_prefix_chars="@"
# args.txt文件中应该一行一个参数,想改变行为参考convert_arg_line_to_args()
# ArgumentParser参数的简单说明
## description - 命令行帮助的开始文字,大部分情况下,我们只会用到这个参数
# epilog - 命令行帮助的结尾文字
# prog - (default: sys.argv[0])程序的名字,一般不需要修改,另外,如果你需要在help中使用到程序的名字,可以使用%(prog)s
# prefix_chars - 命令的前缀,默认是-,例如-f/--file。有些程序可能希望支持/f这样的选项,可以使用prefix_chars="/"
# fromfile_prefix_chars - (default: None)如果你希望命令行参数可以从文件中读取,就可能用到。例如,如果fromfile_prefix_chars='@',命令行参数中有一个为"@args.txt",args.txt的内容会作为命令行参数
# add_help - 是否增加-h/-help选项 (default: True),一般help信息都是必须的,所以不用设置啦。
## parents - 类型是list,如果这个parser的一些选项跟其他某些parser的选项一样,可以用parents来实现继承,例如parents=[parent_parser]
## formatter_class - 自定义帮助信息的格式(description和epilog)。默认情况下会将长的帮助信息进行<自动换行和消除多个连续空白>。
#三个允许的值:
# class argparse.RawDescriptionHelpFormatter 直接输出description和epilog的原始形式(不进行自动换行和消除空白的操作)
# class argparse.RawTextHelpFormatter 直接输出description和epilog以及add_argument中的help字符串的原始形式(不进行自动换行和消除空白的操作)
## class argparse.ArgumentDefaultsHelpFormatter 在每个选项的帮助信息后面输出他们对应的缺省值,如果有设置的话。这个最常用吧!
# argument_default - (default: None)设置一个全局的选项的缺省值,一般每个选项单独设置,所以这个参数用得少,不细说
# usage - (default: generated)如果你需要修改usage的信息(usage: PROG [-h] [--foo [FOO]] bar [bar ...]),那么可以修改这个,一般不要修改。
# conflict_handler - 不建议使用。这个在极端情况下才会用到,主要是定义两个add_argument中添加的选项的名字发生冲突时怎么处理,默认处理是抛出异常。
#注释一行有##表示这几个参数比较常用
parser = argparse.ArgumentParser(description="This is a description of %(prog)s", epilog="This is a epilog of %(prog)s", prefix_chars="-+", fromfile_prefix_chars="@", formatter_class=argparse.ArgumentDefaultsHelpFormatter)

# ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
# add_argument的参数是比较复杂的。。。
# name or flags - 指定参数的形式,想写几个写几个,不过我们一般就写两个,一个短参数,一个长参数,看下面的例子"-f", "--file"
# 可选的选项,位置不固定,想怎么写就怎么写,默认是可选的
parser.add_argument("-f", "--file", help="test test test")

# 位置固定的选项,例如"prog i_am_bar",这样子的话,i_am_bar就是bar选项的值啦,默认是必须有的
parser.add_argument("bar", help="test test test")

# nargs - 指定这个参数后面的value有多少个,例如,我们希望使用-n 1 2 3 4,来设置n的值为[1, 2, 3, 4]
parser.add_argument("-n", "--num", nargs="+", type=int)

# 这里nargs="+"表示,如果你指定了-n选项,那么-n后面至少要跟一个参数,+表示至少一个,?表示一个或0个,*0个或多个,
# default - 如果命令行没有出现这个选项,那么使用default指定的默认值
parser.add_argument("+g", "++gold", help="test test test", default="test_gold")#需要prefix_chars包含"+"

# type - 如果希望传进来的参数是指定的类型(例如 float, int or file等可以从字符串转化过来的类型),可以使用
parser.add_argument("-x", type=int)

# choices - 设置参数值的范围,如果choices中的类型不是字符串,记得指定type哦
parser.add_argument("-y", choices=['a', 'b', 'd'])

# required - 通常-f这样的选项是可选的,但是如果required=True那么就是必须的了
parser.add_argument("-z", choices=['a', 'b', 'd'], required=True)

# metavar - 参数的名字,在显示 帮助信息时才用到.
parser.add_argument("-o", metavar="OOOOOO")

# help - 设置这个选项的帮助信息
# dest - 设置这个选项的值就是解析出来后放到哪个属性中
parser.add_argument("-q", dest="world")

args = parser.parse_args(args) # 如果你没有args参数,那么就使用sys.argv,也就是命令行参数啦。有这个参数,就方便我们调试啊
# args.world就是-q的值啦
# action - The basic type of action to be taken when this argument is encountered at the command line.
# const - A constant value required by some action and nargs selections.
# 这两个自己看帮助文档啦,比较复杂
# http://docs.python.org/library/argparse.html
print args

背景

  • OS Version : rhel 6.4
  • MySQL Version : 5.6.31

改密权限

  • root可以修改所有用户密码
  • 所有用户在无任何权限情况下可修改自己密码
  • 获得“update所有库”权限的用户可修改任何用户密码(包括root)

(以上所诉,均使用set password方法)

改密三种方法

Set Password

set password for <用户名>@{localhost|%|...} =password('<密码>');

grant … identified by

grant <权限> on <数据库>.<数据表> to <user>@{localhost|%|...} identified by '<密码>';

update

update <库名>.<表名> set password=password('<密码>') where user='<用户名>' and host='{localhost | % | ...}';

vi命令

使用“xxd”或“od”工具转换十六进制
方法如下:

  • :%!xxd将当前文本转换为16进制格式

  • :%!xxd -c 12将当前文本转换为16进制格式,并每行显示12个字节

  • :%!xxd -r将当前文件转换回文本格式

  • 参考&鸣谢

    1. vi下以16进制查看二进制文件

背景

  • OS Version : rhel 6.4
  • MySQL Version : 5.6.31

权限

权限列表

Privilege Column Context
CREATE Create_priv databases, tables, or indexes
DROP Drop_priv database, tables, or views
GRANT OPTION Grant_priv database, tables, or stored routines
LOCK TABLES lock_tables_priv databases
REFERENCES References_priv databases or tables, columns
EVENT Event_priv databases
ALTER Alter_priv tables
DELETE Delete_priv tables
INDEX Index_priv tables
INSERT Insert_priv tables or columns
SELECT Select_priv tables or columns
UPDATE Update_priv tables or columns
CREATE TEMPORARY TABLES Create_tmp_table_priv tables
TRIGGER trigger_priv tables
CREATE VIEW Create_view_priv views
SHOW VIEW Show_view_priv views
ALTER ROUTINE alter_routine_priv stored routines
CREATE ROUTINE create_routine_priv stored routines
EXECUTE execute_priv stored routines
FILE file_priv file access on server host (Global)
CREATE TABLESPACE create_tablespace_priv server administration (Global)
CREATE USER create_user_priv server administration (Global)
PROCESS process_priv server administration (Global)
PROXY proxy_priv server administration (user to user)
RELOAD reload_priv server administration (Global)
REPLICATION CLIENT repl_client_priv server administration (Global)
REPLICATION SLAVE repl_slave_priv server administration (Global)
SHOW DATABASES show_db_priv server administration (Global)
SHUTDOWN shutdown_priv server administration (Global)
SUPER super_priv server administration (Global)
ALL [PRIVILEGES] server administration
USAGE server administration

按权限的种类分类

  • 数据访问相关权限
  • 库表结构相关权限
  • 服务相关权限

权限相关表单

MySQL权限信息存储在“mysql”数据中
其中:

  • “user”表负责存储用户信息,及用户本身所拥有的权限;
  • “db”表负责存储用户与db的权限关系;
  • “tables_priv”负责存在用户与table的权限关系;
  • “columns_priv”负责存储用户与column的权限关系;

user表结构

Field Type Null Key Default
Host char(60) NO PRI
User char(16) NO PRI
Password char(41) NO
Select_priv enum(‘N’,’Y’) NO N
Insert_priv enum(‘N’,’Y’) NO N
Update_priv enum(‘N’,’Y’) NO N
Delete_priv enum(‘N’,’Y’) NO N
Create_priv enum(‘N’,’Y’) NO N
Drop_priv enum(‘N’,’Y’) NO N
Reload_priv enum(‘N’,’Y’) NO N
Shutdown_priv enum(‘N’,’Y’) NO N
Process_priv enum(‘N’,’Y’) NO N
File_priv enum(‘N’,’Y’) NO N
Grant_priv enum(‘N’,’Y’) NO N
References_priv enum(‘N’,’Y’) NO N
Index_priv enum(‘N’,’Y’) NO N
Alter_priv enum(‘N’,’Y’) NO N
Show_db_priv enum(‘N’,’Y’) NO N
Super_priv enum(‘N’,’Y’) NO N
Create_tmp_table_priv enum(‘N’,’Y’) NO N
Lock_tables_priv enum(‘N’,’Y’) NO N
Execute_priv enum(‘N’,’Y’) NO N
Repl_slave_priv enum(‘N’,’Y’) NO N
Repl_client_priv enum(‘N’,’Y’) NO N
Create_view_priv enum(‘N’,’Y’) NO N
Show_view_priv enum(‘N’,’Y’) NO N
Create_routine_priv enum(‘N’,’Y’) NO N
Alter_routine_priv enum(‘N’,’Y’) NO N
Create_user_priv enum(‘N’,’Y’) NO N
Event_priv enum(‘N’,’Y’) NO N
Trigger_priv enum(‘N’,’Y’) NO N
Create_tablespace_priv enum(‘N’,’Y’) NO N
ssl_type enum(‘’,’ANY’,’X509’,’SPECIFIED’) NO
ssl_cipher blob NO NULL
x509_issuer blob NO NULL
x509_subject blob NO NULL
max_questions int(11) unsigned NO 0
max_updates int(11) unsigned NO 0
max_connections int(11) unsigned NO 0
max_user_connections int(11) unsigned NO 0
plugin char(64) YES mysql_native_password
authentication_string text YES NULL
password_expired enum(‘N’,’Y’) NO N

db表结构

Field Type Null Key Default
Host char(60) NO PRI
Db char(64) NO PRI
User char(16) NO PRI
Select_priv enum(‘N’,’Y’) NO N
Insert_priv enum(‘N’,’Y’) NO N
Update_priv enum(‘N’,’Y’) NO N
Delete_priv enum(‘N’,’Y’) NO N
Create_priv enum(‘N’,’Y’) NO N
Drop_priv enum(‘N’,’Y’) NO N
Grant_priv enum(‘N’,’Y’) NO N
References_priv enum(‘N’,’Y’) NO N
Index_priv enum(‘N’,’Y’) NO N
Alter_priv enum(‘N’,’Y’) NO N
Create_tmp_table_priv enum(‘N’,’Y’) NO N
Lock_tables_priv enum(‘N’,’Y’) NO N
Create_view_priv enum(‘N’,’Y’) NO N
Show_view_priv enum(‘N’,’Y’) NO N
Create_routine_priv enum(‘N’,’Y’) NO N
Alter_routine_priv enum(‘N’,’Y’) NO N
Execute_priv enum(‘N’,’Y’) NO N
Event_priv enum(‘N’,’Y’) NO N
Trigger_priv enum(‘N’,’Y’) NO N

tables_priv表结构

Field Type Null Key Default Extra
Host char(60) NO PRI
Db char(64) NO PRI
User char(16) NO PRI
Table_name char(64) NO PRI
Grantor char(77) NO MUL
Timestamp timestamp NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
Table_priv set(‘Select’,’Insert’,
‘Update’,’Delete’,
‘Create’,’Drop’,
‘Grant’,’References’,
‘Index’,’Alter’,
‘Create View’,
‘Show view’,’Trigger’)
NO
Column_priv set(‘Select’,’Insert’,
‘Update’,’References’)
NO

columns_priv表结构

Field Type Null Key Default Extra
Host char(60) NO PRI
Db char(64) NO PRI
User char(16) NO PRI
Table_name char(64) NO PRI
Column_name char(64) NO PRI
Timestamp timestamp NO CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP
Column_priv set(‘Select’,
‘Insert’,
‘Update’,
‘References’)
NO

验证流程

mysql_privilege_flow