HackToday Walk Blog


  • Home

  • Tags

  • Archives

  • Search

ChatterBot 智能机器人玩起来

Posted on 2017-07-23

机器学习作为一门技术已经被应用到很多场景中,从个性化推荐到智能数据商业分析等,举不胜举,今天我们看一个简单的小例子,智能会话机器人、

所需技术: gunicorn,nginx,mongodb,mysql

ChatterBot 是一个支持多种语言的机器人,通过基于历史会话进行机器学习,从而可以产生自动应答的效果。具体原理图如下:

官方已经有一个 django 的应用例子,不过默认是使用的 sqlite db
改动: 我们使用了 mongodb,然后 django 应用对应的配置了 mysql,使用gunicorn (HTTP server)和 nginx (proxy server),

具体如下:

  1. 下载 django_app

https://github.com/gunthercox/ChatterBot/tree/master/examples/django_app

  1. 配置 mysql db

配置 mysql:

1
2
3
sudo apt-get update
sudo apt-get install mysql-server
sudo mysql_secure_installation
1
2
3
4
5
6
7
CREATE DATABASE chattraindb CHARACTER SET UTF8;

CREATE USER aiuser@localhost IDENTIFIED BY 'password';

GRANT ALL PRIVILEGES ON chattraindb .* TO aiuser@localhost;

FLUSH PRIVILEGES;
1
2
3
sudo apt-get install python-mysqldb

python manage.py migrate
  1. 安装 mongdb (略,参考官方文档 4)
  2. 修改 chatterbot 配置
1
2
3
4
5
6
7
8
9
10
CHATTERBOT = {
'name': 'Django ChatterBot Example',
'trainer': 'chatterbot.trainers.ChatterBotCorpusTrainer',
'training_data': [
'chatterbot.corpus.english'
],
'storage_adapter': 'chatterbot.storage.MongoDatabaseAdapter',
'database': 'train-sample',
'django_app_name': 'django_chatterbot'
}
  1. 安装 gunicorn,nginx
1
2
sudo pip install gunicorn
sudo apt-get install nginx

然后进行systemd 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ cat /etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target

[Service]
PIDFile=/run/gunicorn/pid
User=kennan
Group=kennan
RuntimeDirectory=gunicorn
WorkingDirectory=/home/kennan/workRepo/ChatterBot/examples/django_app
ExecStart=/usr/local/bin/gunicorn --pid /run/gunicorn/pid \
--bind unix:/run/gunicorn/socket example_app.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

nginx 配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
    server {
listen 80;
server_name kennan-box;

location /static/ {
root /home/kennan/workRepo/ChatterBot/examples/django_app/example_app;
}

location / {
proxy_pass http://unix:/run/gunicorn/socket;
}
}
}

为了访问 80 端口,不会默认到 nginx 欢迎页面,需要删除默认配置

1
sudo rm -rf  /etc/nginx/sites-enabled/default
  1. nginx 生效,就能访问了, 效果如下:

Linuxkit 在 OpenStack Ocota 版本的实验

Posted on 2017-06-22

测试环境 CentOS 7.3

需要说明关于 Devstack 部分,不同的 OS 除了本身 Devstack 默认安装基本步骤一样,还有不同的额外步骤,有的不需要(比如下面的一些防火墙的规则,可能 Ubuntu 默认安装的就不需要)

说一下这个实验的思路,就是 Linuxkit 本身是可以 build VM 镜像的,而 OpenStack 本身又是一款包含有虚拟化管理功能的软件,那么我们希望试试 LinuxKit 自身build的镜像是不是可以很好的运行在 OpenStack 这个平台上。具体步骤如下:

  1. 搭建 OpenStack 环境
    方法1: 使用 Devstack
    优点,简单,快速,定位解决问题方便
    缺点,有些自定义的配置比较多,可以参考 Devstack 详细解释文档,一般不需要

方法2: 使用 RDO (因为是 CentOS 环境)
优点:基本不需要自定义话配置
缺点:使用 RDO 前置条件较多,除了配置源之外,还需要对防火墙等做一些处理。因为集成了 puppet, 所以不熟悉 puppet的话,出了问题,定位解决不方便。网上资料虽多,但是还是不如 DevStack

