The Mirages

樱桃沟夹事

去的航班买的不好,买了南航在伊斯坦布尔转机的,转机时间是6个小时,当然这不是重点。重点是南航这个班机不是在直接到伊斯坦布尔,当中还要转。怪不得在机场跟南航柜台说到巴黎,她还一脸惊讶。 进了机场,居然没有过海关,这就奇怪了,出国难道不用过海关吗? 这就是重点,南航居然还在乌鲁木齐才出关,这就是说飞了3个小时下飞机,然后过海关,继续上飞机,真够可以的南航。然后又飞6个小时到伊斯坦布尔。不过这样飞的好处就是不那么累,过会就下来活动活动。 到了伊斯坦布尔机场,还是挺不错,西亚口音的英文还是可以听明白点的,不用出关,在法航自动柜台办理了新的登机牌,然后重新过安检就进来了,还是比较方便的,之前还想着土耳其不是申根,会不会有问题,后来看到土耳其可以办理落地和电子签证,所以就不管了。伊斯坦布尔机场像个大市场,什么都有,吃的喝的看的啥都有,虽然是这里的午夜了,可不像乌鲁木齐机场就我们一个航班的人那么冷清。 换登机牌也很顺利,直接自助机器就可以搞定,居然还有简体和繁体中文,为了防止麻烦,简体中文和繁体中文上面都没放国企,而其他语言却都有。 IMAG0741 而且这边机场居然还能使用4种货币,土币,欧元,美金还有一个没看懂。在这里我们吃上了北京带的稻香村点心。 IMG_3714 抓紧休息吧,其实我自己是根本休息不好,真羡慕那些神经大条的人,居然能在机场睡那么香,他们不怕被偷,虽然我看上面都是摄像头。可我也睡不着。   重新登记了,土官还是很敬业的,问你从哪里来,去哪里,待多久,还TMD用显微镜看签证,难道现在签证防伪那么好? 那为啥我们的边防不这样检查呀。   坐上了梦想的法航,想感受一下高大上的航空公司,结果发现跟南航一样,不过人家的开机前的安全示范还是很到位的,不像内地现在就是看片了,基本很少示范的了。   想着这个机上总得吃点法国特产啥的吧,结果来了个法国硬面包,土鳖本来觉得是被法国人坑了,后来到了巴黎才发现这边人都吃这种硬面包,怪不得要养那么多鸽子呢,这每天产生的面包屑够养活鸽子的了。   下了戴高乐机场(CDG), 出了海关等行李,结果等了半天行李一直没出来,看着旁边几个都是我们一个航班的,所以一群人就去找机场了,也不知道他们几个法国嘎吱嘎吱说了啥,然后客服人员一顿电话狂打,最后告诉我们等10分钟,结果来了2个箱子,一看不是我们的,又等半天没箱子出来了,又找客服去了,又是一顿电话狂打,告知我们行李知道在哪里了,但是要等很长时间,如果我们着急就让我们告知我们的住的地,然后today(球子跟人研究了半天two day还是today,一个老美看不下去了,说this day, 2个傻冒就都明白了)送我们的住处。 球子说就法国人这办事水平,说今天送谁知道能不能送到呢,而且就算送来的是不是对呢,所以2人就继续等吧,这次总算是等来了,可给我们翻译的老美的行李还没来,不管了,我们先走了。   花了将近20个小时终于到了巴黎!!!

限北京城区,有过饲养宠物经历,能给狗狗上户口和按时接种疫苗。   狗狗父母介绍: 母亲是比熊(这是我们家的),父亲是边境牧羊犬。   下面这只叫多纳,最像她妈了,性格和样子都比较像的。 多纳   下面这只像爸爸,叫熊猫,虎头虎脑。 熊猫   下面这个是最最小的,也最爱卖萌的馅饼 馅饼

