<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Bai &#187; virtualbox</title>
	<atom:link href="http://tonybai.com/tag/virtualbox/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Thu, 30 Apr 2026 23:46:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>使用nomad在weave网络中部署工作负载</title>
		<link>https://tonybai.com/2019/04/20/deploy-workload-in-weave-network-using-nomad/</link>
		<comments>https://tonybai.com/2019/04/20/deploy-workload-in-weave-network-using-nomad/#comments</comments>
		<pubDate>Sat, 20 Apr 2019 04:15:56 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[CIDR]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[consul]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[driver]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hashicorp]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[iproute]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[k8s]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[NAT]]></category>
		<category><![CDATA[nomad]]></category>
		<category><![CDATA[openssh-server]]></category>
		<category><![CDATA[overlay]]></category>
		<category><![CDATA[overlaynetwork]]></category>
		<category><![CDATA[pod]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[route]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[subnet]]></category>
		<category><![CDATA[task]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[weave]]></category>
		<category><![CDATA[子网]]></category>
		<category><![CDATA[容器]]></category>
		<category><![CDATA[微服务]]></category>
		<category><![CDATA[虚拟机]]></category>
		<category><![CDATA[路由]]></category>
		<category><![CDATA[镜像]]></category>
		<category><![CDATA[集群]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2707</guid>
		<description><![CDATA[当初Kubernetes网络的设计目标是使得开发者使用pod时在网络这一层面可以像使用传统物理主机或虚拟机一样。具体的基本要求如下： 所有pod间均应可以在无需NAT的情况下直接通信； 所有集群节点与所有集群的Pod之间均应可以在无需NAT的情况下直接通信； 容器自身的地址和其他pod看到的它的地址是同一个地址； 按照这样的要求，集群中的每个pod都在一个平坦的、共享网络命名空间中，并且每个Pod都拥有一个IP，通信时无需端口映射。 用户也需要额外考虑如何建立Pod之间的连接，也不需要考虑将容器端口映射到主机端口等问题。基于这些要求而实现的k8s pod网络模型，将具有向后兼容的特性，可以使得Pod从某些角度上可以被看成是一个传统的物理主机或vm来对待。 在《使用nomad实现集群管理和微服务部署调度》一文中，我们看到nomad部署调度的driver为docker的服务实例都是通过主机和容器间的端口映射来对外提供服务的。服务实例多的时候，大量服务端口出现在眼前，我们很难用端口判断这是什么服务。并且通过映射端口暴露服务有局限，对于那些需要映射到主机固定端口的服务来说，很可能存在与其他服务的端口冲突而导致部署失败。除此之外，这种端口映射的方式还缺少隔离的作用，所有实例暴露的端口在同一个全局网络空间。 nomad是否可以像k8s一样将服务实例部署到overlay网络中从而实现每个服务实例所在container可以被看成一个独立的vm；并且我们还可以通过划分overlay的网段来隔离，实现某种意义上的“多租户”呢？在本篇文章中，我们来试验一下上述想法是否可行。 一、搭建试验环境 我们这次在一个VirtualBox搭建的三节点环境中进行验证。如果小伙伴对这段很熟悉，或者有现成的环境可用，那么可以跳过这一小节。另外这节不是重点，我不会对这个过程用过多文字做解释。 1. 创建虚机，组建网络 我们在一台ubuntu 18.04 desktop版本主机上搭建环境，所使用的软件版本信息如下： VirtualBox: 5.2.18 Guest OS: Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-142-generic x86_64) 组件环境的虚拟机和网络拓扑示意图如下： 如上图所示：三个vm 通过连入host-only网络(vboxnet0)实现内网通；通过连入NAT网络（NatNetwork）实现外网通。（怪异：在windows上的virtualbox实际上通过natnetwork即可实现全通的，无需host-only network，但是在ubuntu下居然不行）。 每个vm中网络配置如下： # cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see [...]]]></description>
			<content:encoded><![CDATA[<p>当初<a href="https://tonybai.com/tag/kubernetes">Kubernetes</a>网络的设计目标是<strong>使得开发者使用pod时在网络这一层面可以像使用传统物理主机或虚拟机一样</strong>。具体的基本要求如下：</p>
<ul>
<li>所有pod间均应可以在无需NAT的情况下直接通信；</li>
<li>所有集群节点与所有集群的Pod之间均应可以在无需NAT的情况下直接通信；</li>
<li>容器自身的地址和其他pod看到的它的地址是同一个地址；</li>
</ul>
<p>按照这样的要求，集群中的每个pod都在一个平坦的、共享网络命名空间中，并且每个Pod都拥有一个IP，通信时无需端口映射。 用户也需要额外考虑如何建立Pod之间的连接，也不需要考虑将容器端口映射到主机端口等问题。基于这些要求而实现的k8s pod网络模型，将具有向后兼容的特性，可以使得Pod从某些角度上可以被看成是一个传统的物理主机或vm来对待。</p>
<p>在<a href="https://tonybai.com/2019/03/30/cluster-management-and-microservice-deployment-and-scheduled-by-nomad/">《使用nomad实现集群管理和微服务部署调度》</a>一文中，我们看到nomad部署调度的driver为docker的服务实例都是通过主机和容器间的端口映射来对外提供服务的。服务实例多的时候，大量服务端口出现在眼前，我们很难用端口判断这是什么服务。并且通过映射端口暴露服务有局限，对于那些需要映射到主机固定端口的服务来说，很可能存在与其他服务的端口冲突而导致部署失败。除此之外，这种端口映射的方式还缺少隔离的作用，所有实例暴露的端口在同一个全局网络空间。</p>
<p>nomad是否可以像k8s一样将服务实例部署到overlay网络中从而实现每个服务实例所在container可以被看成一个独立的vm；并且我们还可以通过划分overlay的网段来隔离，实现某种意义上的“多租户”呢？在本篇文章中，我们来试验一下上述想法是否可行。</p>
<h2>一、搭建试验环境</h2>
<p>我们这次在一个<a href="https://www.virtualbox.org/">VirtualBox</a>搭建的三节点环境中进行验证。<strong>如果小伙伴对这段很熟悉，或者有现成的环境可用，那么可以跳过这一小节</strong>。另外这节不是重点，我不会对这个过程用过多文字做解释。</p>
<h3>1. 创建虚机，组建网络</h3>
<p>我们在一台<a href="https://tonybai.com/tag/ubuntu">ubuntu</a> 18.04 desktop版本主机上搭建环境，所使用的软件版本信息如下：</p>
<ul>
<li>
<p>VirtualBox: 5.2.18</p>
</li>
<li>
<p>Guest OS: Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-142-generic x86_64)</p>
</li>
</ul>
<p>组件环境的虚拟机和网络拓扑示意图如下：</p>
<p><img src="https://tonybai.com/wp-content/uploads/virtualbox-3-vm-environment-for-nomad.png" alt="img{512x368}" /></p>
<p>如上图所示：三个vm 通过连入host-only网络(vboxnet0)实现内网通；通过连入NAT网络（NatNetwork）实现外网通。（怪异：在windows上的virtualbox实际上通过natnetwork即可实现全通的，无需host-only network，但是在ubuntu下居然不行）。</p>
<p>每个vm中网络配置如下：</p>
<pre><code># cat /etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto enp0s3
iface enp0s3 inet dhcp

auto enp0s8
iface enp0s8 inet dhcp

</code></pre>
<p>保存后，执行/etc/init.d/networking restart生效。</p>
<p>另外每个vm上安装了openssh-server(apt install openssh-server)并设置root可登陆。三个vm的主机名分为为u1、u2和u3（可通过hostnamectl &#8211;static set-hostname u1设置。并在/etc/hosts中添加主机名和内网IP的对应关系）。</p>
<p>每台主机上安装了docker引擎(通过apt install docker.io安装），docker版本信息如下：</p>
<pre><code># docker version
Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        6247962
 Built:             Tue Feb 26 23:56:24 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       6247962
  Built:            Tue Feb 12 22:47:29 2019
  OS/Arch:          linux/amd64
  Experimental:     false

</code></pre>
<h2>二、使用weave创建跨节点的overlay network</h2>
<p>我们选择<a href="https://www.weave.works/">weave</a>作为overlay network的实现。</p>
<h3>1. 安装weave</h3>
<p>我们在每个vm节点上安装目前最新版本的weave，以一个节点为例：</p>
<pre><code># curl -L git.io/weave -o /usr/local/bin/weave
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--:--     0
100   595    0   595    0     0     62      0 --:--:--  0:00:09 --:--:--   137
100 52227  100 52227    0     0   4106      0  0:00:12  0:00:12 --:--:-- 21187

# chmod a+x /usr/local/bin/weave

# weave version
weave script 2.5.1

... ...

</code></pre>
<p>通过weave setup预先将weave相关的容器Image下载到各个节点，为后面的weave launch所使用。</p>
<pre><code># weave setup

2.5.1: Pulling from weaveworks/weave
... ...
c458f7a37ca6: Pull complete
Digest: sha256:a170dd93fa7e678cc37919ffd65601d1015da6c3f10878534ac237381ea0db19
Status: Downloaded newer image for weaveworks/weave:2.5.1
2.5.1: Pulling from weaveworks/weaveexec
... ...
c11f30d06b58: Pull complete
Digest: sha256:ad53aaabf648548ec26cceac3ab49394778322e1623f0d184a2b74ad06338087
Status: Downloaded newer image for weaveworks/weaveexec:2.5.1
latest: Pulling from weaveworks/weavedb
9b0681f946a1: Pull complete
Digest: sha256:c280cf4e7208f4ca0d2514539e0f476dd12db70beacdc368793b7736de023d8d
Status: Downloaded newer image for weaveworks/weavedb:latest

</code></pre>
<h3>2. 启动跨多节点(peer) weave network</h3>
<p>weave的一个优点是建立跨节点overlay network时并不需要一个外部的存储(比如etcd），位于多个节点上的weave进程会自动同步相关信息。而且weave支持动态向weave overlay network中添加节点。</p>
<p>我们来初始化这个由三个vm节点构成的weave overlay network：</p>
<pre><code>root@u1:~# weave launch --no-dns 192.168.56.4 192.168.56.5
78f459a4a8acc07d46c1f86a15a519b91978c809876452b9d9c1294e760394a9

root@u2:~# weave launch --no-dns 192.168.56.3 192.168.56.5
1f379e50f3917e05bd133589f75594d7b2da20a680bb1e5e7172e37a18abe3ff

root@u3:~# weave launch --no-dns 192.168.56.3 192.168.56.4
aa600bfad8db8711e2cbc5f8e127022460ca3738226dd7aa33bb5b9b049f8cee

</code></pre>
<p>执行完上面命令后，在任意一个vm节点上执行下面命令，查看节点weave之间的连接状态：</p>
<pre><code>root@u1:~# weave status connections
&lt;- 192.168.56.4:54715    established fastdp 8e:d8:ad:a8:32:eb(u2) mtu=1376
&lt;- 192.168.56.5:51504    established fastdp f6:58:43:5c:68:d7(u3) mtu=1376

</code></pre>
<p>我们看到u1节点已经和u2、u3节点成功建立了连接，weave的工作模式是fastdp(fast data path)，mtu为默认的1376（<a href="https://tonybai.com/2019/04/18/benchmark-result-of-k8s-network-plugin-cni/">适当调节weave mtu可以提升weave overlay network的网络性能</a>）。<br />
我们也可以通过weave status命令查看一下weave网络的整体状态：</p>
<pre><code># weave status

        Version: 2.5.1 (up to date; next check at 2019/04/18 12:35:41)

        Service: router
       Protocol: weave 1..2
           Name: f6:58:43:5c:68:d7(u3)
     Encryption: disabled
  PeerDiscovery: enabled
        Targets: 3
    Connections: 3 (2 established, 1 failed)
          Peers: 3 (with 6 established connections)
 TrustedSubnets: none

        Service: ipam
         Status: ready
          Range: 10.32.0.0/12
  DefaultSubnet: 10.32.0.0/12

        Service: dns
         Domain: weave.local.
       Upstream: 10.0.3.3
            TTL: 1
        Entries: 0

        Service: proxy
        Address: unix:///var/run/weave/weave.sock

        Service: plugin (legacy)
     DriverName: weave

</code></pre>
<h3>3. 在weave overlay network中创建container并测试overlay网内container的互通性</h3>
<p>我们通过为docker指定net driver为weave的方式让docker在weave overlay network中创建container：</p>
<pre><code>root@u1:~# docker run -ti --net=weave busybox /bin/sh

root@u2:~# docker run -ti --net=weave busybox /bin/sh

root@u3:~# docker run -ti --net=weave busybox /bin/sh

</code></pre>
<p>我们在u1上启动的容器内去ping位于其他两个vm上启动的新容器：</p>
<pre><code>/ # ping -c 3 10.32.0.1
PING 10.32.0.1 (10.32.0.1): 56 data bytes
64 bytes from 10.32.0.1: seq=0 ttl=64 time=1.540 ms
64 bytes from 10.32.0.1: seq=1 ttl=64 time=1.548 ms
64 bytes from 10.32.0.1: seq=2 ttl=64 time=1.434 ms

--- 10.32.0.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.434/1.507/1.548 ms

/ # ping -c 3 10.46.0.0
PING 10.46.0.0 (10.46.0.0): 56 data bytes
64 bytes from 10.46.0.0: seq=0 ttl=64 time=5.118 ms
64 bytes from 10.46.0.0: seq=1 ttl=64 time=1.608 ms
64 bytes from 10.46.0.0: seq=2 ttl=64 time=1.837 ms

--- 10.46.0.0 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.608/2.854/5.118 ms

</code></pre>
<p>我们看到位于weave overlay network中的三个容器是连通的。</p>
<h3>4. 测试host到weave overlay网络中容器的连通性</h3>
<p>考虑到后续host上的<a href="https://tonybai.com/2018/09/10/setup-service-discovery-and-load-balance-based-on-consul/">consul</a>会对部署在weave overlay network中的container中的服务做health check，因此需要在host上能连通位于overlay network中的container。</p>
<p>我们来测试一下：</p>
<pre><code>root@u1:~# docker run -ti --net=weave busybox /bin/sh

/ # ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
29: ethwe0@if30: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1376 qdisc noqueue
    link/ether aa:8f:45:8f:5f:d6 brd ff:ff:ff:ff:ff:ff
    inet 10.40.0.0/12 brd 10.47.255.255 scope global ethwe0
       valid_lft forever preferred_lft forever
31: eth0@if32: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1500 qdisc noqueue
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

root@u1:~# ping 10.40.0.0
PING 10.40.0.0 (10.40.0.0) 56(84) bytes of data.

^C
--- 10.40.0.0 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3024ms

</code></pre>
<p>从测试结果来看，在host无法ping通位于weave network上的container。这个问题实则也显而易见，因为当前host上的路由表中没有以weave网络range: 10.32.0.0/12为目的地址的路由，并且weave网络设备也并未启用ip地址：</p>
<pre><code>root@u1:~# ip route
default via 10.0.3.2 dev enp0s8
10.0.3.0/24 dev enp0s8  proto kernel  scope link  src 10.0.3.15
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
172.18.0.0/16 dev docker_gwbridge  proto kernel  scope link  src 172.18.0.1
192.168.56.0/24 dev enp0s3  proto kernel  scope link  src 192.168.56.3

</code></pre>
<p>关于这个问题，weave官方给出了<a href="https://www.weave.works/docs/net/latest/tasks/manage/host-network-integration/">答案</a>：我们可以通过weave expose命令自动为主机上的weave设备分配ip地址，添加到10.32.0.0/12的路由。</p>
<pre><code>root@u1:~# weave expose
10.40.0.1

root@u1:~# ip a

.... ...

7: weave: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1376 qdisc noqueue state UP group default qlen 1000
    link/ether b2:97:b5:7b:0f:a9 brd ff:ff:ff:ff:ff:ff
    inet 10.40.0.1/12 brd 10.47.255.255 scope global weave
       valid_lft forever preferred_lft forever
    inet6 fe80::b097:b5ff:fe7b:fa9/64 scope link
       valid_lft forever preferred_lft forever

.... ...

root@u1:~# ip route
default via 10.0.3.2 dev enp0s8
10.0.3.0/24 dev enp0s8  proto kernel  scope link  src 10.0.3.15
10.32.0.0/12 dev weave  proto kernel  scope link  src 10.40.0.1
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
172.18.0.0/16 dev docker_gwbridge  proto kernel  scope link  src 172.18.0.1
192.168.56.0/24 dev enp0s3  proto kernel  scope link  src 192.168.56.3

</code></pre>
<p>我们看到在u1节点上执行完expose之后，weave设备拥有了自己的ip地址，并且主机路由表中也增加了10.32.0.0/12网络的路由。我们再来测试一下u1上主机到container是否通了：</p>
<pre><code>root@u1:~# ping 10.40.0.0
PING 10.40.0.0 (10.40.0.0) 56(84) bytes of data.
64 bytes from 10.40.0.0: icmp_seq=1 ttl=64 time=4.42 ms

64 bytes from 10.40.0.0: icmp_seq=2 ttl=64 time=1.04 ms
64 bytes from 10.40.0.0: icmp_seq=3 ttl=64 time=1.21 ms
^C
--- 10.40.0.0 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.048/2.228/4.425/1.554 ms

</code></pre>
<p>网络已经打通。我们继续在u2、u3两个节点上执行weave expose，这样三台主机都可以通过网络reach到位于任何一台主机上的、weave network中的container。</p>
<p>而从container到host，原本就可以访问，以u1上的container为例：</p>
<pre><code>/ # ping 192.168.56.3
PING 192.168.56.3 (192.168.56.3): 56 data bytes
64 bytes from 192.168.56.3: seq=0 ttl=64 time=0.345 ms
^C
--- 192.168.56.3 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.345/0.345/0.345 ms

/ # ping 192.168.56.4
PING 192.168.56.4 (192.168.56.4): 56 data bytes
64 bytes from 192.168.56.4: seq=0 ttl=63 time=1.277 ms
^C
--- 192.168.56.4 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.277/1.277/1.277 ms

</code></pre>
<h2>三、安装consul和nomad集群</h2>
<p>在<a href="https://tonybai.com/2019/03/30/cluster-management-and-microservice-deployment-and-scheduled-by-nomad/">《使用nomad实现集群管理和微服务部署调度》</a>一文中，我们已经详细说过consul和nomad的安装配置过程，这里仅列出步骤，不再详细说明。已经有环境的朋友可以略过该步骤！</p>
<h3>1. 安装consul</h3>
<p>在每个节点上执行下面步骤安装：</p>
<pre><code># wget -c https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
# unzip consul_1.4.4_linux_amd64.zip
# mv consul /usr/local/bin

# mkdir -p ~/consul-install/consul-data

</code></pre>
<p>启动consul集群：</p>
<pre><code>u1:

# nohup consul agent -server -ui -dns-port=53 -bootstrap-expect=3 -data-dir=/root/consul-install/consul-data -node=consul-1 -client=0.0.0.0 -bind=192.168.56.3 -datacenter=dc1 &gt; consul-1.log &amp; 2&gt;&amp;1

u2:

# nohup consul agent -server -ui -dns-port=53 -bootstrap-expect=3 -data-dir=/root/consul-install/consul-data -node=consul-2 -client=0.0.0.0 -bind=192.168.56.4 -datacenter=dc1 -join 192.168.56.3 &gt; consul-2.log &amp; 2&gt;&amp;1

u3:

nohup consul agent -server -ui -dns-port=53  -bootstrap-expect=3 -data-dir=/root/consul-install/consul-data -node=consul-3 -client=0.0.0.0 -bind=192.168.56.5 -datacenter=dc1 -join 192.168.56.3 &gt; consul-3.log &amp; 2&gt;&amp;1
</code></pre>
<p>查看启动状态：</p>
<pre><code>#  consul operator raft list-peers
Node      ID                                    Address            State     Voter  RaftProtocol
consul-1  db838e7c-2b02-949b-763b-a6646ee51981  192.168.56.3:8300  leader    true   3
consul-2  33c81139-5054-7e76-f320-7d28d7528cc8  192.168.56.4:8300  follower  true   3
consul-3  4eda7d24-3fe2-45f5-f4ad-b95fa39f13c1  192.168.56.5:8300  follower  true   3

</code></pre>
<p>如果输出类似上面的日志，则说明consul集群启动成功！</p>
<p>接下来为了利用consul内嵌的DNS server，我们修改一下各个node的DNS配置 /etc/resolvconf/resolv.conf.d/base：</p>
<pre><code>//  /etc/resolvconf/resolv.conf.d/base

nameserver 192.168.56.3
nameserver 192.168.56.4

options timeout:2 attempts:3 rotate single-request-reopen

# /etc/init.d/resolvconf restart

[ ok ] Restarting resolvconf (via systemctl): resolvconf.service.
</code></pre>
<h3>2. 安装nomad并启动nomad集群</h3>
<p>下面是在每个node上安装nomad的步骤：</p>
<pre><code># wget -c https://releases.hashicorp.com/nomad/0.8.7/nomad_0.8.7_linux_amd64.zip

# mkdir nomad-install

# unzip nomad_0.8.7_linux_amd64.zip

# mv nomad /usr/local/bin

# nomad version
Nomad v0.8.7 (21a2d93eecf018ad2209a5eab6aae6c359267933+CHANGES)

</code></pre>
<p>在每个node上创建agent.hcl文件，放到nomad-install下面：</p>
<pre><code>// agent.hcl

data_dir = "/root/nomad-install/nomad.d"

bind_addr = "192.168.56.3" //node 内网ip，这里以u1 host为例

server {
  enabled = true
  bootstrap_expect = 3
}

client {
  enabled = true
}

</code></pre>
<p>启动集群(基于consul)：</p>
<pre><code>u1:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-1.log &amp; 2&gt;&amp;1

u2:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-2.log &amp; 2&gt;&amp;1

u3:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-3.log &amp; 2&gt;&amp;1

</code></pre>
<p>查看nomad集群状态：</p>
<pre><code># nomad server members -address="http://192.168.56.3:4646"
Name       Address       Port  Status  Leader  Protocol  Build  Datacenter  Region
u1.global  192.168.56.3  4648  alive   false   2         0.8.7  dc1         global
u2.global  192.168.56.4  4648  alive   true    2         0.8.7  dc1         global
u3.global  192.168.56.5  4648  alive   false   2         0.8.7  dc1         global

# nomad operator raft list-peers -address="http://192.168.56.3:4646"
Node       ID                 Address            State     Voter  RaftProtocol
u3.global  192.168.56.5:4647  192.168.56.5:4647  follower  true   2
u2.global  192.168.56.4:4647  192.168.56.4:4647  leader    true   2
u1.global  192.168.56.3:4647  192.168.56.3:4647  follower  true   2

</code></pre>
<p>nomad集群启动成功！</p>
<h2>四. nomad实现在weave overlay network中的job部署</h2>
<h3>1. 创建位于weave overlay network中的nomad task service实例</h3>
<p>我们定义如下nomad job的配置文件：</p>
<pre><code>//httpbackend.nomad

job "httpbackend" {
  datacenters = ["dc1"]
  type = "service"

  group "httpbackend" {
    count = 3

    task "httpbackend" {
      driver = "docker"
      config {
        image = "bigwhite/httpbackendservice:v1.0.0"
        dns_servers =  ["192.168.56.3", "192.168.56.4", "192.168.56.5"]
        network_mode = "weave"
        logging {
          type = "json-file"
        }
      }

      resources {
        network {
          mbits = 10
        }
      }

      service {
        name = "httpbackend"
      }
    }
  }
}

</code></pre>
<p>与之前文章中job的配置文件不同的是，该job配置在task的config中增加了：</p>
<ul>
<li>
<p>dns_servers：由于docker 18.09在-net=weave下，container没有继承host的/etc/resolv.conf文件，我们为了能在container中通过服务的domain查询到其真实ip地址，我们在docker的执行参数中加入dns_servers，我们将u1,u2,u3都作为dns server提供了。</p>
</li>
<li>
<p>network_node：我们希望nomad调度负载、创建docker容器时将docker container创建在weave network中，因此我们在network_node中传入”weave”，这就相当于在执行docker时执行：docker run &#8230; &#8211;net=weave &#8230; &#8230;</p>
</li>
</ul>
<p>我们来创建一下该job：</p>
<pre><code># nomad job run -address=http://192.168.56.3:4646 httpbackend.nomad

==&gt; Monitoring evaluation "806eaecf"
    Evaluation triggered by job "httpbackend"
    Allocation "6e06be74" created: node "11212ed9", group "httpbackend"
    Allocation "e7ed8569" created: node "aa5a06fe", group "httpbackend"
    Allocation "fd6c6a05" created: node "fe7a7e9c", group "httpbackend"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "806eaecf" finished with status "complete"

# nomad job status -address=http://192.168.56.3:4646  httpbackend
ID            = httpbackend
Name          = httpbackend
Submit Date   = 2019-04-19T13:18:21+08:00
Type          = service
Priority      = 50
Datacenters   = dc1
Status        = running
Periodic      = false
Parameterized = false

Summary
Task Group   Queued  Starting  Running  Failed  Complete  Lost
httpbackend  0       0         3        0       0         0

Allocations
ID        Node ID   Task Group   Version  Desired  Status   Created  Modified
6e06be74  11212ed9  httpbackend  0        run      running  54s ago  7s ago
e7ed8569  aa5a06fe  httpbackend  0        run      running  54s ago  6s ago
fd6c6a05  fe7a7e9c  httpbackend  0        run      running  54s ago  12s ago

</code></pre>
<p>我们查看一下u1节点上的httpbackend负载的状态和ip：</p>
<pre><code>root@u1:~/nomad-install/jobs# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
2e2229cf8f64        c196c122feea             "/root/httpbackendse…"   49 seconds ago      Up 48 seconds                           httpbackend-e7ed8569-fdde-537b-91b3-84583d1ea238
912ac43350f7        weaveworks/weave:2.5.1   "/home/weave/weaver …"   22 hours ago        Up 22 hours                             weave

root@u1:~/nomad-install/jobs# docker exec 2e2229cf8f64 ip a
... ...
49: ethwe0@if50: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1376 qdisc noqueue
    link/ether a2:f1:ef:d7:89:ee brd ff:ff:ff:ff:ff:ff
    inet 10.40.0.0/12 brd 10.47.255.255 scope global ethwe0
       valid_lft forever preferred_lft forever
.... ...

</code></pre>
<p>我们看到新创建的container的ip为10.40.0.0，是weave network subnet range中的一个地址。</p>
<p>我们访问一下该服务：</p>
<pre><code># curl http://10.40.0.0:8081
this is httpbackendservice, version: v1.0.0

</code></pre>
<p>我们看到了预期返回的结果。通过consul的域名访问也同样ok：</p>
<pre><code># curl httpbackend.service.dc1.consul:8081
this is httpbackendservice, version: v1.0.0

</code></pre>
<p>我们从一个位于weave network中的container中去访问httpbackend服务，依然会得到正确的应答结果：</p>
<pre><code># docker run -ti --net=weave --dns=192.168.56.3 --dns=8.8.8.8 ubuntu /bin/bash

root@3fe76a39b66f:/# curl httpbackend.service.dc1.consul:8081
this is httpbackendservice, version: v1.0.0

</code></pre>
<h2>五、 应用隔离</h2>
<p>有些时候我们需要将部署的应用之间做隔离，让彼此无法互相访问。weave overlay network是支持这样做的，我们一起来看一下。</p>
<h3>1.重建weave网络</h3>
<p>我们首先需要重新创建weave网络，使之能支持划分不同subnet。</p>
<p>先在每个node上执行下面命令，将原有的weave网络清理干净：</p>
<pre><code># weave reset

</code></pre>
<p>执行后，发现weave网络设备、weave相关容器、路由表中有关weave的路由都不见了。</p>
<p>我们重新建立三节点的weave网络，在这个10.32.0.0/16的大网中，我们划分若干subnet，默认的subnet为10.32.0.0/24。</p>
<pre><code>u1:

# weave launch --no-dns --ipalloc-range 10.32.0.0/16 --ipalloc-default-subnet 10.32.0.0/24 192.168.56.4 192.168.56.5

# weave expose

u2:

# weave launch --no-dns --ipalloc-range 10.32.0.0/16 --ipalloc-default-subnet 10.32.0.0/24 192.168.56.3 192.168.56.5

# weave expose

u3:

# weave launch --no-dns --ipalloc-range 10.32.0.0/16 --ipalloc-default-subnet 10.32.0.0/24 192.168.56.3 192.168.56.4

# weave expose

</code></pre>
<p>接下来我们在不同的subnet下分别建立两个container：</p>
<p>首先在u1上，在default subnet下建立两个container a1和a2：</p>
<pre><code>#docker run -ti --net=weave --dns=192.168.56.3 --dns=8.8.8.8 --name a1 busybox /bin/sh

#docker run -ti --net=weave --dns=192.168.56.3 --dns=8.8.8.8 --name a2 busybox /bin/sh

</code></pre>
<p>再在u2上在subnet 10.32.1.0/24下建立两个container：b1和b2</p>
<pre><code>u2上：

# docker run -ti --net=weave --dns=192.168.56.3 --dns=8.8.8.8 -e WEAVE_CIDR=net:10.32.1.0/24 --name b1 busybox /bin/sh

# docker run -ti --net=weave --dns=192.168.56.3 --dns=8.8.8.8 -e WEAVE_CIDR=net:10.32.1.0/24 --name b2 busybox /bin/sh

</code></pre>
<p>我们经过测试发现：a1与a2、a1与b1都是可以ping通的，这与我们的预期a1与b1、b2不通不符。我们发现b1(10.32.0.2)、b2(10.32.0.3)两个容器的ip地址居然依然在default subnet内，似乎通过环境变量WEAVE_CIDR传递的subnet信息没有生效。<br />
在weave的一个<a href="https://github.com/weaveworks/weave/issues/2420">issue</a>中，有开发者提到：WEAVE_CIDR仅用于weave proxy模式，在weave作为plugin模式工作时，docker不会将该环境变量信息传递给weave。也就是说即便上面在u2上创建b1、b2时设置了环境变量WEAVE_CIDR，weave插件也无法得到该信息，于是依旧在默认subnet范围为b1、b2分配了ip。</p>
<h3>2. 让docker使用weave proxy模式</h3>
<p>weave proxy是位于docker client与docker engine(docker daemon)之间的代理服务：</p>
<pre><code>docker client --&gt; weave proxy ---&gt; docker engine/daemon

</code></pre>
<p>默认情况下，/var/run/docker.sock是docker client和docker engine之间的通信“媒介”，Docker daemon默认监听的Unix域套接字(Unix domain socket)：/var/run/docker.sock，docker client以及容器中的进程可以通过它与Docker daemon进行通信。</p>
<p>我们可通过docker -H xxx.sock或通过设置 DOCKER_HOST环境变量的方式让docker client与传入的unix socket通信。这样我们就可以将weave proxy的套接字unix:///var/run/weave/weave.sock（通过weave env查看到）传给docker client了。我们来测试一下：</p>
<pre><code>u1:

# docker -H unix:///var/run/weave/weave.sock run -ti --dns=192.168.56.3 --dns=8.8.8.8 --name a1 busybox /bin/sh

# docker -H unix:///var/run/weave/weave.sock run -ti --dns=192.168.56.3 --dns=8.8.8.8 --name a2 busybox /bin/sh

u2:

# docker -H unix:///var/run/weave/weave.sock  run -ti --dns=192.168.56.3 --dns=8.8.8.8 -e WEAVE_CIDR=net:10.32.1.0/24 --name b1 busybox /bin/sh

#docker -H unix:///var/run/weave/weave.sock run -ti --dns=192.168.56.3 --dns=8.8.8.8 -e WEAVE_CIDR=net:10.32.1.0/24 --name b2 busybox /bin/sh

</code></pre>
<p>四个container启动后，我们发现b1、b2的ip地址都在WEAVE_CIDR指定的空间内，a1、a2间互通；b1、b2间互通，但a1、a2与b1、b2间是不通的。这样就与预期相符了。</p>
<h3>3. nomad与weave proxy模式集成实现应用工作负载的隔离</h3>
<p>接下来，我们来看看如何将nomad和weave的proxy模式集成在一起，实现工作负载分配在不同subnet。</p>
<p>这里我们就无法仅仅通过在job配置文件中传入参数的方式来实现了，我们需要修改一下agent.hcl并重启nomad集群。以u1节点上的agent.hcl为例，我们需要改为下面这样：</p>
<pre><code>data_dir = "/root/nomad-install/nomad.d"

bind_addr = "192.168.56.5"

server {
  enabled = true
  bootstrap_expect = 3
}

client {
  enabled = true
  "options":{
     "docker.endpoint":"unix://var/run/weave/weave.sock"
  }
}

</code></pre>
<p>我们在client配置block中增加一个options，设置了docker.endpoint为weave proxy监听的weave.sock。重启集群：</p>
<pre><code>u1:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-1.log &amp; 2&gt;&amp;1

u2:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-2.log &amp; 2&gt;&amp;1

u3:

# nohup nomad agent -config=/root/nomad-install/agent.hcl  &gt; nomad-3.log &amp; 2&gt;&amp;1

</code></pre>
<p>接下来，我们重建一个httpbackend-another-subnet.nomad，内容如下：</p>
<pre><code>//httpbackend-another-subnet.nomad

job "httpbackend" {
  datacenters = ["dc1"]
  type = "service"

  group "httpbackend" {
    count = 3

    task "httpbackend" {
      driver = "docker"
      config {
        image = "bigwhite/httpbackendservice:v1.0.0"
        dns_servers =  ["192.168.56.3", "192.168.56.4", "192.168.56.5"]
        logging {
          type = "json-file"
        }
      }

      env {
        WEAVE_CIDR="net:10.32.1.0/24"
      }

      resources {
        network {
          mbits = 10
        }
      }

      service {
        name = "httpbackend"
      }
    }
  }
}

</code></pre>
<p>我们去掉了network_mode = “weave”，增加了一个env：WEAVE_CIDR=”net:10.32.1.0/24&#8243;。run这个job：</p>
<pre><code># nomad job run -address=http://192.168.56.3:4646 httpbackend-another-subnet.nomad
==&gt; Monitoring evaluation "e94bdd00"
    Evaluation triggered by job "httpbackend"
    Allocation "3f5032b5" created: node "11212ed9", group "httpbackend"
    Allocation "40d75ae8" created: node "aa5a06fe", group "httpbackend"
    Allocation "627fe1e7" created: node "fe7a7e9c", group "httpbackend"
    Evaluation status changed: "pending" -&gt; "complete"
==&gt; Evaluation "e94bdd00" finished with status "complete"

# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
700bbea7c89e        c196c122feea             "/w/w /root/httpback…"   17 seconds ago      Up 16 seconds                           httpbackend-40d75ae8-fe75-c560-b87b-c1272db4850c
8b7e29522b8b        weaveworks/weave:2.5.1   "/home/weave/weaver …"   10 hours ago        Up 10 hours                             weave
root@u1:~/nomad-install/jobs# docker exec 700bbea7c89e ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
142: eth0@if143: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1500 qdisc noqueue
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
144: ethwe@if145: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1376 qdisc noqueue
    link/ether f2:55:9d:26:72:56 brd ff:ff:ff:ff:ff:ff
    inet 10.32.1.192/24 brd 10.32.1.255 scope global ethwe
       valid_lft forever preferred_lft forever

</code></pre>
<p>我们看到新创建的httpbackend container的ip已经分配到10.32.1.0/24 subnet下面了。这种方式使得我们可以任意安排我们的job放入哪个subnet。</p>
<h3>4. 遗留问题</h3>
<p>我们通过consul go api试图从consul中获取service: httpbackend的ip信息，我们得到了如下的输出：</p>
<pre><code>#  ./services
10.0.3.15 : 0
10.0.3.15 : 0
10.0.3.15 : 0
[]

</code></pre>
<p>如果在httpbackend的service配置中使用如下配置：</p>
<pre><code> service {
        name = "httpbackend"
        address_mode = "driver"
      }

</code></pre>
<p>那么，我们得到的是下面结果：</p>
<pre><code># ./services
172.17.0.3 : 0
172.17.0.2 : 0
172.17.0.2 : 0
[]

</code></pre>
<p>也就是说nomad在consul中记录的container的advertise ip不是我们想要的weave subnet网段的ip信息，这样就会导致我们通过consul的DNS服务或者通过consul api获取的服务ip信息有误，导致无法通过这两种方式访问到服务实例。在nomad的最新版v0.9.0中该问题依然存在。</p>
<p>综上，“隔离”的目的得到了部分满足，期待后续nomad的改进。</p>
<h2>六、参考资料</h2>
<ul>
<li>
<p>https://www.weave.works/docs/net/latest/install/installing-weave/</p>
</li>
<li>
<p>https://www.weave.works/docs/net/latest/install/using-weave/#peer-connections</p>
</li>
<li>
<p>https://www.weave.works/docs/net/latest/install/plugin/plugin/#launching</p>
</li>
<li>
<p>https://www.weave.works/docs/net/latest/tasks/manage/host-network-integration/</p>
</li>
<li>
<p>https://docs.docker.com/v17.09/engine/userguide/networking/configure-dns/</p>
</li>
<li>
<p>https://www.nomadproject.io/docs/drivers/docker.html#client-requirements</p>
</li>
<li>
<p>https://www.weave.works/docs/net/latest/tasks/manage/application-isolation/</p>
</li>
<li>
<p>https://www.weave.works/docs/net/latest/tasks/weave-docker-api/weave-docker-api/</p>
</li>
<li>
<p>https://www.nomadproject.io/docs/drivers/docker.html</p>
</li>
<li>
<p>https://www.nomadproject.io/docs/configuration/client.html</p>
</li>
<li>
<p>https://www.nomadproject.io/docs/job-specification/service.html#using-driver-address-mode</p>
</li>
<li>
<p>https://success.docker.com/article/networking</p>
</li>
</ul>
<p>本文涉及到的配置文件和源码，参见<a href="https://github.com/bigwhite/experiments/tree/master/nomad-demo/part3">这里</a>。</p>
<hr />
<p>我的网课“<a href="https://coding.imooc.com/class/284.html">Kubernetes实战：高可用集群搭建、配置、运维与应用</a>”在慕课网上线了，感谢小伙伴们学习支持！</p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2019, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2019/04/20/deploy-workload-in-weave-network-using-nomad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用core-vagrant方式安装CoreOS</title>
		<link>https://tonybai.com/2015/07/20/install-coreos-by-coreos-vagrant/</link>
		<comments>https://tonybai.com/2015/07/20/install-coreos-by-coreos-vagrant/#comments</comments>
		<pubDate>Mon, 20 Jul 2015 11:34:24 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[amazonec2]]></category>
		<category><![CDATA[atomic]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[coreos]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[DigitalOcean]]></category>
		<category><![CDATA[distributedsystem]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[etcd]]></category>
		<category><![CDATA[etcd2]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[GCE]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[iso]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PXE]]></category>
		<category><![CDATA[Redhat]]></category>
		<category><![CDATA[snappy]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[vagrant]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[分布式系统]]></category>
		<category><![CDATA[然并卵]]></category>
		<category><![CDATA[集群]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1768</guid>
		<description><![CDATA[CoreOS是一种专门为运行类docker容器而生的linux发行版。与其他通用linux发行版（ubuntu、debian、redhat)相 比，它具有体型最小，消耗最小，支持滚动更新等特点。除此之外CoreOS内置的分布式系统服务组件也给开发者和运维者组建分布式集群、部署分布式服务应 用带来了极大便利。 CoreOS与知名容器Docker脚前脚后诞生，到目前为止已经较为成熟，国外主流云平台提供商如Amazon EC2、Google Compute Engine、Microsoft Azure、Digtial Ocean等均提供了CoreOS image，通过这些服务，你可以一键建立一个CoreOS实例，这似乎也是CoreOS官方推荐的主流install方式（最Easy）。 CoreOS当然支持其他方式的安装，比如支持虚拟机安装(vagrant+virtualbox)、PXE(preboot execute environment)安装以及iso install to 物理disk方式。如果仅仅是做一些实验，虚拟机安装是最简单也是最安全的方式。不过由于CoreOS的官方下载站在大陆无法直接访问（大陆程序员们好悲 催啊），因此这一最简单的虚拟机安装CoreOS的过程也就不那么简单了。 通过core-vagrant安装的直接结果是CoreOS被安装到一个VirtualBox虚拟机中，之后我们利用Vagrant命令来进行 CoreOS虚拟机的启停。CoreOS以及Vagrant都在持续演进，尤其是CoreOS目前在active dev中，版本号变化很快，这也是CoreOS滚动升级的必然结果。因此在安装操作演示前，我们有必要明确一下这个安装过程使用的软件版本： &#160;&#160;&#160; 物理机OS: &#160;&#160;&#160; &#160;&#160;&#160; Ubuntu 12.04 3.8.0-42-generic x86_64 &#160;&#160;&#160; VirtualBox: &#160;&#160;&#160; &#160;&#160;&#160; Oracle VM VirtualBox Manager 4.2.10 &#160;&#160;&#160; Vagrant: &#160;&#160;&#160; &#160;&#160;&#160; Vagrant 1.7.3 &#160;&#160;&#160; CoreOS: &#160;&#160;&#160; &#160;&#160;&#160; stable 717.3.0 &#160;&#160;&#160; coreos-vagrant source: &#160;&#160;&#160; &#160;&#160;&#160; commit [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://coreos.com">CoreOS</a>是一种专门为运行类<a href="http://tonybai.com/tag/docker">docker</a>容器而生的linux发行版。与其他通用linux发行版（<a href="http://tonybai.com/tag/ubuntu">ubuntu</a>、<a href="http://www.debian.org">debian</a>、<a href="http://www.redhat.com">redhat</a>)相 比，它具有体型最小，消耗最小，支持滚动更新等特点。除此之外CoreOS内置的分布式系统服务组件也给开发者和运维者组建分布式集群、部署分布式服务应 用带来了极大便利。</p>
<p>CoreOS与知名容器<a href="http://docker.com">Docker</a>脚前脚后诞生，到目前为止已经较为成熟，国外主流云平台提供商如<a href="http://aws.amazon.com/ec2">Amazon EC2</a>、<a href="https://cloud.google.com/compute">Google Compute Engine</a>、<a href="http://azure.microsoft.com">Microsoft Azure</a>、<a href="https://www.digitalocean.com/?refcode=bff6eed92687">Digtial Ocean</a>等均提供了CoreOS image，通过这些服务，你可以一键建立一个CoreOS实例，这似乎也是CoreOS官方推荐的主流install方式（最Easy）。</p>
<p>CoreOS当然支持其他方式的安装，比如支持虚拟机安装(<a href="https://www.vagrantup.com">vagrant</a>+<a href="https://virtualbox.org">virtualbox</a>)、PXE(preboot execute environment)安装以及iso install to 物理disk方式。如果仅仅是做一些实验，虚拟机安装是最简单也是最安全的方式。不过由于CoreOS的官方下载站在大陆无法直接访问（大陆程序员们好悲 催啊），因此这一最简单的虚拟机安装CoreOS的过程也就不那么简单了。</p>
<p>通过core-vagrant安装的直接结果是CoreOS被安装到一个VirtualBox虚拟机中，之后我们利用Vagrant命令来进行 CoreOS虚拟机的启停。CoreOS以及Vagrant都在持续演进，尤其是CoreOS目前在active dev中，版本号变化很快，这也是CoreOS滚动升级的必然结果。因此在安装操作演示前，我们有必要明确一下这个安装过程使用的软件版本：</p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; 物理机OS:<br />
	&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Ubuntu 12.04 3.8.0-42-generic x86_64<br />
	&nbsp;&nbsp;&nbsp; VirtualBox:<br />
	&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Oracle VM VirtualBox Manager 4.2.10<br />
	&nbsp;&nbsp;&nbsp; Vagrant:<br />
	&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Vagrant 1.7.3</font><br />
	<font face="Courier New">&nbsp;&nbsp;&nbsp; CoreOS:<br />
	&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stable 717.3.0</font><br />
	<font face="Courier New">&nbsp;&nbsp;&nbsp; coreos-vagrant source:<br />
	&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; commit b9ed7e2182ff08b72419ab3e89f4a5652bc75082</font></p>
<p><b>一、原理</b></p>
<p>如果没有Wall，CoreOS的coreos-vagrant安装将非常简单：</p>
<p><font face="Courier New">1、git clone https://github.com/coreos/coreos-vagrant<br />
	2、编辑配置文件<br />
	3、vagrant up<br />
	4、vagrant ssh</font></p>
<p>但是现在有了Wall，步骤3：vagrant up会报错：无法连接到http://stable.release.core-os.net/amd64-usr/717.3.0/xx这个url，导致安装失败。</p>
<p>我大致分析了一下vagrant up的执行过程：</p>
<p><font face="Courier New">1、设置配置默认值</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; $num_instances = 1<br />
	&nbsp;&nbsp;&nbsp; $instance_name_prefix = &quot;core&quot;<br />
	&nbsp;&nbsp;&nbsp; $update_channel = &quot;alpha&quot;<br />
	&nbsp;&nbsp;&nbsp; $image_version = &quot;current&quot;<br />
	&nbsp;&nbsp;&nbsp; $enable_serial_logging = false<br />
	&nbsp;&nbsp;&nbsp; $share_home = false<br />
	&nbsp;&nbsp;&nbsp; $vm_gui = false<br />
	&nbsp;&nbsp;&nbsp; $vm_memory = 1024<br />
	&nbsp;&nbsp;&nbsp; $vm_cpus = 1<br />
	&nbsp;&nbsp;&nbsp; $shared_folders = {}<br />
	&nbsp;&nbsp;&nbsp; $forwarded_ports = {}</font></p>
<p>2、判断是否存在config.rb这个配置，如果有，则加载。<br />
	3、设置config.vm.url，并获取对应的json文件：</p>
<p><font face="Courier New">{<br />
	&nbsp; &quot;name&quot;: &quot;coreos-stable&quot;,<br />
	&nbsp; &quot;description&quot;: &quot;CoreOS stable&quot;,<br />
	&nbsp; &quot;versions&quot;: [{<br />
	&nbsp;&nbsp;&nbsp; &quot;version&quot;: &quot;717.3.0&quot;,<br />
	&nbsp;&nbsp;&nbsp; &quot;providers&quot;: [{<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;name&quot;: &quot;virtualbox&quot;,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;url&quot;: &quot;http://stable.release.core-os.net/amd64-usr/717.3.0/coreos_production_vagrant.box&quot;,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;checksum_type&quot;: &quot;sha256&quot;,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;checksum&quot;: &quot;99dcd74c7cae8b1d90f108f8819f92b17bfbd34f4f141325bd0400fe4def55b6&quot;<br />
	&nbsp;&nbsp;&nbsp; }]<br />
	&nbsp; }]<br />
	}</font></p>
<p>4、根据config.vm.provider（是virtualbox还是vmvare等）来决定采用哪种虚拟机创建逻辑。</p>
<p>这里我们看到，整个过程只需要从core-os.net下载两个文件：<font face="Courier New">coreos_production_vagrant.box</font>和<font face="Courier New">coreos_production_vagrant.json</font>。如果我们提前将这两个文件下载到本地，并放在一个临时的http server下，修改Vagrantfile和coreos_production_vagrant.json这两个文件，就应该可以通过coreos-vagrant安装了。</p>
<p><b>二、coreos-vagrant安装single instance CoreOS</b></p>
<p>好了，根据上述原理，我们首先要下载<font face="Courier New">coreos_production_vagrant.box</font>和<font face="Courier New">coreos_production_vagrant.json这两个文件，根据我们的channel和版本选择，两个文件的下载地址分别为：</font></p>
<p><font face="Courier New">&nbsp;http://stable.release.core-os.net/amd64-usr/717.3.0/coreos_production_vagrant.box</font><br />
	<font face="Courier New">&nbsp;http://stable.release.core-os.net/amd64-usr/717.3.0/</font><font face="Courier New"><font face="Courier New">coreos_production_vagrant.json</font></font></p>
<p>接下来就是不管你用什么梯子，只要把这两个文件下载到本地，并放到一个目录下就好了。</p>
<p>我们需要修改一下<font face="Courier New"><font face="Courier New">coreos_production_vagrant.json，将其中的url改为：<br />
	&nbsp;&nbsp;&nbsp;<br />
	&nbsp;&nbsp;&nbsp; &quot;url&quot;: &quot;http://localhost:8080/coreos_production_vagrant.box&quot;</font></font></p>
<p>我们要将这两个文件放到一个local file server中，后续供core-vagrant访问。最简单的方法就是使用<font face="Courier New">:</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; python -m SimpleHTTPServer 8080</font></p>
<p>当然使用Go实现一个简单的http file server也是非常简单的：</p>
<p><font face="Courier New">//fileserver.go<br />
	package main</font></p>
<p><font face="Courier New">import &quot;net/http&quot;<br />
	import &quot;log&quot;</font></p>
<p><font face="Courier New">func main() {<br />
	&nbsp;&nbsp;&nbsp; log.Fatal(http.ListenAndServe(&quot;:8080&quot;, http.FileServer(http.Dir(&quot;./&quot;))))<br />
	}</font></p>
<p>接下来我们就可以按照正常步骤，下载coreos-vagrant并up了：</p>
<p><font face="Courier New">$git clone https://github.com/coreos/coreos-vagrant</font></p>
<p>修改Vagrantfile：</p>
<p><font face="Courier New">$ diff Vagrantfile Vagrantfile.bak<br />
	14,15c14,15<br />
	&lt; $update_channel = &quot;stable&quot;<br />
	&lt; $image_version = &quot;717.3.0&quot;<br />
	&#8212;<br />
	&gt; $update_channel = &quot;alpha&quot;<br />
	&gt; $image_version = &quot;current&quot;<br />
	55c55<br />
	&lt;&nbsp;&nbsp; config.vm.box_url = &quot;http://localhost:8080/coreos_production_vagrant.json&quot;<br />
	&#8212;<br />
	&gt;&nbsp;&nbsp; config.vm.box_url = &quot;http://%s.release.core-os.net/amd64-usr/%s/coreos_production_vagrant.json&quot; % [$update_channel, $image_version]</font></p>
<p>将user-data.sample改名为user-data，并编辑user-data，在etcd2下面增加一行：</p>
<p>&nbsp;&nbsp;&nbsp; &nbsp; <font face="Courier New">etcd2:<br />
	&nbsp;&nbsp;&nbsp; name: core-01</font></p>
<p>将units:下面对于etcd2的注释去掉，以enable etcd2服务。（将etcd服务注释掉）</p>
<p>万事俱备，只需vagrant up。</p>
<p><font face="Courier New">$ vagrant up<br />
	Bringing machine &#39;core-01&#39; up with &#39;virtualbox&#39; provider&#8230;<br />
	==&gt; core-01: Box &#39;coreos-stable&#39; could not be found. Attempting to find and install&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-01: <b>Box Provider: virtualbox</b><br />
	&nbsp;&nbsp;&nbsp; core-01: <b>Box Version: 717.3.0</b><br />
	==&gt; core-01: <b>Loading metadata for box &#39;http://localhost:8080/coreos_production_vagrant.json&#39;</b><br />
	&nbsp;&nbsp;&nbsp; core-01: URL: http://localhost:8080/coreos_production_vagrant.json<br />
	==&gt; core-01: Adding box &#39;coreos-stable&#39; (v717.3.0) for provider: virtualbox<br />
	&nbsp;&nbsp;&nbsp; core-01: <b>Downloading: http://localhost:8080/coreos_production_vagrant.box</b><br />
	&nbsp;&nbsp;&nbsp; core-01: Calculating and comparing box checksum&#8230;<br />
	==&gt; core-01: Successfully added box &#39;coreos-stable&#39; (v717.3.0) for &#39;virtualbox&#39;!<br />
	==&gt; core-01: Importing base box &#39;coreos-stable&#39;&#8230;<br />
	==&gt; core-01: Matching MAC address for NAT networking&#8230;<br />
	==&gt; core-01: Checking if box &#39;coreos-stable&#39; is up to date&#8230;<br />
	==&gt; core-01: Setting the name of the VM: coreos-vagrant_core-01_1437121834188_89503<br />
	==&gt; core-01: Clearing any previously set network interfaces&#8230;<br />
	==&gt; core-01: Preparing network interfaces based on configuration&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-01: Adapter 1: nat<br />
	&nbsp;&nbsp;&nbsp; core-01: Adapter 2: hostonly<br />
	==&gt; core-01: Forwarding ports&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-01: 22 =&gt; 2222 (adapter 1)<br />
	==&gt; core-01: Running &#39;pre-boot&#39; VM customizations&#8230;<br />
	==&gt; core-01: Booting VM&#8230;<br />
	==&gt; core-01: Waiting for machine to boot. This may take a few minutes&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-01: SSH address: 127.0.0.1:2222<br />
	&nbsp;&nbsp;&nbsp; core-01: SSH username: core<br />
	&nbsp;&nbsp;&nbsp; core-01: SSH auth method: private key<br />
	&nbsp;&nbsp;&nbsp; core-01: Warning: Connection timeout. Retrying&#8230;<br />
	==&gt; core-01: Machine booted and ready!<br />
	==&gt; core-01: Setting hostname&#8230;<br />
	==&gt; core-01: Configuring and enabling network interfaces&#8230;<br />
	==&gt; core-01: Running provisioner: file&#8230;<br />
	==&gt; core-01: Running provisioner: shell&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-01: Running: inline script</font></p>
<p><font face="Courier New">登入你的coreos实例：<br />
	$ vagrant ssh<br />
	CoreOS stable (717.3.0)<br />
	core@core-01 ~ $ </font></p>
<p>在vagrant up时，你可能会遇到如下两个错误：</p>
<p>错误1：</p>
<p><font face="Courier New">Progress state: VBOX_E_FILE_ERROR<br />
	VBoxManage: error: Could not open the medium storage unit &#39;/home1/tonybai/.vagrant.d/boxes/coreos-stable/717.3.0/virtualbox/coreos_production_vagrant_image.vmdk&#39;.<br />
	VBoxManage: error: VMDK: inconsistent references to grain directory in &#39;/home1/tonybai/.vagrant.d/boxes/coreos-stable/717.3.0/virtualbox/coreos_production_vagrant_image.vmdk&#39;&nbsp; (VERR_VD_VMDK_INVALID_HEADER).</font></p>
<p>这个问题的原因很可能是你的Virtualbox版本不对，比如版本太低，与<font face="Courier New"><b>coreos_production_vagrant.box</b>格式不兼容<b>。可</b></font>尝试安装一下高版本virtualbox来解决。</p>
<p>错误2：</p>
<p><font face="Courier New">core-01: SSH address: 127.0.0.1:2222<br />
	core-01: SSH username: core<br />
	core-01: SSH auth method: private key<br />
	core-01: Warning: Connection timeout. Retrying&#8230;<br />
	core-01: Warning: Connection timeout. Retrying&#8230;<br />
	core-01: Warning: Connection timeout. Retrying&#8230;</font></p>
<p>coreos虚拟机创建后，似乎一直无法连接上。在coreos的github issue中，有人遇到了这个问题，目前给出的原因是因为cpu的支持虚拟化技术的vt开关没有打开，需要在bios中将其开启。这主要在安装64bit box时才会发生。</p>
<p>到这里，我们已经完成了一个single instance coreos虚拟机的安装。vagrant halt可以帮助你将启动的coreos虚拟机停下来。</p>
<p><font face="Courier New">$ vagrant halt<br />
	==&gt; core-01: Attempting graceful shutdown of VM&#8230;</font></p>
<p><b>三、&nbsp; CoreOS</b><font face="Courier New"><b> cluster</b></font></p>
<p>上面虽然成功的安装了coreos，然并卵。在实际应用中，CoreOS多以Cluster形式呈现，也就是说我们要启动多个CoreOS实例。</p>
<p>使用vagrant启动多个coreos实例很简单，只需将配置中的$num_instances从1改为n。</p>
<p>这里我们启用config.rb这个配置文件(将<font face="Courier New">config.rb.sample改名为config.rb</font>)，并将其中的$num_instances修改为3：</p>
<p><font face="Courier New"># Size of the CoreOS cluster created by Vagrant<br />
	$num_instances=3</font></p>
<p>该配置文件中的数据会覆盖Vagrantfile中的默认配置。</p>
<p>三个instance中的etcd2要想组成集群还需要一个配置修改，那就是在etcd.io上申请一个token：</p>
<p><font face="Courier New">$curl https://discovery.etcd.io/new</p>
<p>https://discovery.etcd.io/fe81755687323aae273dc5f111eb059a</font></p>
<p>将这个token配置到user-data中的etcd2下：</p>
<p><font face="Courier New">&nbsp; etcd2:</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; #generate a new token for each unique cluster from https://discovery.etcd.io/new<br />
	&nbsp;&nbsp;&nbsp; #discovery: https://discovery.etcd.io/&lt;token&gt;<br />
	&nbsp;&nbsp;&nbsp; discovery: https://discovery.etcd.io/fe81755687323aae273dc5f111eb059a</font></p>
<p>我们再来up看看：</p>
<p><font face="Courier New">$ vagrant up<br />
	Bringing machine &#39;core-01&#39; up with &#39;virtualbox&#39; provider&#8230;<br />
	Bringing machine &#39;core-02&#39; up with &#39;virtualbox&#39; provider&#8230;<br />
	Bringing machine &#39;core-03&#39; up with &#39;virtualbox&#39; provider&#8230;<br />
	==&gt; core-01: Checking if box &#39;coreos-stable&#39; is up to date&#8230;<br />
	==&gt; core-01: VirtualBox VM is already running.<br />
	==&gt; core-02: Importing base box &#39;coreos-stable&#39;&#8230;<br />
	==&gt; core-02: Matching MAC address for NAT networking&#8230;<br />
	==&gt; core-02: Checking if box &#39;coreos-stable&#39; is up to date&#8230;<br />
	==&gt; core-02: Setting the name of the VM: coreos-vagrant_core-02_1437388468647_96550<br />
	==&gt; core-02: Fixed port collision for 22 =&gt; 2222. Now on port 2200.<br />
	==&gt; core-02: Clearing any previously set network interfaces&#8230;<br />
	==&gt; core-02: Preparing network interfaces based on configuration&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-02: Adapter 1: nat<br />
	&nbsp;&nbsp;&nbsp; core-02: Adapter 2: hostonly<br />
	==&gt; core-02: Forwarding ports&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-02: 22 =&gt; 2200 (adapter 1)<br />
	==&gt; core-02: Running &#39;pre-boot&#39; VM customizations&#8230;<br />
	==&gt; core-02: Booting VM&#8230;<br />
	==&gt; core-02: Waiting for machine to boot. This may take a few minutes&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-02: SSH address: 127.0.0.1:2200<br />
	&nbsp;&nbsp;&nbsp; core-02: SSH username: core<br />
	&nbsp;&nbsp;&nbsp; core-02: SSH auth method: private key<br />
	&nbsp;&nbsp;&nbsp; core-02: Warning: Connection timeout. Retrying&#8230;<br />
	==&gt; core-02: Machine booted and ready!<br />
	==&gt; core-02: Setting hostname&#8230;<br />
	==&gt; core-02: Configuring and enabling network interfaces&#8230;<br />
	==&gt; core-02: Running provisioner: file&#8230;<br />
	==&gt; core-02: Running provisioner: shell&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-02: Running: inline script<br />
	==&gt; core-03: Importing base box &#39;coreos-stable&#39;&#8230;<br />
	==&gt; core-03: Matching MAC address for NAT networking&#8230;<br />
	==&gt; core-03: Checking if box &#39;coreos-stable&#39; is up to date&#8230;<br />
	==&gt; core-03: Setting the name of the VM: coreos-vagrant_core-03_1437388512743_68112<br />
	==&gt; core-03: Fixed port collision for 22 =&gt; 2222. Now on port 2201.<br />
	==&gt; core-03: Clearing any previously set network interfaces&#8230;<br />
	==&gt; core-03: Preparing network interfaces based on configuration&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-03: Adapter 1: nat<br />
	&nbsp;&nbsp;&nbsp; core-03: Adapter 2: hostonly<br />
	==&gt; core-03: Forwarding ports&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-03: 22 =&gt; 2201 (adapter 1)<br />
	==&gt; core-03: Running &#39;pre-boot&#39; VM customizations&#8230;<br />
	==&gt; core-03: Booting VM&#8230;<br />
	==&gt; core-03: Waiting for machine to boot. This may take a few minutes&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-03: SSH address: 127.0.0.1:2201<br />
	&nbsp;&nbsp;&nbsp; core-03: SSH username: core<br />
	&nbsp;&nbsp;&nbsp; core-03: SSH auth method: private key<br />
	&nbsp;&nbsp;&nbsp; core-03: Warning: Connection timeout. Retrying&#8230;<br />
	==&gt; core-03: Machine booted and ready!<br />
	==&gt; core-03: Setting hostname&#8230;<br />
	==&gt; core-03: Configuring and enabling network interfaces&#8230;<br />
	==&gt; core-03: Running provisioner: file&#8230;<br />
	==&gt; core-03: Running provisioner: shell&#8230;<br />
	&nbsp;&nbsp;&nbsp; core-03: Running: inline script</font></p>
<p><font face="Courier New">$vagrant ssh core-02<br />
	CoreOS stable (717.3.0)<br />
	core@core-02 ~ $</font></p>
<p>可以看到Vagrant启动了三个coreos instance。关闭这些instance，同样用halt：</p>
<p><font face="Courier New">$ vagrant halt<br />
	==&gt; core-03: Attempting graceful shutdown of VM&#8230;<br />
	==&gt; core-02: Attempting graceful shutdown of VM&#8230;<br />
	==&gt; core-01: Attempting graceful shutdown of VM&#8230;</font></p>
<p><b>四、小结</b></p>
<p>以上仅仅是CoreOS最基本的入门，虽然现在安装ok了，但CoreOS的各种服务组件的功用、配置；如何与Docker配合形成分布式服务系统；如何用<a href="http://github.com/GoogleCloudPlatform/kubernetes">Google Kubernetes</a>管理容器集群等还需更进一步深入学习，这个后续会慢慢道来。</p>
<p style='text-align:left'>&copy; 2015, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2015/07/20/install-coreos-by-coreos-vagrant/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>VirtualBox虚拟机下Windows登录密码破解方法</title>
		<link>https://tonybai.com/2014/10/29/crack-windows-logon-password-under-virtualbox/</link>
		<comments>https://tonybai.com/2014/10/29/crack-windows-logon-password-under-virtualbox/#comments</comments>
		<pubDate>Wed, 29 Oct 2014 09:28:52 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[CDLinux]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[Crack]]></category>
		<category><![CDATA[livecd]]></category>
		<category><![CDATA[MacAir]]></category>
		<category><![CDATA[TinyCoreLinux]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[vm]]></category>
		<category><![CDATA[Win7]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[破解]]></category>
		<category><![CDATA[虚拟机]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1589</guid>
		<description><![CDATA[近两年虚拟机的发展给开发人员带来了极大便利，安装一个新环境，只需从别人那里copy一份虚拟机文件即可，分分钟搞定。我之前一直在Ubuntu下工 作，Windows偶尔使用，于是在Ubuntu VirtualBox下安装了一个Windows 7。今年将工作环境迁移到Mac Air下了，但偶尔也有Windows的使用需求，于是直接从我原来的Ubuntu下将Win7的Vdi文件Copy到Air上，便直接可以使用Win7 了，省去了重新安装Win7以及庞大的Office组件的工作。 前两天，打开Mac Air下的VirtualBox，启动Win7虚拟机，在Win7登录界面输入密码后，系统提示我密码错误。反复输入多次，将我常用的密码都试了一遍依旧 无法进入。我只能在原Ubuntu下临时用用Win7。但毕竟在Air上没有Win7十分不便，一些Word, PPT文档需要在两天机器上传来传去。无奈下，我都由了重新在Air下安装一个Win7甚至是Win8的打算了。 今天又有一个PPT编写的task，这件事再次被提上日程。我换了下思维：能不能破解一下Win7登录密码呢？于是求助度娘（谷哥离去好久了）。还别说， 还真是有破解方法，多数是通过PE工具盘快速修改登录密码。但PE工具盘挺大（几百兆，公司下载不便），我的又是虚拟机环境，这种方法不是我的菜啊。于是 又看到另外一种思路：通过某个Linux livecd或安装盘引导，mount windows分区，将C:\Windows\System32\cmd.exe改名为osk.exe。osk.exe是虚拟键盘程序。在Win7登录页 面的左下角可以启动这个虚拟键盘程序。一旦我替换成功，启动虚拟键盘程序就变成了启动Win7命令行程序。有了命令行，我们就可以通过net user命令查看当前账户列表、重置某个用户的password了。思路很清晰，是我的菜。 在我的Ubuntu机器上倒是有几个Linux发行版的live cd iso文件，比如ubuntu 14.04.1 desktop, centos7 desktop，不过个头都太大了，传到我的Air上还是很费劲的。我想最好有一个tiny的linux发行版。度娘告诉我有很多选择。我首先选了Tiny Core Linux， TinyCore-5.4.iso才不到14M。于是打开Win7虚拟机的&#8220;设置&#8221;页面，将 TinyCore-5.4.iso作为虚拟iso&#8220;插入&#8221;IDE光驱。TinyCore的启动就是秒秒的事情。TinyCore的桌面风格模仿Mac OS，桌面下方放置了一个dock条。TinyCore自带mount tools，打开后，用鼠标点击sda2，sda2盘符由红变绿，说明mount成功。 打开TinyCore的Terminal程序，进入/mnt/sda2，本想安装方案修改cmd.exe的名字，但Tiny Core提示：这是个Read-Only Filesystem。显然这是个只读mount。于是各种尝试读写挂在（包括修改/etc/fstab、mount -a, mount -o remount等），都无法改变Read-Only Filesystem的事实，于是放弃。 换国人的发行版：CDLinux，这个发行版似乎已经不再更新，最新版本 CDlinux_mini-0.9.7.1.iso，发布时间是2012年3月18日。CDLinux的Size比TinyLinux稍大些，36M。 CDLinux启动略慢，并且只是Console Only（标准版带有桌面环境），没有图形桌面。进入命令行后，执行一下mount命令，发现/dev/sda2居然是rw方式挂载载/media /xxx下的，于是进入该目录，尝试touch test.txt，完全没有问题。 于是按照方案说明，将C:\Windows\System32下的osk.exe备份一下，将cmd.exe改名为osk.exe。 将光盘盘片删除，启动Win7，进入登陆页面时，点击左下角&#8220;轻松访问&#8221;按钮，选择&#8220;不使用键盘键入&#8221;，确定。命令行窗口弹出。 在命令行窗口执行net user 查看用户名列表。我的用户名是tonybai，再通过net user tonybai newpassword重置tonybai的密码。执行成功后，用新密码登陆，顺利进入Win7 Desktop。Crack成功！ &#169; 2014, [...]]]></description>
			<content:encoded><![CDATA[<p>近两年虚拟机的发展给开发人员带来了极大便利，安装一个新环境，只需从别人那里copy一份虚拟机文件即可，分分钟搞定。我之前一直在<a href="http://tonybai.com/tag/Ubuntu/">Ubuntu</a>下工 作，Windows偶尔使用，于是在Ubuntu<a href="http://virtualbox.org/"> VirtualBox</a>下安装了一个Windows 7。今年将工作环境迁移到Mac Air下了，但偶尔也有Windows的使用需求，于是直接从我原来的<a href="http://tonybai.com/2012/12/04/upgrade-ubuntu-to-1204-lts/">Ubuntu</a>下将Win7的Vdi文件Copy到Air上，便直接可以使用Win7 了，省去了重新安装Win7以及庞大的Office组件的工作。</p>
<p>前两天，打开Mac Air下的VirtualBox，启动Win7虚拟机，在Win7登录界面输入密码后，系统提示我密码错误。反复输入多次，将我常用的密码都试了一遍依旧 无法进入。我只能在原Ubuntu下临时用用Win7。但毕竟在Air上没有Win7十分不便，一些Word, PPT文档需要在两天机器上传来传去。无奈下，我都由了重新在Air下安装一个Win7甚至是Win8的打算了。</p>
<p>今天又有一个PPT编写的task，这件事再次被提上日程。我换了下思维：能不能破解一下Win7登录密码呢？于是求助度娘（谷哥离去好久了）。还别说， 还真是有破解方法，多数是通过PE工具盘快速修改登录密码。但PE工具盘挺大（几百兆，公司下载不便），我的又是虚拟机环境，这种方法不是我的菜啊。于是 又看到另外一种思路：通过某个Linux livecd或安装盘引导，mount windows分区，将C:\Windows\System32\cmd.exe改名为osk.exe。osk.exe是虚拟键盘程序。在Win7登录页 面的左下角可以启动这个虚拟键盘程序。一旦我替换成功，启动虚拟键盘程序就变成了启动Win7命令行程序。有了命令行，我们就可以通过net user命令查看当前账户列表、重置某个用户的password了。思路很清晰，是我的菜。</p>
<p>在我的Ubuntu机器上倒是有几个Linux发行版的live cd iso文件，比如ubuntu 14.04.1 desktop, centos7 desktop，不过个头都太大了，传到我的Air上还是很费劲的。我想最好有一个tiny的linux发行版。度娘告诉我有很多选择。我首先选了<a href="http://distro.ibiblio.org/tinycorelinux/">Tiny Core Linux</a>， TinyCore-5.4.iso才不到14M。于是打开Win7虚拟机的&ldquo;设置&rdquo;页面，将 TinyCore-5.4.iso作为虚拟iso&ldquo;插入&rdquo;IDE光驱。TinyCore的启动就是秒秒的事情。TinyCore的桌面风格模仿Mac OS，桌面下方放置了一个dock条。TinyCore自带mount tools，打开后，用鼠标点击sda2，sda2盘符由红变绿，说明mount成功。</p>
<p>打开TinyCore的Terminal程序，进入/mnt/sda2，本想安装方案修改cmd.exe的名字，但Tiny Core提示：这是个Read-Only Filesystem。显然这是个只读mount。于是各种尝试读写挂在（包括修改/etc/fstab、mount -a, mount -o remount等），都无法改变Read-Only Filesystem的事实，于是放弃。</p>
<p>换国人的发行版：<a href="http://cdlinux.info/wiki/">CDLinux</a>，这个发行版似乎已经不再更新，最新版本 CDlinux_mini-0.9.7.1.iso，发布时间是2012年3月18日。CDLinux的Size比TinyLinux稍大些，36M。 CDLinux启动略慢，并且只是Console Only（标准版带有桌面环境），没有图形桌面。进入命令行后，执行一下mount命令，发现/dev/sda2居然是rw方式挂载载/media /xxx下的，于是进入该目录，尝试touch test.txt，完全没有问题。</p>
<p>于是按照方案说明，将C:\Windows\System32下的osk.exe备份一下，将cmd.exe改名为osk.exe。</p>
<p>将光盘盘片删除，启动Win7，进入登陆页面时，点击左下角&ldquo;轻松访问&rdquo;按钮，选择&ldquo;不使用键盘键入&rdquo;，确定。命令行窗口弹出。</p>
<p>在命令行窗口执行net user 查看用户名列表。我的用户名是tonybai，再通过net user tonybai newpassword重置tonybai的密码。执行成功后，用新密码登陆，顺利进入Win7 Desktop。Crack成功！</p>
<p style='text-align:left'>&copy; 2014, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2014/10/29/crack-windows-logon-password-under-virtualbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu Server 14.04安装docker</title>
		<link>https://tonybai.com/2014/09/26/install-docker-on-ubuntu-server-1404/</link>
		<comments>https://tonybai.com/2014/09/26/install-docker-on-ubuntu-server-1404/#comments</comments>
		<pubDate>Fri, 26 Sep 2014 07:09:52 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Blogger]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Kernel]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Opensource]]></category>
		<category><![CDATA[Programmer]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[学习]]></category>
		<category><![CDATA[容器]]></category>
		<category><![CDATA[工作]]></category>
		<category><![CDATA[程序员]]></category>
		<category><![CDATA[端口转发]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1547</guid>
		<description><![CDATA[近期在研究docker这一轻量级容器引擎，研究docker对日常开发测试工作以及产品部署运维工作能带来哪些便利。前些时候刚刚将工作环境从 Ubuntu搬到了Mac Air上，对Mac OS X的一切均不甚熟悉，给docker研究带来了不便，于是打算在VirtualBox中安装一Ubuntu Server作为docker之承载平台。这里记录一下安装配置过程，主要为了备忘，如果能给其他人带来帮助，我会甚感欣慰。 docker官方对ubuntu的支持是蛮好的。docker对Linux内核版本有要求，要&#62;=3.8，Ubuntu Server目前最新版本14.04.1恰符合这一要求，其kernel version = 3.13.0-32。 一、VirtualBox安装Ubuntu Server 14.04.1 VirtualBox安装Ubuntu OS做过了不止一遍，即便是换成最新的14.04.1 Server版，差别也没有太多，无非是按照安装提示，逐步Next。这里给Ubuntu Server 14.04分配了1G Memory, 32G动态硬盘空间。 【配置源】 &#160; 默认情况下，/etc/apt/sources.list中只有一组源：cn.archive.ubuntu.com/ubuntu。这个国外源的下载速度显然无法满足我的要求，于是我把我常用的sohu源加入sources.list中，并且放在前面： &#160; deb http://mirrors.sohu.com/ubuntu/ trusty main restricted &#160; deb http://mirrors.sohu.com/ubuntu/ trusty-security main restricted &#160; deb http://mirrors.sohu.com/ubuntu/ trusty-updates main restricted &#160; deb http://mirrors.sohu.com/ubuntu/ trusty-proposed main restricted &#160; deb http://mirrors.sohu.com/ubuntu/ trusty-backports main restricted &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>近期在研究<a href="http://docker.com">docker</a>这一轻量级容器引擎，研究docker对日常开发测试工作以及产品部署运维工作能带来哪些便利。前些时候刚刚将工作环境从 <a href="http://tonybai.com/tag/ubuntu">Ubuntu</a>搬到了Mac Air上，对Mac OS X的一切均不甚熟悉，给docker研究带来了不便，于是打算在<a href="http://virtualbox.org">VirtualBox</a>中安装一Ubuntu Server作为docker之承载平台。这里记录一下安装配置过程，主要为了备忘，如果能给其他人带来帮助，我会甚感欣慰。</p>
<p>docker官方对<a href="http://ubuntu.com">ubuntu</a>的支持是蛮好的。docker对Linux内核版本有要求，要&gt;=3.8，Ubuntu Server目前最新版本14.04.1恰符合这一要求，其kernel version = 3.13.0-32。</p>
<p><strong>一、VirtualBox安装Ubuntu Server 14.04.1</strong></p>
<p>VirtualBox安装Ubuntu OS做过了不止一遍，即便是换成最新的14.04.1 Server版，差别也没有太多，无非是按照安装提示，逐步Next。这里给Ubuntu Server 14.04分配了1G Memory, 32G动态硬盘空间。</p>
<p>【配置源】</p>
<p>&nbsp; 默认情况下，/etc/apt/sources.list中只有一组源：cn.archive.ubuntu.com/ubuntu。这个国外源的下载速度显然无法满足我的要求，于是我把我常用的sohu源加入sources.list中，并且放在前面：</p>
<p><font face="Courier New">&nbsp; deb http://mirrors.sohu.com/ubuntu/ trusty main restricted<br />
	&nbsp; deb http://mirrors.sohu.com/ubuntu/ trusty-security main restricted<br />
	&nbsp; deb http://mirrors.sohu.com/ubuntu/ trusty-updates main restricted<br />
	&nbsp; deb http://mirrors.sohu.com/ubuntu/ trusty-proposed main restricted<br />
	&nbsp; deb http://mirrors.sohu.com/ubuntu/ trusty-backports main restricted</font></p>
<p><font face="Courier New">&nbsp; deb-src http://mirros.sohu.com/ubuntu/ trusty main restricted<br />
	&nbsp; deb-src http://mirrors.sohu.com/ubuntu/ trusty-security main restricted<br />
	&nbsp; deb-src http://mirrors.sohu.com/ubuntu/ trusty-updates main restricted<br />
	&nbsp; deb-src http://mirrors.sohu.com/ubuntu/ trusty-proposed main restricted<br />
	&nbsp; deb-src http://mirrors.sohu.com/ubuntu/ trusty-backports main restricted</font></p>
<p>&nbsp; 公司采用代理访问外网，于是还得在/etc/apt/apt.conf中加上代理的设置，否则无法更新源，也就无法安装第三方软件：</p>
<p><font face="Courier New">&nbsp; Acquire::http::Proxy &quot;http://username:passwd@proxyhost:proxyport&quot;;</font></p>
<p>&nbsp;【乱码处理】</p>
<p>&nbsp; 由于安装时候选择了中国区域（locale zh_CN.UTF-8），因此在VirtualBox的窗口中直接执行命令的提示信息可能是乱码。对于Server，我们一般是不会直接通过其主机显示 器登录使用的，都是通过终端访问，但在未安装和开启ssh服务和未配置端口转发前，我们只能先凑合这个窗口了。可先将/etc/default /locale中的LANGUAGE由&quot;zh_CN:zh&quot;改为&quot;en_US:en&quot;， logout后重新登录就可以看到非乱码的英文提示信息了。</p>
<p>【安装VirtualBox增强组件】</p>
<p>&nbsp; Ubuntu Server默认是不安装图形桌面的，只有一个命令行窗口，连鼠标都无法使用。因此增强组件安装的意义没有桌面系统那么强烈。我能想到的只有&ldquo;共享目录&rdquo;这一个功能有些用处。</p>
<p>&nbsp; 安装方法也不难，按下面步骤逐步操作即可：</p>
<p><font face="Courier New">&nbsp; sudo apt-get install build-essential linux-headers-$(uname -r) dkms gcc g++<br />
	&nbsp; sudo mnt /dev/cdrom /mnt<br />
	&nbsp; cd /mnt<br />
	&nbsp; sudo bash ./VBoxLinuxAdditions.run</font></p>
<p>&nbsp; 如果结果都是&quot;done&quot;，重启后就ok了。</p>
<p>【安装ssh服务】</p>
<p>&nbsp;&nbsp;&nbsp; ssh服务由openssh-server提供：<br />
	&nbsp;&nbsp;&nbsp; <font face="Courier New">sudo apt-get openssh-server</font><br />
	&nbsp;&nbsp;&nbsp;<br />
	&nbsp;&nbsp; 安装成功后，ssh server服务就会自动启动起来。</p>
<p>&nbsp;&nbsp; 不过我们还是需要修改一些配置，比如允许Root登录：打开/etc/ssh/sshd_config，将PermitRootLogin后面的内容改为yes。<br />
	&nbsp;&nbsp;&nbsp;<br />
	【设置端口转发】</p>
<p>&nbsp; 前面说过，对于Server，我们更多是在其他主机上通过ssh或telnet远程访问该Server并执行各种操作。由于这里是VirtualBox安 装的虚拟机，其他主机无法看到这台Server，我们需要设置端口转发将外部访问的数据转发给这个内部虚拟Server。</p>
<p>&nbsp; 我们通过VirtualBox软件提供的图形界面即可完成这个操作：<br />
	&nbsp;&nbsp;&nbsp; 1、&ldquo;设置&rdquo;这个虚拟机<br />
	&nbsp;&nbsp;&nbsp; 2、在&ldquo;网络&rdquo;标签中，点击&ldquo;端口转发&rdquo;按钮，进入端口转发规则添加窗口。<br />
	&nbsp;&nbsp;&nbsp; 3、添加一条规则：<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 名称：ssh-rules<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 协议：TCP<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主机IP、子系统IP可以为空。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 主机端口：2222<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 子系统端口：22<br />
	&nbsp;&nbsp; 4、配置结束</p>
<p>&nbsp;&nbsp;&nbsp; 配置结束后，我们在宿主机上netstat -an|grep 2222，可以看到VirtualBox增加了该端口2222的监听。</p>
<p>&nbsp; 现在我们就可以在其他机器上通过ssh -l tonybai 宿主机ip -p 2222的方式登录到我们新安装的这台虚拟Server了。</p>
<p>&nbsp;&nbsp;<br />
	<b>二、安装docker</b></p>
<p>docker目前的最新版本号是1.2.0，但14.04源中的docker还是正式稳定版1.0之前的版本，显然这是无法满足我的要求的。我们只能另外添加docker源来安装最新版docker。</p>
<p>&nbsp; 【安装docker】</p>
<p>&nbsp;&nbsp;&nbsp; 我们在/etc/apt/sources.list中加入下面这个源：<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face="Courier New">deb <a class="moz-txt-link-freetext" href="http://mirror.yandex.ru/mirrors/docker/">http://mirror.yandex.ru/mirrors/docker/</a> docker main</font><br />
	&nbsp;&nbsp;<br />
	&nbsp;&nbsp;&nbsp; 执行apt-get update。</p>
<p>&nbsp;&nbsp;&nbsp; sudo apt-get install lxc-docker</p>
<p><font face="Courier New">正在读取软件包列表&#8230; 完成<br />
	正在分析软件包的依赖关系树&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
	正在读取状态信息&#8230; 完成&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
	将会安装下列额外的软件包：<br />
	&nbsp; aufs-tools cgroup-lite git git-man liberror-perl lxc-docker-1.2.0<br />
	建议安装的软件包：<br />
	&nbsp; git-daemon-run git-daemon-sysvinit git-doc git-el git-email git-gui gitk<br />
	&nbsp; gitweb git-arch git-bzr git-cvs git-mediawiki git-svn<br />
	下列新软件包将被安装：<br />
	&nbsp; aufs-tools cgroup-lite git git-man liberror-perl lxc-docker lxc-docker-1.2.0<br />
	升级了 0 个软件包，新安装了 7 个软件包，要卸载 0 个软件包，有 59 个软件包未被升级。<br />
	需要下载 7,477 kB 的软件包。<br />
	解压缩后会消耗掉 35.4 MB 的额外空间。<br />
	您希望继续执行吗？ [Y/n] y</font></p>
<p>&nbsp; 这个源里的docker居然是最新版。于是安装之。安装后，我们执行docker version来确认一下安装是否成功。</p>
<p><font face="Courier New">&nbsp; tonybai@ubuntu-Server-14:~$ docker version<br />
	Client version: 1.2.0<br />
	Client API version: 1.14<br />
	Go version (client): go1.3.1<br />
	Git commit (client): fa7b24f<br />
	OS/Arch (client): linux/amd64<br />
	2014/09/26 13:56:53 Get http:///var/run/docker.sock/v1.14/version: dial unix /var/run/docker.sock: permission denied</font></p>
<p>&nbsp; 【为docker设置http代理】</p>
<p>&nbsp;&nbsp;&nbsp; 在公司内使用代理才能访问到外网，于是我们也需要为docker命令设置代理以使其顺利执行命令。</p>
<p>&nbsp;&nbsp;&nbsp; 我们安装的docker实际上分为两部分，docker命令行和docker daemon。两者是C/S结构，docker命令行将用户的请求转发给docker daemon，后者会真正与外部通信完成各种操作。</p>
<p>&nbsp;&nbsp;&nbsp; 于是我们可以这样为docker daemon设置http_proxy:<br />
	<font face="Courier New">&nbsp;&nbsp;&nbsp; sudo service docker stop<br />
	&nbsp;&nbsp;&nbsp; sudo http_proxy=&#39;<a class="moz-txt-link-freetext" href="http://baim:xxx@proxy.neusoft.com:8080">http://user:passwd@proxyhost:port</a>&#39; docker -d &amp;</font></p>
<p>&nbsp;&nbsp;&nbsp; 这样设置启动后，我们可以通过下面命令测试设置是否ok：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face="Courier New"> sudo docker search ubuntu</font></p>
<p>&nbsp;&nbsp;&nbsp; 如果你看到下面信息，说明设置成功了：</p>
<p>&nbsp;<font face="Courier New">&nbsp;&nbsp; tonybai@ubuntu-Server-14:~$ sudo docker search ubuntu<br />
	[info] GET /v1.14/images/search?term=ubuntu<br />
	[b36518a9] +job search(ubuntu)<br />
	[b36518a9] -job search(ubuntu) = OK (0)<br />
	NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DESCRIPTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STARS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OFFICIAL&nbsp;&nbsp; AUTOMATED<br />
	ubuntu&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Official Ubuntu base image&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 709&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OK]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
	dockerfile/ubuntu&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Trusted automated Ubuntu (http://www.ubunt&#8230;&nbsp;&nbsp; 24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OK]<br />
	crashsystems/gitlab-docker&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A trusted, regularly updated build of GitL&#8230;&nbsp;&nbsp; 20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OK]<br />
	ubuntu-upstart&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Upstart is an event-based replacement for &#8230;&nbsp;&nbsp; 13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OK]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><br />
	&#8230; &#8230;.</p>
<p>&nbsp;</p>
<p style='text-align:left'>&copy; 2014, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2014/09/26/install-docker-on-ubuntu-server-1404/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