最初尝试了 RDO,试了几次均不成功,发现除了一些模块相关的问题(我拿到手的这台 CentOS 机器也是被做了一些自定义配置,有些不知名的问题,比如 ipv4 iptables 中 filter 规则不识别,ipv6 模块加载不正常等),还最会报错 sql connection 配置没有。

因为我们今天的重点不是研究怎么部署 OpenStack, 所以就没功夫调试 RDO 了,投入了 DevStack 的怀抱

DevStack 老方法,文档也介绍的很详细,不再累赘了,请参考文献【1】

说几个在 DevStack 中没有提到的,就是最新版的devstack 在 CentOS 安装后,需要开启对应的 80, 443 端口,要不然你在其他机器上无法访问 Horizon Dashboard, 具体就是参考文献【2】

/etc/sysconfig/iptables 加入下面的两条规则,然后重启 iptables 服务

1
2
-A INPUT -p tcp -m multiport --dports 443 -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80 -j ACCEPT
  1. 搭建完 DevStack 基本就完了,如果还有其他的需要的话(比如通过虚拟机ping 主机 IP),你可能在 tcpdump 发现有admin prohibited 日志,那么就需要参考文献【4】进行防火墙规则的更新。

  2. 部署 DevStack 后,简单的部署一个 Cirros 镜像,然后测试 private ip 连通性,分配一个 floating ip,测试联通性(假设你添加的securitygroups 中包含了对相应协议端口的开放,比如 ICMP,DNS 等)

  3. 下面开始导入 Linuxkit 镜像,这里以 sshd 镜像为例,具体怎么 Build, 在我的博客中文献【5】也做了介绍

  4. 上传 sshd qcow2 镜像 (当然可以使用 kernel+inittrd ramdisk 方式) 到 OpenStack Glance, 这里简化通过 dashboard 操作,不用命令行,如下图所示:

  1. 部署镜像,关联 float ip (上面的图中的ip 172.24.4.5)

  2. 验证测试效果, 如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
[root@mytestpc ~]# ssh 172.24.4.5
Welcome to LinuxKit
moby:~# whoami
root
moby:~# ls
moby:~# ps -ef | grep ssh
317 root 0:00 ctr run --runtime-config /containers/services/sshd/config.json --rootfs /containers/services/sshd/rootfs --id sshd
427 root 0:00 /sbin/tini /usr/bin/ssh.sh
524 root 0:00 /usr/sbin/sshd -D -e
548 root 0:00 sshd: root@pts/0
554 root 0:00 grep ssh
moby:~#
  1. 当然我们也可以测试 linuxkit 中 redis 镜像,如下

验证如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@mytestpc ~]# redis-cli  -h 172.24.4.3
172.24.4.3:6379> help
redis-cli 3.2.8
To get help about Redis commands type:
"help @" to get a list of commands in
"help " for help on
"help " to get a list of possible help topics
"quit" to exit

To set redis-cli perferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
172.24.4.3:6379>

参考:

  1. https://docs.openstack.org/developer/devstack/
  2. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux_OpenStack_Platform/2/html/Getting_Started_Guide/chap-Deploying_The_Dashboard.html
  3. http://linuxwiki.github.io/NetTools/tcpdump.html
  4. http://blog.chinaunix.net/uid-21335514-id-5403664.html
  5. http://blog.chinaunix.net/uid-21335514-id-5765203.html

Django Migration 的 Cannot add foreign key constraint 问题解决

Posted on 2017-06-14

最近在 Django 项目执行 Migration 的时候发现一个奇怪的报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
File "/usr/lib64/python2.7/site-packages/django/db/backends/mysql/base.py", line 124, in execute

return self.cursor.execute(query, args)

File "/usr/lib64/python2.7/site-packages/MySQLdb/cursors.py", line 205, in execute

self.errorhandler(self, exc, value)

File "/usr/lib64/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler

raise errorclass, errorvalue

django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')

在新数据库 CI Migration 测试中是没有发现这类问题的,后来 Google 发现有类似的问题和分析 [1],于是整理一下,以备其他人参考
这是因为老系统原来的表使用的是 MyISAM 引擎,但是现在 MySQL 新版本默认的表都是 InnoDB 了,而 MyISAM 是不支持外键约束的。
MyISAM 在 MySQL 5.5.1 之前是默认的引擎
InnoDB 在 MySQL 5.5 之后是默认的引擎