想着火车要19:33分才开呢,我司到北京站才4站公交车,1个小时无论怎么慢也能按时到吧。 工体车站没多久来了个673上了,很快就到了第一站东大桥北,花了点时间过了东大桥,大家也知道,这个东大桥比较奇特,所以慢也正常,我比较好奇巴黎凯旋门周边12个方向都有马路,这还不都得堵死,这东大桥5个方向就这样了。 过了东大桥就发现不对劲啊,怎么半天都不动啊,这还都没到芳草地呢,看着手机时间也就18:42呢,自我安慰下应该还来得及。 这个时候有个外国姑娘要吵着下车去芳草地了,可司机就是不开门。理由就是公交车没有到站呢,不能开门。时间一点点过了,46分。。48分。。这个路终于开始挪一点了,到了19点02分的公交车终于快挪到了一个站,但是不是这个线路的站,不过司机还是开了门,让着急的都下车了。 这个时候我犹豫了一下,是继续坐这个该死的公交车还是换地铁。 因为换地铁未必能赶上, 先要走到东大桥地铁站,到朝阳门换二号线,然后就是建国门和北京站,共3站。理论上一站是3分钟左右,那就是9分钟,但是换乘这个线路没有走过,不知道多远,要是都跟西直门那样的就完蛋了。还有加上等6号线和二号线的时间。算起来应该也差不多。 于是,马上就下车了,拉着行李箱一阵跑,可还是碰到了倒霉的红灯,等啊等的,又是2分钟过去了,都19点06分了进了地铁站,又SB一样还要安检,还好人不是很多。08分到达了地下等地铁,显示还有3分钟,妈的上车就是11分了,终于没有晚点,2分多钟就到了朝阳门了。开始漫长的换乘了,一直沿着导向牌快走,一阵电梯的上上下下的,大概换乘花了5分钟。拉着行李在二号线上头,看见下面地铁正好在,一阵猛跑下楼,这个时候地铁“嘀嘀嘀”的鸣叫着要关门了,一顿猛冲,结果跟人撞了个满怀,眼见着车门关上了。 这个时候已经是16分了,显示下一班车3分钟内进站。同样还好没有晚点。上了地铁,立刻从包里把身份证拿出来了。然后这个时候就盘算着要不要去车站换票还是直接拿着身份证进站。 打定主意就直接拿着身份证和手机进站了,不换票了。 下了二号线刚好是21分,离停止检票还有7分钟,应该来得及。 火速拿着行李出北京站大概又花了1分30秒吧,刚出地铁口,瞄了一下检票口,一下子傻了,怎么那么多人排队,然后再扫描一遍发现有个专门站台票的检票队伍没啥人,立刻拿着行李跟人说我赶时间,让我就这样进去吧,当然也拿着身份证和手机订票信息,工作人员还好心提醒我:“可能你上车了人还要你补票。”这个先不管了。 进火车站也得安检,也是一个长队,拿着行李跟人打招呼说快迟到了,插了一个队,终于很快的安检完了,进站了我。还有4分钟时间。 扫视了一下列车信息显示屏,T109居然在二楼中央检票大厅,按以前都是在一楼的3号大厅,中央检票大厅没有去过,没法,拉着行李上吧。 上了二楼发现也有很多检票口,到底哪个? 再看了下显示屏,6号检票口,飞一样的过去了,也是拿着身份证和手机订票信息,也让我顺利的进去了。从楼梯上往下看,车还在呢。还好啊。 拿着行李往下跑吧,12车我来了。车厢门口检查的时候终于不再担心了。等我放好行李,好好缓下心情后,火车开了。 真TMD太险了,之前有过一次没赶上火车的事情发生过了,当然那是在某人英明的带领下才导致的。不过那也成就了我第一次坐飞机的情况。 下了上海站了,特地问了列车员下车检票怎么办,人说你就拿着身份证和订票信息就可以出站了,不过还是碰到了各种麻烦,不能直接刷身份证,火车站各种后台系统查询的结果还都不一样,不过这个时候我是一点都不担心了,花了点时间还是顺利出站了。

要说看球那还是读小学的时候,记得那时候是美国世界杯。 决赛是巴西跟意大利,比赛过程还是比较沉闷的,最后是点球决战的,那巴乔的背影还是深深印在我的脑海里了。结果那天上课还迟到了,这场比赛是老爸跟我一起看完的。虽然当中说了什么基本都忘记了,但是还是比较幸福的。现在你让我陪孩子看世界杯,估计难了。 今天早上荷兰5:1痛斩西班牙,我一直是荷兰球迷,可已经没有了任何激情去高兴了。就跟灌篮高手里铁男对三井说的:“别了,运动男孩。”,当然电视里可不是指我这个意思。 从一个可以给人做规则培训,比如越位到战术讨论的真球迷彻底沦为了伪球迷了。更不会半夜爬起来看的了。 现在重要比赛都是看重播,但是基本都是在关闭信息来源的基础上当成直播去看。 94世界杯后来是97年遗憾的中国队了, 我记得10强赛还是8强赛来着,然后第一场是中国主场跟伊朗,那天刚好是要去我干妈家吃饭,所以看了上半场就匆匆从家走了,上半场记得还是2:0的,中国队领先,有一球是范大将军进的。 结果等在干妈家吃完饭再开电视机就2:4落后了,妈的早知道我就一直开着自己家的电视机了。 于是98年给我的记忆基本就是罗纳尔多突然在决赛阳痿了,而法国突然冒出了齐丹,特雷泽盖和一个2个字的二逼前锋,名字忘记了,还有他们的教练貌似是星占术专家,这东西好像在整个欧洲都有市场的。 另外就是荷兰队博格坎普的绝杀,这个实在是印象太深刻了。 当然98年最火的还是那首主题曲“o lei, o lei, o lei”, 不记得歌名,只知道这一段,又暴露了我音盲本色。 02年世界杯,特地还买了球迷衫在比赛前。这衣服现在还能穿呢。但是给我最大感想的是“运气真TMD重要”。要不是龙哥这NB的抽签结果,中国队要进入世界杯估计还得等50年。 进入世界杯的那场是主场跟科威特还是卡塔尔还是阿联酋来着,反正是3个字的国家,进球的是祁宏同学,我居然连怎么进的都给忘记了。 最终小胜对手进入了世界杯。 世界杯前中国足协的目标是赢一场,进一球,平一场。然后抽签后还挺高兴,跟巴西,土耳其和中美洲一支球队一组。 赢就是指赢中美洲的哥们,平就是平土耳其,对巴西连中国足协这样不要脸的也没敢说平和赢,只说小输。 结果第一场就被人斩落马下,貌似是孙继海很快受伤下场,杨晨和谁还中了一个门柱。很快足协之前指定的目标成了一个大笑话。但是那时候最高兴的就是每天跟同学各种热烈的讨论,买各种足球报纸,那段时间本来周报也都成了日报。 不过足协的笑话还是因为这届土耳其真的很强,都进了4强了。 但是这届世界杯也让全世界看到韩国人多么的不要脸,什么草皮上撒水啊,反正怎么不适应怎么来,于是有了韩国跟意大利经典一站,我甚至忘记了这届世界杯是巴西跟谁踢的,只记得巴西淘汰了土耳其进入了决赛。 而06年世界杯是在哪里踢的都忘记了,而10年要不是前2天90后同事提醒也都忘记了,只知道最后决赛是西班牙对荷兰,反正那时候大家对荷兰一顿扁,确实那届的荷兰踢的挺难看的,跟我喜欢的荷兰根本不是风格来的。 而所有的看球生涯就是我的整个学生时代,别了我们的青春岁月。

