0%


作者: 耗子007


最近被python的条件坑了一波,在此小计一下。
python的IF的条件判断和C是一致的,0表示False,非0表示True。这本没什么问题,坑爹的是,很多函数的成功返回0,而失败返回-1,这就很容易被坑了。
先看看0和-1的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

root@rtos:/home/work/rtos# python
Python 2.7.6 (default, Oct 26 2016, 20:30:19)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> if 0:
... print("0 is True")
... else:
... print("0 is False")
...
0 is False
>>> if -1:
... print("-1 is True")
... else:
... print("-1 is False")
...
-1 is True

字符串的find函数,在查找失败的时候返回-1,成功时返回匹配的起始下标。当匹配的起始下标是0和查找失败的时候,在if判断时候需要注意了。

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

>>> tmp = "abcdefg"
>>> a = "abc"
>>> b = "bcd"
>>> if tmp.find(a):
... print("%s find in %s" % (a, tmp))
... else:
... print("%s cannot find in %s" % (a, tmp))
...
abc cannot find in abcdefg

>>> if tmp.find(b):
... print("%s find in %s" % (b, tmp))
... else:
... print("%s cannot find in %s" % (b, tmp))
...
bcd find in abcdefg

>>> c = "234"
>>> if tmp.find(c):
... print("%s find in %s" % (c, tmp))
... else:
... print("%s cannot find in %s" % (c, tmp))
...
234 find in abcdefg


作者: 耗子007


搭建非安全Registry

Docker官方hub上面已提供容器化的Registry,可以通过docker run直接启动一个本地的Registry的服务。

1
2
docker run -d -p 5000:5000 \
--restart=always --name registry registry:2

上传镜像的方法:

1
2
3
docker pull ubuntu
docker tag ubuntu localhost:5000/ubuntu
docker push localhost:5000/ubuntu

可以通过数据卷的方式,把上传的docker镜像保存到指定的host目录:

1
2
3
docker run -d -p 5000:5000 --restart=always --name registry \
-v /data:/var/lib/registry \
registry:2

跨机器访问非安全Registry

跨机器访问非安全的Registry,需要对机器的Docker daemon的启动参数进行设置,设置方法取决于docker daemon的启动方式。
以Ubuntu为例:

  • 修改/etc/default/docker文件
  • 添加DOCKER_OPTS=”–insecure-registry myregistrydomain.com:5000”,以myregistrydomain.com为例,也可以是IP地址
  • 重启Docker daemon服务

搭建安全Registry

首先,需要对openssl的配置做一些修改:

  • Ubuntu配置文件: /etc/ssl/openssl.cnf
  • Redhat配置文件: /etc/pki/tls/openssl.cnf

注:在上面的配置文件的[ v3_ca ]标签下面加上subjectAltName=IP:192.168.1.181 <192.168.1.181为当期机器的IP>
参考文章:http://dockone.io/article/684

可以通过openssl生成自己的证书和密钥,用来验证。生成证书的方法:

1
2
3
mkdir -p /certs && openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt

关于openssl生成密钥的办法还有下面的:

1
2
3
4
5
6
7
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf
$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:

参考文档:https://docs.docker.com/engine/security/https/

生成账号密码:

1
2
mkdir auth 
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd

用生成的证书和密钥启动Registry的服务:

1
2
3
4
5
6
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/auth:/auth
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2

跨机器访问安全Registry

把Registry机器上生成的证书文件domain.crt拷贝到指定目录(取决于系统类型):

  • Ubuntu /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt
  • Redhat系统 /etc/pki/ca-trust/source/anchors/myregistrydomain.com:5000.crt,并更新证书update-ca-trust

然后重新启动Docker daemon的服务。
最后,可以push镜像了。

1
2
3
4
docker pull ubuntu
docker tag ubuntu myregistrydomain.com:5000/ubuntu
docker push myregistrydomain.com:5000/ubuntu
docker pull myregistrydomain.com:5000/ubuntu


作者: 耗子007


日志驱动

Driver Description
none Disables any logging for the container. docker logs won’t be available with this driver.
json-file Default logging driver for Docker. Writes JSON messages to file.
syslog Syslog logging driver for Docker. Writes log messages to syslog.
journald Journald logging driver for Docker. Writes log messages to journald.
gelf Graylog Extended Log Format logging driver for Docker. Writes log messages to a GELF endpoint like Graylog or Logstash.
fluentd Fluentd logging driver for Docker. Writes log messages to fluentd (forward input).
awslogs Amazon CloudWatch Logs logging driver for Docker. Writes log messages to Amazon CloudWatch Logs.
splunk Splunk logging driver for Docker. Writes log messages to splunk using HTTP Event Collector.
etwlogs ETW logging driver for Docker on Windows. Writes log messages as ETW events.
gcplogs Google Cloud Logging driver for Docker. Writes log messages to Google Cloud Logging.