所以如果你的老的表是 MyISAM,而新表对此有外键引入, 那么自然会报上面的错误了。

解决方法也很简单:(修改旧表引擎为 InnoDB),具体如下:

1
ALTER TABLE   ENGINE = InnoDB;

如何查看表的信息:

  1. 查看所有表的信息
1
SHOW TABLE STATUS FROM `DB_NAME`;
  1. 查看某个表的信息
1
SHOW TABLE STATUS FROM `DB_NAME` LIKE 'TABLE_NAME';

参考资料:

  1. https://stackoverflow.com/questions/6178816/django-cannot-add-or-update-a-child-row-a-foreign-key-constraint-fails
  2. https://stackoverflow.com/questions/12614541/whats-the-difference-between-myisam-and-innodb
  3. https://stackoverflow.com/questions/4515490/how-do-i-know-if-a-mysql-table-is-using-myisam-or-innodb-engine
  4. https://dev.mysql.com/doc/refman/5.6/en/storage-engine-setting.html
  5. https://github.com/divio/django-filer/issues/939

Linuxkit 源码分析,从开始到镜像构建完成

Posted on 2017-06-08

在上一篇【1】中我们介绍了 “Linuxkit 中的 kernel+initrd 镜像启动过程”,那么我们接下来看看 Linuxkit 是如何一步一步构造出 kernel +initrd 这些镜像的。

首先看一下 Moby 结构体定义,基本和 yml 中支持的属性一一对应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
23 // Moby is the type of a Moby config file
24 type Moby struct {
25 Kernel struct {
26 Image string
27 Cmdline string
28 }
29 Init []string
30 Onboot []MobyImage
31 Services []MobyImage
32 Trust TrustConfig
33 Files []struct {
34 Path string
35 Directory bool
36 Symlink string
37 Contents string
38 }
39 Outputs []struct {
40 Format string
41 }
42 }
43

NewConfig(parse yml config 文件) –> buildInternal (实际的 build 过程) –> outputs (生成相应格式的镜像)

其中 buildInternal 的过程如下

1
--> dockerPull   --> ImageExtract  --> untarKernel

下载 Kernel 对应的 image,从对应的镜像中提取文件系统并返回一个 tar,从 tar 中提取出 kernel 、 kernel.tar 并放到新的 tar 文件中(initrdAppend 操作),tar 文件为了区分 kernel 和 其他文件,对 kernel 设置了 tar header 字段(boot/kernel boot/cmdline)

对于 Init 镜像都要解压,并且添加到上面新的tar 文件中(initrdAppend)

对于 Onboot 镜像,执行以下操作:
ConfigToOCI(image) , –> ImageBundle(对应目录为/containers/onboot/) –> 同样添加到文件中 (initrdAppend)

对于 service 镜像,执行以下操作:
ConfigToOCI(image) –》 ImageBundle(对应目录为 /containers/services/) –> 同样添加到文件中 (initrdAppend )

最后是添加一些额外的文件,程序需要的,比如 ssh key 文件(initrdAppend)

–> outputs
按照 yml 中的输出格式,输出对应的文件,这里以 kernel+initrd 举例
输出对应的 kernel + initrd 文件,其中 kernel 和 initrd 是在前面的 tar 包装的时候,都有设置了对应的 tar header,所以可以从一个文件中抽取出 kernel,剩下的就是 initrd 文件

对于其他虚拟机镜像格式,其实就是讲对应的 kernel + initrd 打包成对应的镜像格式比如 qcow2

那么对于上述构造的 VM 镜像,里面的容器如何自动运行起来的。那么我们就需要理解前面讲的 kernel +initrd 的启动过程,在 BIOS 自检后,bootloder 开始加载 kernel +initramfs, 那么我们从下面将这里如何对应到 moby 构建的镜像里面的代码

initrd 上面除了包含一些 modules, 还包含 init, onboot, services 镜像,其中 kernel+ initrd 配合完成对应的真正 root 挂载后,控制权交给了/sbin/init

init 进程,开始根据 /etc/inittab 中进行进程的派生,看卡 inittab 什么样子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/ # cat /etc/inittab
# /etc/inittab

::sysinit:/etc/init.d/rcS
::once:/etc/init.d/containerd
::once:/etc/init.d/containers

# Stuff to do for the 3-finger salute
::ctrlaltdel:/sbin/reboot