注:本文是翻译自http://docs.docker.io/reference/run/,版权归原作者所有,没记错应该是apache协议。翻译本文的目的对于我仅仅是为了对于docker命令行更熟悉一点。因为我看英文文档一般都不够仔细思考,翻译只是为了督促自己多点思考,这里会有很多语法错误或者理解错误,所以英文好的尽量看原文。 docker是运行在一个独立的隔离的进程中的。当操作者执行docker run, 它将开启一个拥有独立的文件系统,独立的网络和独立的进程树的进程。Image是一个包含了默认相关的二进制文件的运行,网络会进行映射以及更多的内容。但是docker run给操作者最终的控制权从镜像中开启一个容器。这就是为什么docker run比其他docker命令有更多的选项。   实例中所有的都是正在运行的容器,所以这里我们将尝试更多深度的guideline。   General Form 就跟你所见的例子一样,基本的docker run命令是如下的格式: ```c
$ docker run  [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]

types_](http://docs.docker.io/commandline/cli/#cli-options). \[OPTIONS\]的列表被分为2组:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

1. 对于操作者独占性的设定:
1. 前台或者后台运行
2. 容器的定义
3. 网络的设定
4. 容器在CPU和内存中的运行时间
5. 运行特权和LXC配置
2. 在操作者和开发者之间的共享设定,操作者可以覆盖掉开发者在build镜像的时候的默认设置。

同时docker run \[OPTIONS\]给予操作者在整个运行时间内完全的控制,允许他们覆盖所有的由开发者在docker build时候定义的默认设置和几乎所有Docker自身的默认设置。   **操作者独占性的选项** 只有操作者(执行docker run的那个人)才可以设置下列选项.

* 前台和后台
* 后台(-d)
* 前台
* 容器定义
* 容器的名字(-name)
* PID等价
* 网络设定
* 清理删除(-rm)
* 容器运行时的CPU和内存占用
* 特权和LXC配置

**前台和后台** 当你开启一个Docker容器运行时,就必须要先确定容器是否以"detached"模式运行在后台还是默认的在前台运行。 ```c
-d=false:Detached mode:Run container in the background,printnew container id
``` 后台(-d) 在后台模式(-d=true 或者就 -d), 所有的IO必须通过网络连接或者共享卷来执行,因为容器在后台运行的时候就不再监听命令行。有可以通过执行_docker attach_重新连上在后台执行的容器。如果你选择运行一个容器在后台模式,那你就不能使用--rm选项了。 前台 在前台模式(默认-d是不被指定的)。 docker run可以在容器里开启一个进程同时你可以通过console来获得进程的标准输入(stdin),输出(stdout)和标准错误(stderr)。它甚至可以伪装成TTY和传递信号。 所有这些的配置方法如下: ```c
-a=\[\] : Attach to \`\`stdin\`\`, \`\`stdout\`\` and/or \`\`stderr\`\` -t=false : Allocate a pseudo-tty --sig-proxy=true: Proxify all received signal to the process (even in non-tty mode) -i=false : Keep STDIN open even if not attached
``` 如果你没有特别指定 -a 那Docker_[将获取所有(stdin, stdout,stderr)](https://github.com/dotcloud/docker/blob/75a7f4d90cde0295bcfb7213004abce8d4779b75/commands.go#L1797)_。你可以指定这3种标准流中其中一个你想连接替代的: ```c
$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash
``` 对于交互式的进程(如shell)你通常希望指定一个长久的标准输入(stdin),所以你可以同时使用 -i -t 在大部分的交换式的情况。 **容器定义** 名字(-name) 我们可以通过三种方式来定义一个容器

* UUID长定义("f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778")
* UUID短定义("f78375b1c487")
* 名字("evil_ptolemy")

UUID标识是来自于Docker的守护进程,如果你不通过 --name 来分配一个名字给容器,那么守护进程就会产生一个随机的字段名。名字可以成为给容器添加含义一个便利的方式,因为你可以在定义 _[links](http://docs.docker.io/use/working_with_links_names/#working-with-links-names)_ 的时候使用这个名字。这个工作适合给前台和后台容器。 PID等价 为了更自动化,你可以让Docker写入你选择的容器的ID到一个文件中。这就跟一些程序会写入它们的进程ID到到一个文件中(就跟你看到的PID文件一样) ```c
--cidfile="": Write the container ID to the file
``` **网络设定** ```c
--dns=\[\] : Set custom dns servers for the container --net="bridge": Set the Network mode for the container ('bridge': creates a new network stack for the container on the docker bridge, 'none': no networking for this container, 'container:<name|id>': reuses another container network stack), 'host': use the host network stack inside the container --net="bridge" Set the Network mode for the container 'bridge': creates a new network stack for the container on the docker bridge 'none': no networking for this container 'container:<name|id>': reuses another container network stack 'host': use the host network stack inside the contaner
``` 默认,所有的容器都会默认启用网络连接,然后它会跟外部进行连接。操作者可以通过docker run --net none来完全禁止网络连接包括所有进入和出去的网络连接。这样你就只能通过文件或者STDIN/STDOUT来处理IO了。 你的容器默认将使用跟host相同的DNS服务器,除非你通过 --dns 来指定。 支持的网络连接模式:

* none: 在容器内没有网络连接。
* bridge: (默认的)通过桥接到网卡来连接容器。
* host: 使用容器内部的网络
* container: 使用另外一个容器的网络。

Mode: none 通过设置网络连接模式为none,那一个容器将不能访问任何的外部路由。容器将仍旧拥有和启用一个loopback接口在容器内,它没有任何路由到外部访问。 Mode: bridge 通过设置网络连接模式为bridge,那将使用默认的docker网络连接设定。将会在主机上建立一个桥接网卡,通常命名为docker0, 同时会为容器创建一组虚拟网卡。虚拟网卡一边是为了保持与主机的桥接网卡的连接,另一边在容器内部建立一个loopback网卡。容器将为桥接网卡分配一个IP,同时所有的去到容器的网络流量都经过这个桥接网卡。 Mode: host 通过设置网络连接模式为host,那容器将会共享到所有对容器有效的host的网络堆栈和网卡。容器的hostname将跟匹配到主机系统的hostname中。当共享使用主机的网卡堆栈的时候,发布容器的端口和连接跟其他容器将不能运行。 Mode: container 通过设置网络连接模式为container, 一个容器将与其他容器之间共享网络堆栈。其他容器的名字必须以 --net container:n<name|id> 这样的格式提供。   下面这个例子是在一个redis容器中运行redis server并绑定到IP到localhost,然后使用redis-cli通过localhost网卡来连接redis server ```c
$ docker run -d --name redis example/redis --bind 127.0.0.1 $ # use the redis container's network stack to access localhost $ docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1
``` **清理(-rm)** 默认一个容器的文件系统将继续存留就算容器已经退出。这会让debug更简单(因为你可以查看最后的状态),默认也会保留你的数据。但是当你运行一些短暂的前台命令,容器的文件系统就可能越来越大。如果你想要像Docker一样自动清理容器以及在容器退出后自动删除,你可以增加 --rm 标记。 ```c
--rm=false: Automatically remove the container when it exits (incompatible with -d)
``` **容器的CPU和内存占用** 操作者可以调整容器的性能参数: ```c
-m="": Memory limit (format: , where unit = b, k, m or g) -c=0 : CPU shares (relative weight)
``` 操作者可以通过docker run -m来方便的限定容器的内存使用。如果主机支持swap的话,那 -m 内存设定就可以超过物理内存大小。 类似的操作者可以通过 -c 来增加容器的优先级。默认所有容器都运行在相同优先级上,得到相同的比例的CPU周期。但是你可以在docker启动这些容器的时候告诉内核给予更多的cpu分配。 **运行特权和LXC配置** ```c
--privileged=false: Give extended privileges to this container --lxc-conf=\[\]: (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
``` 默认Docker容器是在非特权模式下的。我们不能在一个Docker容器中运行一个Docker守护进程。因为默认一个容器是不能被允许访问任何设备的,但是一个特权的容器是可以允许访问所有设备的(参见[lxc-template.go](https://github.com/dotcloud/docker/blob/master/execdriver/lxc/lxc_template.go)和[cgroups devices](https://www.kernel.org/doc/Documentation/cgroups/devices.txt)) 当操作者执行docker run --privileged,Docker将启用允许访问主机上的所有设备,也会在AppArmor(Linux安全模块)进行设置来允许容器访问主机上的其他进程。 如果Docker守护进程是使用lxc exec-driver(docker -d --exec-driver=lxc)来启动的, 操作者就可以通过一个或者过多--lxc-conf参数来指定LXC的选项。这些参数会覆盖掉来源于lxc-template.go参数设定。 注:在将来一个主机的host守护进程可能不再使用LXC,但实现这些特性配置跟直接使用LXC是类似的对于操作者而言。 **修改Dockerfile镜像的默认设置** 当一个开发者通过Dockerfile来build一个镜像或者他提交的时候的,开发者可以设定很多的默认参数在镜像作为一个容器启动的时候生效。 4个Dockerfile的命令是不能在运行时修改的: FROM, MAINTAINER, RUN 以及 ADD。其他的很多我们都可以通过docker run来进行修改。我们将仔细检查那些设定是开发者可能在Dockerfile内做的以及如何操作可以修改这些设定。

* CMD(默认的命令或选项)
* ENTRYPOINT(在运行时默认哪些命令执行)
* EXPOSE(进入端口)
* ENV(环境变量)
* VOLUME(共享的文件系统)
* USER
* WORKDIR

**CMD(默认的命令或选项)** 在Docker命令行回调可选的command ```c
$ docker run \[OPTIONS\] IMAGE\[:TAG\] \[COMMAND\] \[ARG...\]
``` 这个命令是可选的,因为创建了这个镜像的人可能已经使用Dockerfile CMD 提供了默认的的 COMMAND。因此操作者只需要指定新的 COMMAND 就可以覆盖掉老的 CMD。 如果镜像已经指定了一个ENTRYPOINT,那CMD或者COMMAND将作为ENTRYPOINT的附属参数。 **ENTRYPOINT(在运行时默认哪些命令执行)** ```c
--entrypoint="": Overwrite the default entrypoint set by the image
``` 一个镜像ENTRYPOINT的类似于一个COMMAND,因为它指定了在容器启动时那些程序启动,但是它很难被覆盖掉。ENTRYPOINT给了一个容器它的默认行为和本质,所以你设定的ENTRYPOINT是你能在容器内运行的犹如一个二进制的文件一样拥有完整和默认的选项, 你可以通过COMMAND设置更多的选项。但是有事一些操作者可能希望不再容器内部运行一些程序,所以你可以在运行时通过指定新的ENTRYPOINT来覆盖掉默认的ENTRYPOINT。这里是一个如何运行一个shell在容器已经被设定为了自动运行一些程序除了(/usr/bin/redis-server) ```c
$ docker run -i -t --entrypoint /bin/bash example/redis
``` 或者其他两个例子是如何给ENTRYPOINT设置更多的参数: ```c
$ docker run -i -t --entrypoint /bin/bash example/redis -c ls -l $ docker run -i -t --entrypoint /usr/bin/redis-cli example/redis --help
``` **EXPOSE(进入端口)** Dockerfile没有在网络连接部分提供很多控制,只提供EXPOSE命令来给操作者一个示意哪些进入的端口可能提供服务。下面这个选项会覆盖掉默认Dockerfile的设置: ```c
--expose=\[\]: Expose a port from the container without publishing it to your host -P=false : Publish all exposed ports to the host interfaces -p=\[\] : Publish a container᾿s port to the host (format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort) (use 'docker port' to see the actual mapping) --link="" : Add link to another container (name:alias)
``` 如之前提到的,EXPOSE(和 --expose)使在容器内的端口对于进入的连接是有效的。在容器内部的端口(服务监听的端口)不必跟在容器外部的端口号(用户连接的端口)一致,所以在容器内部你可以是一个HTTP服务监听者80端口(所以你使用EXPOSE 80在Dockerfile中),但是容器外部的端口可能是42800. 通过操作者执行--expose或者开发者定义EXPOSE都可以帮助一个客户端容器到达服务器端容器的内部端口,操作者有三种方法开启服务器端容器通过-P或者-p,或者用--link启动客户端容器。 如果操作者使用-P或者-p那Docker将使主机上映射的端口是可访问的同时端口对于期望到达主机的客户端也都是有效的。我们使用docker port来发现主机端口和容器内部端口的映射。 如果操作者在启动客户端容器的时候使用--link,那客户端容器就可以通过私有网络端口访问映射端口。Docker将客户端容器设置一些环境变量来指明哪个网卡和端口可以使用。   **ENV(环境变量)** 操作者可以通过-e参数来设置容器内的环境变量,设置可以覆盖掉开发者在Dockerfile里使用ENV定义的环境变量: ```c
$ docker run -e "deep=purple" --rm ubuntu /bin/bash -c export declare -x HOME="/" declare -x HOSTNAME="85bc26a0e200" declare -x OLDPWD declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" declare -x PWD="/" declare -x SHLVL="1" declare -x container="lxc" declare -x deep="purple"
``` 类似的操作者可以用-h来制定hostname。 --link name:alias同样可以设置环境变量,使用alias在容器内定义环境变量将给那些连接到这个服务容器一些IP和端口信息。让我们想象一个容器运行着Redis: ```c
# Start the service container, named redis-name $ docker run -d --name redis-name dockerfiles/redis 4241164edf6f5aca5b0e9e4c9eccd899b0b8080c64c0cd26efe02166c73208f3 # The redis-name container exposed port 6379 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4241164edf6f $ dockerfiles/redis:latest /redis-stable/src/re 5 seconds ago Up 4 seconds 6379/tcp redis-name # Note that there are no public ports exposed since we didn᾿t use -p or -P $ docker port 4241164edf6f 6379 2014/01/25 00:55:38 Error: No public port '6379' published for 4241164edf6f
``` 你可以通过 --link 得到Redis容器的映射端口的相关信息.  选择一个构成有效环境变量的作为别名。 ```c
$ docker run --rm --link redis-name:redis_alias --entrypoint /bin/bash dockerfiles/redis -c export declare -x HOME="/" declare -x HOSTNAME="acda7f7b1cdc" declare -x OLDPWD declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" declare -x PWD="/" declare -x REDIS_ALIAS_NAME="/distracted_wright/redis" declare -x REDIS_ALIAS_PORT="tcp://172.17.0.32:6379" declare -x REDIS_ALIAS_PORT_6379_TCP="tcp://172.17.0.32:6379" declare -x REDIS_ALIAS_PORT_6379_TCP_ADDR="172.17.0.32" declare -x REDIS_ALIAS_PORT_6379_TCP_PORT="6379" declare -x REDIS_ALIAS_PORT_6379_TCP_PROTO="tcp" declare -x SHLVL="1" declare -x container="lxc"
``` 同时我们使用这些信息从其他容器作为客户端连接过来: ```c
$ docker run -i -t --rm --link redis-name:redis_alias --entrypoint /bin/bash dockerfiles/redis -c '/redis-stable/src/redis-cli -h $REDIS_ALIAS_PORT_6379_TCP_ADDR -p $REDIS_ALIAS_PORT_6379_TCP_PORT' 172.17.0.32:6379>
``` Docker将映射一个私有IP成为一个已连接的容器的别名,这是通过修改/etc/hosts来实现的。我们通过这个机制就可以使用别名来与一个以连接的容器进行通信。 ```c
$ docker run -d --name servicename busybox sleep 30 $ docker run -i -t --link servicename:servicealias busybox ping -c 1 servicealias
```   **卷(共享的文件系统)** ```c
-v=\[\]: Create a bind mount with: \[host-dir\]:\[container-dir\]:\[rw|ro\]. If "container-dir" is missing, then docker creates a new volume. --volumes-from="": Mount all volumes from the given container(s)
``` volumes 命令足够复杂到它拥有自己的文档[_Share Directories via Volumes_](http://docs.docker.io/use/working_with_volumes/#volume-def). 一个开发者可以定义一个或者多个卷的关联在一个镜像中, 但是只有操作者可以给予一个容器访问另外一个容器的权限(或一个容器访问在主机上挂载的卷)   **用户** 容器默认的用户是root(id=0), 但是如果开发者创建了额外的用户,那些用户也可以访问。开发者可以设置一个默认用户来运行第一个进程通过Dockerfile USER 命令,但是操作者可以覆盖它: ```c
-u="": Username or UID
```   **工作目录 ** 一个容器内的默认工作目录是根目录(/), 但是开发者可以设定一个不同的默认目录通过Dockerfile WORKDIR 命令设置。 操作者同样也可以覆盖掉这个: ```c
-w="": Working directory inside the container

上周公司做了一个培训,是讲团结协作的,但是更高一个层次其实是整体观。

今天大猫说IDC迁移的事情,也是一个整体观。很多搞技术的同学很容易专注于技术上,而忽略了你只是集体中的一部分,而你所做的只是让公司这个组织里的一部分。     在技术中,我们很容易发现某个模块跟其他模块之间的关系,也知道一个模块出现了问题,会导致与它相连的其他模块也会出现问题。 往更上一层来想,其实运维是技术部的一环,而整个技术部又是公司组织里的一部分,所以当你跟技术部其他同事谈的时候,你是代表了运维组,而当你跟其他比如HR这样的部门谈的时候,你又是代表着技术部的形象。而你跟供应商谈的时候又代表着你的公司,当你出国的时候又是代表着中国。   所以人还是那个人,但是在不同的情形又是不同的一个角色,而并不是说你的角色是一成不变的。就跟电脑CPU一样,总是在上下文切换干不同的事情,而且还要调度好,不然一件事情占用过多的时间,当然也有可以绑定CPU只干一件事情的。这个世界也必定有人只专注于某一件事情的,可这些毕竟都是小部分。   在工作中就得考虑每件事情你所处的位置。 当然我做的还是太烂了,以至于老是被骂啊! 其实很多非技术的同事基本很能搞清楚,难道我们搞技术的都太木纳了?   团队协作说起来容易,但是出现利益冲突的时候就比较难协作好了,毕竟人的本性是自私的,安-兰德还写过一本书叫《自私的德性》。比较好说通的是当最终集体得到的利益远远大于个人的时候,大家一般都会暂时放弃一些个人的。   不说下去了,下面就没底了。 具体可以看胡适的一篇散文《容忍和自由》。

  原文链接: http://steveltn.me/blog/2014/03/15/deploy-rails-applications-using-docker 原作者:Weiyan Shao  

什么是docker?

  Docker是一个用来打包,装载和运行应用程序的一个轻量级容器的开源项目。它的工作方式非常像虚拟机,包裹所有的东西(文件系统,进程管理,环境变量等)在一个容器内。跟虚拟机有所不同,它是使用LXC(Linux kernel container)来替代虚拟层。 LXC没有自己的内核,但是与主机和其他容器一起共享Linux内核的。 基于LXC,因此Docker是非常轻量级的,因此在运行应用程序的时候几乎没有性能损失。 Docker同样提供了聪明的方法去管理你的images镜像。通过Dockerfile和自己的缓存机制,任何人都可以容易重新发布一个更新过的镜像而不用重新传输大量的数据。  

为什么是Docker?

  因为你从来都不知道你的应用程序能否在服务器上正常运行,就算你在本地已经测试和正常运行过了。那是因为服务器上的环境跟你的本地并非完全一致。RVM的设置,ruby和gem的版本差异。如果我们在发布前进行本地测试的时候,我们就已经确认如果在本地正常运行那它也能在服务器上正常运行,那我们会节省一些在服务器上debug错误的时间。 对于巨量的发布,使用虚拟机镜像是相对比较容易的。你可以在几分钟内创建一个虚拟机实例和应用你的镜像让它进行工作。除了便利性,它也有如下一些问题:

  1. 如果你只做了一个很小的更新可不得不提交一个完整的新镜像
  2. 有很多的性能损失。
  3. 你的应用程序可能运行在一个虚拟环境的VPS上,所以你不能运行一个虚拟机在已有的虚拟环境之上。
阅读全文 »

网络的秘密 现代网络的秘密基本就是tcp/ip的秘密。解开这个秘密最重要的钥匙是steven写的《tcp/ip 详解的卷一,卷二》,下面这个就是看这个书的一些总结吧。 要了解tcp/ip那首先要了解一些基本概念。 MTU: 最大传输单元,这个就是指明了一次最多传输多少bytes的数据。这个一般都是1500. MSS: 最大报文段大小,这个指明了每次传输segment的大小,这个一般是1460. 之前一直没弄明白MTU和MSS之前的区别,后来看书才突然想明白了,MTU是2层的,而MSS是4层的。 所以为什么MSS定下的大小是1460, 就是1500-20(IP包头)- 20(TCP包头)的结果。 win: 也就是窗口大小,这个就是指明了本地可以接收多少数据大小再返回一个ACK确认。 RTT: 往返传输时间, 就是网络中src和dst之间的往返的延时,这个时间的长短跟win的大小是有关系的。 RTO: 重传超时, 也就是计时器计算多久没有收到返回后再次进行发送。 以上是一些基础概念,下面是一些基本网络流程。 先抄一个tcp状态迁移图吧,然后再稍微解释一下:   tcp TCP的三次握手,准确的说应该是TCP建立连接的3次握手。 这个就是一个互相确认的过程。 TCP的4次握手, 准确的说应该是TCP关闭连接的4次握手。 很多人会比较困惑,为什么建立连接是3次,而关闭要4次呢。 这个是因为大部分TCP实现都是全双工的, 也就是数据包是相互传递的。 所以当要释放的时候要2边都要确认没有数据传送了。所以我们看到系统中一些TIME_OUT就不用太大惊小怪,对于有些公网服务,有这种TIME_OUT是非常正常的。 所以在建立连接的时候我们有client和server之分,而关闭连接的时候是没有server和client之分的。 认识一些TCP的标志位: SYN, ACK 这2个我们经常碰到的,这2个后面带的值一般都是从0开始累加上去的。 PSH: 就是说将收到的报文段尽快转给应用层进行处理。 RST: 这个在天朝访问辽国的时候会经常出现的一个状态,重建连接。

aryaka是一家做互联网加速的互联网公司。我们大猫同学想要用他们的加速服务来进行互联网服务。 到底要多快呢,大猫同学设想的是中国到美国在100ms以内。这个有可能吗? 通过公开的资料,中国到到美国有2条海底光缆: 分别为TPE和CUCN,其中TPE全长17700KM, CUCN是36800KM。 参考资料: http://en.wikipedia.org/wiki/TPE_(cable_system) http://en.wikipedia.org/wiki/CUCN_(cable_system)   同时我们知道,tcp通讯基本都是全双工进行的,所以RTT都是是2倍的物理距离。 同时物理原理告诉我们,光速每秒是30万公里/小时。由此我们就可以计算中国到美国最快可以到多久之内完成呢。 17700(TPE)/300000(光速) * 2 = 118ms 由此可知要实现中美之间80ms以内传输是完全不行的,除非你认为塞班和关岛也算美国本土。   因此我在测试之前我就知道这个要求是根本无法实现的。 但是为了想看看aryaka的一个服务,于是还是稍微测试了一下,并用tcpdump做了记录。   要使用aryaka的服务必须先跟对方的pop点进行连接,连接了这个pop点后就可以直接通过aryaka内部的路由到达我们洛杉矶的AWS服务器上。   但是连接了之后发现,ping的延迟还是在200ms左右,于是问了aryaka的工作人员,他们说他们对tcp的连接做了加速,于是就用tcp进行测试,发现连接真的很快啊,几ms就已经建立完成了,可实际要传输数据的时候还是在200ms左右。   tcpdump   而从tcpdump里的数据可以看到,实际的IP并不是我发起方的一个IP,而是他们在美国的一个POP点的IP。 于是我基本可以推测出来,所谓的tcp层连接快其实是一个假象。   推测出来的结果来就是: 1. aryaka内部网络是始终保持连接的。 2. 你一旦连接了aryaka的一个pop点后,这个pop点会立刻进行返回,并告诉你连接已完成,对对端也是pop点跟对端之间连接完成就认为是连接完成。 3. 实际数据传输的时候还是走的aryaka的内部网络,这个说实话还是很快的,从北京去往洛杉矶下载可以在450KB/s, 而不走他们的网络是70KB/s。 4.  断开连接同样也是跟pop点断开就认为是全部断开了   不过测试下来感觉aryaka比较适合对于传送数据要求稳定的要求比较好,毕竟比直接介入MPLS会节省很多费用啊。不过我也没有问过aryaka的价格结算方式。

  现在欧洲国家不景气,所以都希望吸引中国人过去,但是他们又害怕你留在那里打黑工。 说如何办理吧,有了上次签西班牙的过程,这次就方便多了。法国旅游签证貌似中智都代理了,中智这中介费挣的,所以还能在芳草地这样的地方租了一层,这都是广大百姓的钱啊。 而且现在法国签证48小时就出结果了,基本3天就可以到你手上了。 首先登录 https://cn.tlscontact.com/cnBJS2fr/login.php?l=zh_CN 进行注册和预约。 需要准备的材料都大同小异,可老婆大人就怕不过,所以弄了一堆。 2寸照片2张,但是最后又给回了一张,实际就用了一张,为了这个某些人还花了35元照了个像。 公司准假证明,网上有现成的模板,就是注意要公司盖章和人事签字。 护照和复印件 户口本和复印件 资产证明:银行流水,定期存款,房本等等,反正让他们相信你不稀罕在那打工就成。 往返机票订单 住宿酒店订单 行程单 其他参照网站说明吧。 然后就填写《短期申根签证申请表》和《短期申根签证申请补充问题》 接着就提前90天预约就行了。 到了芳草地,这地真不错,以前还真不知道东大桥附近还有这么高大上的地方呢。排队,提交材料,付钱,打印发票,走人,要不了一个小时的。 签证费500多,中介费200多,真你妈够黑的。 3天后就拿到签证了,真快,比以前那个啥啥啥国家快多了。 拿到签证才是自助游的第一步呢,后面定酒店,火车,住宿,租车,拼团,参观哪些景点,这些都让球球去弄吧,我负责付款就成。 飞机票: 看来看去还是kuxun上比较便宜,老东家qunar自从收编那些小破网站后明显涨价了。 住宿: 闲booking上太贵的话就上airbnb上订吧,booking是各种旅馆和宾馆,airbnb是民宿(基本就1-2个房间的)。booking上所谓的旅馆也就是大一点的民宿而已。 买火车票: 你总不能就在巴黎待着啊。直接上欧铁中文网站买的那是有钱人。自由行的就上下面2个上买吧。 https://www.idtgv.com/en/reserver http://www.sncf.com/en/passengers 哦,说一句很多人都说付不了款,记得把自己信用卡开通3D验证。上次用了兴业的没有问题,就是货币转换费收的我肉疼,所以这次直接中行全币种卡,没有货币转换费,付款都没有问题的。 在巴黎基本坐地铁就行了,下面这个就是英文版巴黎地铁查询,貌似比天朝的要高大上很多啊。只是这个没有跟google map整合起来,导致没法在google进行搜索。 http://www.ratp.fr/plan-interactif/carteidf.php?lang=uk 法国南部就基本是靠火车是自驾了,看了很多qyer的分享公交车还是不靠谱啊。 看来今年车本必须出啊,不然以后怎么去德国和美国以及澳洲啊。

0%