在daemon启动的时候可以配置日志驱动,命令如下:

1
docker daemon --log-driver=json-file --log-opt=map[]

默认的驱动是json-file,可配置选项通过log-opt设置。
log-opt可选项如下:

1
2
3
4
--log-opt max-size=[0-9+][k|m|g]
--log-opt max-file=[0-9+]
--log-opt labels=label1,label2
--log-opt env=env1,env2

例如:
–log-opt max-size=2m限定日志文件的大小为2MB
–log-opt max-file=7限定日志文件最多7个
当日志文件超过2MB是,会写到第二个日志文件,如果日志文件超过7个时,会覆盖之前的日志文件。

容器日志

容器日志是容器在运行过程中产生的日志,默认会保存到/var/lib/docker/containers/CID/CID-json.log文件中。
可以用下面命令读取易读的日志:

1
$ docker logs CID

日志处理流程图如下:
日志流程图

syslog驱动设置容器日志到单个日志文件

syslog驱动时,默认容器的日志都是输出到/var/log/messages文件中的,当需要把容器日志单独保存时,可以通过一些小办法实现。
步骤如下:

  • 设置容器日志的facility为一个特定值保证其他应用不会使用,例如:local5
  • 配置一下rsyslog.cfg就好了,把local5的日志指定到一个文件中,例如:
1
local5.*						 /var/log/mydocker.log

Daemon挂掉时容器日志处理流程

当daemon挂掉时,容器的日志会缓存到上图的fifo中,fifo的默认大小是1M,可以通过如下命令获取:

1
$ cat /proc/sys/fs/pipe-max-size


作者: 耗子007


安装liteide

1
2
3
4
5
6
7
8
9
10
$ git clone https://github.com/visualfc/liteide.git
$ sudo apt-get update
$ sudo apt-get install qt4-dev-tools libqt4-dev libqt4-core libqt4-gui libqtwebkit-dev g++
$ cd liteide/build
$ ./update_pkg.sh
$ QTDIR=/usr ./build_linux.sh

## Run it: ##
$ cd ~/liteide/build/liteide/bin
$ ./liteide

安装golang

1
2
3
4
wget https://storage.googleapis.com/golang/go1.7.4.linux-amd64.tar.gz
tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
vi $HOME/.profile
> export PATH=$PATH:/usr/local/go/bin


作者: 耗子007


1. kiwi简介

1.1 kiwi是什么