# Stuff to do before rebooting
::shutdown:/usr/sbin/killall5 -15
::shutdown:/bin/sleep 5
::shutdown:/usr/sbin/killall5 -9
::shutdown:/bin/echo "Unmounting filesystems"
::shutdown:/bin/umount -a -r
ttyS0::once:cat /etc/issue
ttyS0::respawn:/sbin/getty -n -l /bin/sh -L 115200 ttyS0 vt100
tty0::once:cat /etc/issue
tty0::respawn:/sbin/getty -n -l /bin/sh 38400 tty0

我们看到了熟悉的 /etc/init.d/containerd 和 /etc/init.d/containers,其中 containerd 是容器运行控制进程,首先启动。接着对于所有的containers 进行 roofs 的挂载,runc 调用运行这些容器,代码如下:

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
/ # cat /etc/init.d/containers
#!/bin/sh

# start onboot containers, run to completion

if [ -d /containers/onboot ]
then
for f in $(find /containers/onboot -mindepth 1 -maxdepth 1 | sort)
do
base="$(basename $f)"
/bin/mount --bind "$f/rootfs" "$f/rootfs"
mount -o remount,rw "$f/rootfs"
/usr/bin/runc run --bundle "$f" "$(basename $f)"
printf " - $base\n"
done
fi

# start service containers

if [ -d /containers/services ]
then
for f in $(find /containers/services -mindepth 1 -maxdepth 1 | sort)
do
base="$(basename $f)"
/bin/mount --bind "$f/rootfs" "$f/rootfs"
mount -o remount,rw "$f/rootfs"
log="/var/log/$base.log"
ctr run --runtime-config "$f/config.json" --rootfs "$f/rootfs" --id "$(basename $f)" $log >$log &
printf " - $base\n"
done
fi

wait

通过mount 查看里面的挂载情况:

1
2
3
4
5
6
7
8
9
10
tmpfs on /var type tmpfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /containers/onboot/000-sysctl/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/onboot/001-sysfs/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/onboot/002-binfmt/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/onboot/003-format/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/onboot/004-mount/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/services/dhcpcd/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/services/docker/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/services/ntpd/rootfs type tmpfs (rw,relatime)
tmpfs on /containers/services/rngd/rootfs type tmpfs (rw,relatime)

如此,就完成了 VM 启动后的容器的自动运行

参考:

  1. http://blog.chinaunix.net/uid-21335514-id-5765657.html
  2. https://en.wikipedia.org/wiki/Tar_(computing)

Linuxkit 中的 kernel+initrd 镜像启动过程

Posted on 2017-05-31

Linuxkit 中有一种镜像输出方式是 kernel+initird,以这类镜像为例,我们就来谈谈一个可运行的操作系统启动过程“发展史”:

  1. 开机,主板上电 CPU Reset,寄存器初始化,根据 CS、IP 寄存器(FFFF0h) 运行第一条指令地址,由于处于内存高位地址,所以一般是一个简单的跳转指令(JMP),找到对应的BIOS 程序

  2. 启动 BIOS 进行 POST 自检 (内存等硬件自检),然后 BIOS 会查找可引导的设备,找到后也就是对应的引导扇区 MBR,加载内存中,然后执行

引导扇区比较小,只有 512 字节,所以肯定无法完成后续的操作系统加载初始化的所有工作,所以这里就包含了一些关键信息:如何继续启动过程和装载 OS 的一些信息,也就是包含分区表,Boot Code(查看哪个分区是 Active)Boot code 执行后就会把控制权交给对应 Active 分区的 boot 部分

  1. 接下来就是 Bootloader(比如 GRUB) 部分,装载 kernel 和 initrd

initrd 就是 Ram Disk,可以被 kernel 解压使用,用来作为临时的 root 文件系统,直到真正的 root 文件系统被挂载。
initrd 主要包含了可以挂载真正 root 文件系统的程序和一 些必要的驱动

kernel 和 initrd 配合完成上面的,就开始将控制权交给 /sbin/init (对于 initramfs 则是 /init),/sbin/init 主要会加载所有对应的 service 和用户空间的工具(配置的内容在 /etc/inittab 文件中),挂载对应 /etc/fstab 下的分区

  1. 用户进入登录界面

特别说明,关于 initrd 和 initramfs 区别,在于
initrd 和 initramfs 都是作为根文件系统被挂载前的临时文件系统,被内核调用

区别是:(更详细参考文献 12)
initrd 是 linux kernel 2.6 前引入的, 是一个 gzip 压缩的文件系统类型的镜像,需要内核中相应的模块编译才能完成对应的加载(比如loop 设备)
initramfs 是 linux kernel 2.6 引入的,一个 gzip 压缩的 cpio 归档,是一个内存盘,不依赖于底层的文件系统

Image type Location of init Tool used to build the image
initramfs /init cpio -H newc -o
initrd /sbin/init mkcramfs, genext2fs (and others)

具体查看对应镜像中的内容如下:

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
initrd: 
# mkdir /tmp/initrd
# cp initrd.img /tmp/initrd
# gunzip < /tmp/initrd/initrd.img
# mkdir /mnt/initrd
# mount –ro loop /tmp/initrd/initrd /mnt/initrd
# cd /mnt/initrd


initramfs:
# gunzip -c /boot/initrd-2.6.31.img > /tmp/my_initrd
# cpio -it < /tmp/my_initrd [examine contents]
lib
lib/udev
lib/udev/console_init
lib/firmware
lib/firmware/radeon
lib/firmware/radeon/RV730_me.bin
... snip ...
lib/modules
lib/modules/2.6.31
lib/modules/2.6.31/radeon.ko
lib/modules/2.6.31/modules.isapnpmap
... and so on and so on ...
# cd [somewhere] [in preparation for unloading]
# cpio -i < /tmp/my_initrd [unload]

参考:

[1] http://flint.cs.yale.edu/feng/cos/resources/BIOS/
[2] https://www.bbsmax.com/A/pRdBnwg9dn/
[3] http://www.dewassoc.com/kbase/hard_drives/master_boot_record.htm
[4] https://www.pks.mpg.de/~mueller/docs/suse10.1/suselinux-manual_en/manual/cha.boot.html
[5] https://www.novell.com/documentation/suse91/suselinux-adminguide/html/ch12s03.html
[6] https://www.kernel.org/doc/html/v4.10/admin-guide/initrd.html
[7] https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Installation_Guide/ch-boot-init-shutdown.html
[8] https://en.wikipedia.org/wiki/Initrd
[9] https://en.wikipedia.org/wiki/Linux_startup_process
[10] http://www.thegeekstuff.com/2011/02/Linux-boot-process/
[11] http://www.aclevername.com/articles/linux-xilinx-tutorial/minimalist-initramfs.html
[12] https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt
[13] https://www.zhihu.com/question/22364502
[14] https://www.linux.com/learn/kernel-newbie-corner-initrd-and-initramfs-whats
[15] http://www.aclevername.com/articles/linux-xilinx-tutorial/minimalist-initramfs.html
[16] https://zh.wikipedia.org/wiki/Initrd
[17] https://ksearch.wordpress.com/2010/09/30/extract-contents-of-initrd/

一篇很好的 Linux EXT 文件系统入门介绍的文章

Posted on 2017-05-27

一个国外的技术专家写的文章,介绍了 EXT 文件系统演进的历史,以及文件系统的基础知识,绝对值得一读

https://opensource.com/article/17/5/introduction-ext4-filesystem

编译 QEMU 报错 configure.ac:14: error: possibly undefined macro: AC_PROG_LIBTOOL

Posted on 2017-05-25

在 CentOS 7.2 上编译最新的 QEMU 2.9.0 版本的时候,发现除了常规的

1
yum install gcc gcc-c++  zlib-devel glibc-devel automake autoconf

依赖包,还会报另外一个错误

1
2
3
configure.ac:14: error: possibly undefined macro: AC_PROG_LIBTOOL
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.

这个错误可以安装如下的包来解决:

1
yum install libtool

CNI 项目被接纳托管到 CNCF,推动云原生应用的网络模型演进

Posted on 2017-05-24

今天 CNCF 又迎来了一位重要网络项目成员——CNI,这也是放在 CNCF 托管的第10个项目

CNI 是一个关于容器网络接口标准的项目,由 CoreOS 发起,Redhat OpenShift, Apache Mesos, Cloud Foundry, Kubernetes, Kurma 和 rkt 公司创立。
CNI 定义了一套通用接口,接口面向网络插件和容器运行环境,CNI 定义的接口也是最小化,主要关注:容器的网络连通性和容器移除的时候的相关网络资源释放。