kiwi用Perl编写的,用于制作linux镜像的命令行工具。支持制作多种格式的镜像:

  • ISO
  • Live CD/DVD
  • PXEBoot
  • Hard Disk
  • USB
  • Amazon EC2 (.ami)
  • Docker
  • Google Cloud Format (..gce)
  • KVM/Qemu (.qcow2)
  • Open Virtualization Format (.ovf, .ova)
  • Vagrant (.vagrant
  • VirtualBox (.vdi)
  • Virtual Hard Disk (.vhd)
  • VMware (.vmdk)
  • XEN

1.2 kiwi工作流

kiwi的工作流分为两个流程:

  1. 准备。创建root目录,用于保存新文件系统的内容;然后从软件源(可以是安装镜像或者在线的仓库)安装请求的软件包;然后创建镜像描述文件(config.xml);
    最后可选的自定义配置。该流程会输出一个“unpacked root tree”。
  2. 制作。kiwi会自动使用上个流程的输出制作镜像,此流程没有交互,但是可以通过修改image.sh脚本,实现在制作镜像过程中执行用户定义动作。

1.3 kiwi使用方法

准备流程:kiwi –prepare
制作流程:kiwi –create

2 kiwi的基本流程

kiwi制作镜像的流程是自动的,制作需要的必要信息主要来自config.xml的配置文件。此外,kiwi可以通过config.sh和images.sh实现可选的自定义功能。

2.1 制作镜像

kiwi制作镜像分为两步。第一步,prepare操作,使用config.xml配置文件生成“unpacked image tree”。第二步,create操作,基于第一步生成的
“unpacked image”和config.xml配置文件提供的信息创建一个“packed image”(就是镜像)。

制作镜像架构图

注:
(1) Unpacked Image
Encapsulated system reachable via chroot
(2) Packed Image
Encapsulated system reachable via kernel file system/extension drivers such as loopback mounts, etc.

2.1.1 Prepare操作

只有prepare操作成功,才能进行下一步的create操作。
prepare操作,kiwi会创建一个unpacked image(也就是root tree)。这个root tree是通过–root参数或者config.xml的defaultroot元素指定的。
该目录会在create操作中用于安装软件。软件管理工具是通过config.xml的packagemanager元素指定的,
kiwi目前支持的软件管理工具有:smart、zypper(默认选项)、yum和apt。
Prepare操作主要包括以下步骤:

  1. 创建目标root目录。如果目标root目录存在,kiwi会退出并报错。可以使用–force-new-root参数,强制创建,如果指定目录存在,kiwi会先删除,
    然后重新创建。
  2. 安装软件包。把配置文件的bootstrap部分指定的软件安装到root目录。filesystem和glibc-locale(euler没指定此包)包是构建引导环境
    必需的软件。这两个包的依赖链足以在引导环境中填充所有必需的软件,以支持将软件包安装到新root目录中。软件包管理可能安装了一些不需要的软件包,
    可以通过”package_to_be_deleted“来删除多余的软件包。
  3. 应用overlay目录。软件包安装完成后,KIWI将名为root的overlay目录中存在的所有文件和目录拷贝到目标root tree。
    已经存在于目标root tree中的文件将被覆盖,其他将被添加。 这允许您覆盖在安装阶段期间软件包安装的任何文件。
  4. 安装archives。在上一步完成之后,把config.xml的archive元素指定的任何archive(可以使任何文件,以tar包形式保存),解开到目标root tree。
    可能覆盖掉已有的文件。
  5. 运行用户定义的脚本config.sh。prepare操作的最后,执行config.sh脚本,运行在root tree的顶层。该脚本的主要功能是完成系统配置,例如启动一些服务。
    更详细使用可参考 config.sh
  6. 管理新的root tree。你可以通过chroot操作新的root tree,此文件系统与常用的区别在于多一个image目录,用于保存kiwi在create步骤需要用到的信息,
    例如,config.xml配置文件的副本。

2.1.2 Create操作

Prepare操作的成功时Create操作的前提。保证unpacked root tree是完整的和一致的。create操作会创建一个packed image。利用unpacked root tree能够
创建多种类型image,例如,OEM image或者虚拟机的images。
Create操作主要执行以下步骤:

  1. 运行用户自定义脚本images.sh。如果images.sh存在,首先在root tree的顶层执行此脚本。该脚本主要作用是删除最终镜像不需要的文件。
    更详细使用方法可参考 images.sh
  2. 创建请求类型镜像。创建config.xml的type元素指定的image类型,配置文件必须包含至少一个type元素。下图显示当前支持的镜像类型。
    支持镜像类型


作者: 耗子007


通过把hexo安装到docker容器中,然后在容器中启动hexo的服务。

构建hexo的docker镜像

基于node的docker镜像制作我们的hexo镜像,主要做了如下几件事:

  • 配置代理(内网需要)
  • 添加hexo工作目录
  • 安装全局hexo
  • 初始化hexo工作目录
  • 暴露hexo服务的端口
  • 在启动时,生成静态页面以及启动hexo服务

Dockerfile如下所示:


    FROM node
    MAINTAINER Haozi007

    ENV http_proxy http://name:password@proxy:8080
    ENV https_proxy http://name:password@proxy:8080
    # Create hexo work dir
    WORKDIR /blog
    RUN npm install -g hexo-cli
    RUN hexo init /blog
    EXPOSE 4000

    CMD hexo generate && hexo server

制作docker镜像


    docker build -t haozi/hexo .

启动hexo服务

可以通过docker的-v方法,把我们的markdown文档指定到容器中hexo的工作目录的source/_posts目录中,
这样当容器启动时,会自动生成对应的静态页面。
启动容器的命令如下:


    docker run --name hexo -itd -p 8088:4000 \
    -v /home/rtos/learning/workNotes/blogs:/blog/source/_posts \
    haozi/hexo

注:

  • -p把容器的4000端口映射到host的8088端口,这样访问host的8088端口,就可以访问我们的hexo网站了。
  • -v把markdown写的文档,映射到hexo的工作目录下的_posts目录,这样我们可以方便的更新文档

网站维护

可以把我们的所有markdown文档传到github或者其它内源保存。
每次更新文档的时候,有两种方法可以更新我们的hexo静态网站。

  • 只需要重启我们的hexo容器
  • 执行docker exec -it hexo /bin/bash进入容器,然后到/blog目录,执行hexo generate就可以了

前者需要重启容器,导致网站服务中断,后者比较麻烦,但是网站服务不好中断。