CNI 主要包含了三大组件 (参考下图)

  1. CNI Specification: 定义了容器运行时和网络插件之间的API,实现容器网络的建立和销毁
  2. Plugins:支持不同网络技术和方案的扩展性手段
  3. Library:提供了 CNI Specification 一种 Go 实现,容器运行时可以很容易的使用 CNI

当然 CNI 还很年轻,还需要根据容器领域的发展很好的进一步调整和适配,保证容器运行可以很便利稳定的消费 CNI, 为整个容器系统构建稳定网络环境

参考:

https://www.cncf.io/category/blog/

Web 开发值得注意的 12 个安全原则

Posted on 2017-05-23

下面的这篇文章值得读一下,结合云计算开发中一些特点,将相应的安全问题分类做了一些总结:

https://simplesecurity.sensedeep.com/web-developer-security-checklist-f2e4f43c9c56.

Linuxkit 快速 build VM 镜像

Posted on 2017-05-19

Linuxkit 是什么? 这个我原来这博文【1】中大概介绍过,今天再重新说一下,其实 Linuxkit 就是一个强大的工具集,这个工具集可以定制化基于容器的操作系统,这些镜像可以部署到现有的一些云平台上,因为本身支持很多的镜像格式 kernel+initrd,qcow2 等。

废话不多说,我们演示一下如何 build 一个镜像,拿 docker 为例

1> $ git clone https://github.com/linuxkit/linuxkit.git
2> $ cd linuxkit
运行 make 命令

一会就 build 完成对应的工具,包括 linuxkit,moby,rtf

linuxkit 命令主要用于和 cloud 或者本地 hypervisor 交互的: push 镜像,部署镜像
moby 用于 build VM 镜像的
rtf 社区开发中运行集成测试的

3> 使用上面的工具开始 build 镜像

$ cd examples
$ moby build docker
默认生成 kernel+initrd 镜像,还有对应的启动参数

1
2
3
-rw-r--r-- 1 root root 71622481 May 17 11:42 docker-initrd.img
-rw-r--r-- 1 root root 7541328 May 17 11:42 docker-kernel
-rw-r--r-- 1 root root 40 May 17 11:42 docker-cmdline

$ 运行 docker 镜像

1
$ linuxkit run docker

注意这里运行的时候,依赖一些可支持的平台,如下:

1
2
3
4
5
6
Supported backends are (default platform in brackets):
gcp
hyperkit [macOS]
qemu [linux]
vmware
packet

本文一台 CentOS 机器,装了相关的 QEMU 相关的软件,否则会出现不能运行,或者进入VM 后,出现乱码的状况

最后有如下的画面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[   12.764709] tsc: Refined TSC clocksource calibration: 2294.665 MHz
[ 12.764991] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2113854cd53, max_idle_ns: 440795215552 ns
[ 12.773755] Freeing unused kernel memory: 820K (ffff8ba191933000 - ffff8ba191a00000)
[ 12.823433] Freeing unused kernel memory: 1012K (ffff8ba191d03000 - ffff8ba191e00000)
[ 13.782833] clocksource: Switched to clocksource tsc

Welcome to LinuxKit

## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/


/ #

执行 runc list 查看

1
2
3
4
5
/ # runc list
ID PID STATUS BUNDLE CREATED OWNER
dhcpcd 607 running /run/containerd/linux/dhcpcd 2017-05-18T10:36:44.584310687Z root
docker 639 running /run/containerd/linux/docker 2017-05-18T10:36:47.003939228Z root
ntpd 668 running /run/containerd/linux/ntpd 2017-05-18T10:36:48.825102369Z root

进入 docker 容器,

1
2
3
4
/ # runc exec -t docker sh
/ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
/ #

这样一个 VM 中的容器中运行的 docker 进程就 OK 了,也很简单

当然了社区这个工具开发相对时间不长,所以有些调试或者使用易用性上还有很多要做的工作

参考文献:

  1. http://blog.chinaunix.net/uid-21335514-id-5763176.html
  2. https://github.com/linuxkit/linuxkit
1234…26

Kai Qiang Wu

This is a place for thinking and writing

253 posts
32 tags
GitHub
© 2020 Kai Qiang Wu
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4
Visitor Total Visit