关于爱情的几个观点

小故事1

一对情侣,女方让男方春节回家买高铁,男方家里听到了非常不开心,觉得委屈儿子了,果断给儿子买了贵1k多的机票,女方知道又很不开心,因为有一种被对方父母乱想的感觉,然后弄得两家人不是很愉快。

比较常见的家庭矛盾,两方家庭条件不同,三观也有差异的。怎么说呢,我是觉得这种事儿,强求不了,既不能让自己按照对方父辈的想法去思考,又不能让对方父辈在自己的角度思考。

我是外人的角度看这个事,其实就是在对方父母面前好好听话,他们说啥就是啥,盲从也好愚孝也好,我觉得能避免就避免。然后脱开父母,立马把情绪转移给对方就好了,凶死对方,但不让对方爸妈知道,我觉得这就是一个比较好的相处模式吧。

小故事2

男方追女方,男方觉得女方虚荣,这种想法对吗,适合在一起吗。

我从来不信说能找到一个人脑海想象中完美无缺的,和自己完美匹配的对象,就是举个栗子,我喜欢一个女生,我觉得她很幼稚,我会好好维护她的幼稚;我觉得她虚荣,那就维护好这份虚荣心就好。

当然承担不起是另外一回事,哈哈哈哈哈哈。

股票投资计划

  1. 试水,股票投资只占所有资金的5%~10%,可接受本金亏损60%期待年化20%,如果在非牛非熊的环境下,这套方法盈利能够保持20%的盈利,明年把股市资金比例调整到20%;
  2. 纯赌博 纯赌博 纯赌博!对散户来说,股票是一个纯粹的赌博,可以看成每只股票每天是一个独立的涨跌随机事件,符合什么分布并不重要,也没有人知道。
  3. 股票就是为了短期盈利,在不崩盘退市的情况下,任何股票总会有反弹和下滑,除了抓短期涨跌就是等大行情。
  4. 虽然是为了短期盈利,即使某一只股票跌了也不要有着急的心态,要看所有资金的月收益,季度收益和年收益,莫盯着短处的跌看,即使涨不回来,也只是总资金的5%~10%投资的某几只股票而已,心态万要端平!
  5. 亏损切记不要补仓,散户股票本质是赌博,有钱与其补仓,不如买另一只股票,因为补仓相当于期待的还是原来那个随机的事件,而另买相当于期待两个独立事件,第二天遇到涨的概率必然要大些。
  6. 股票的选择,现在的想法是做一个软件,输入已购买的股票,然后在庞大的股票数量里,随机一只和原有股票毫不相关的板块里的股票,这只股票盘子不能太小,至少大几千万。
  7. 卖出时机,其实切记不补仓就行,挣2~3个点就能走,没必要盯盘,好好工作好好生活。

自律

单纯坚持去做一件事并不是自律,自律是对成功的渴望能够战胜疲劳和诱惑的一种自我驱动。自律的内在核心并不是坚持去做某一件事,而是心有所期一个不移的目标,并不在乎是要如何艰辛的翻越某座山,而只在乎我偏要去到那座山,无论代价是什么。

自律不是一种热血行为,一时的热血和冲动也绝无坚持的可能性。所以我告诉自己2020年我要变的自律,其实是一个伪命题,真实的自律一定不单单是一个执行计划。

自律是反人性,所对抗的是惰性,是诱惑,而热血是一个自我欺骗行为,似乎一时热血能够缓解过去没有做“正确的事情”的一种焦虑情绪。真正的自律实际上是当你身体不想继续的时候,我的大脑让我要继续,例如深夜下班经过好吃的牛杂店,十里飘香的炒面铺,我口水直流,心里所想皆是食之食之食之… 但是这个时候,有另外一个声音,并不是我做过一个不能吃夜宵的计划,而是我一定要瘦下去的愿望,足够强烈,一番斗争之后,每次都能够抵抗住这样的诱惑,包括抵抗住对健身疲倦的惰性,这才是自律。

不能逼迫你的大脑去做他不愿意的事,就像你剥夺一个七八岁的小孩让他们去学习,这是反人性的。要做的事情是,告诉他们为什么要去学习,让他们理解学习,让他们把学习作为目标。

但这远不够,我们永远知道什么是正确的,什么是应当做什么是应当拒绝的,真正的自律是对某个结局某个目标的渴望非常之大,并不是一时想要达到,而是清晰地知道,这个目标可能要花几个月,几年的时间去实现,这期间在别人眼里你是在坚持做一些事情,但在自己眼里只是在实现一个非要不可的目标而已。

这才是自律。

一个小的通用缓存库

背景

(使用python语言)

非常常见的一个应用场景, 经常会有这样的场景,某个服务需要大量读取db,为了缓解db的压力,可以在服务上做一些db的缓存,降低db的压力,提高服务的效率。

重复写多了就想独立成一个小模块,只需要简单的接口就能在进程上提供缓存命中的库,而且似乎还能提供一种更加通用的功能。遇到了这个场景不止一次,之前每次在这个场景下,我都是重复的用两个dict,一个存上次访问时间,一个存上次访问到的数据,然后是在下次访问的时候判断是否需要重新拉取db。

这里有一个细节是从来不会主动删除数据,在访问的数据量不大的情况下,我们的业务是能够承受这种级别的内存缓存数据的,之前就没想那么多。

但这次的工作场景是存不下的,必须要主动删除不必要的缓存数据,就想做一个通用一点的接口。

接口

缓存系统内存空间是有上限的,需要主动过期不必要的缓存,常见的选择策略有下面几种

  • Least-Recently-Used(LRU)
  • Least-Frequently-Used(LFU)
  • First in First Out(FIFO)

提供一个类作为缓存系统,缓存数据为基础缓存存储单元,本身的数据结构:

  1. 外部定时器回调(也可以用单次访问来做触发)
  2. 基础缓存存储单元缓存最大数量
  3. 缓存数据的dict
  4. 过期策略(LRU,LFU)
  5. 缓存过期时间(即使一直在内存中,也需要重新读db)
  6. 使用者要提供缓存数据未命中时,数据生成函数(db访问函数)
  7. 缓存过期回调函数

基础缓存存储单元本身包含:

  1. 缓存数据的key
  2. 缓存数据本身
  3. 缓存上次访问时间
  4. 缓存上次刷新时间
  5. 过期回调函数

需要提供的接口:

  1. 缓存删除函数:根据策略,将缓存删除到只剩最大数量;
  2. 访问缓存数据(触发缓存删除函数,并且不存在则触发生成函数);
  3. 新增缓存数据的函数,这个函数会作为数据生成函数的参数提供;

End。

内心不够坚定这件事情

注意到一个很细节的心理,股票涨了,即使理智告诉我不是这样,但心理总有一个声音让我觉得是自己很聪明很果决。这会让自己非常自信,觉得自己无比理智,风吹过耳边都会觉得自己非常帅气。

但股票这件事情本身就是一场赌局,我这样普通的散户在这里做的决定,和用钱向上抛一枚硬币没有两样。所谓的思考,无非就是因为之前硬币反面次数太多,我相信下一次是正面,美其名曰短期经济规律,虽然确实存在,但是依然是赌博。我为什么会因为在大的随机分布里的一个看似理智实则随机的选择而认为自己聪明呢。

很早就注意到了自己这个心理,但真的注意到内心不够坚定这件事情,还是是在选中的一支股票从5%的盈利变成亏损5%的时候,亏钱心疼钱的心态是没有的,只有一种莫名其妙的自卑心理…

(黑人问号???)

为什么跌了会觉得自己不够聪明呢?为什么涨了会觉得非常自信呢?其实每天就是很小比例的上下波动,但真实的会让我对自己的看法在一定程度上左右摇摆,还是内心不够坚定吧。

他解自我感知自律

写自一个极度饥饿,但是极度自我感知自律的晚上。不是很确定这种自我感知是从哪里来的,下班没比之前早太多,肚子极度饥饿,感觉核心还是,路过三五家好吃的店子,肚子大叫了两三声,大脑制止住了,由此产生了一种自信?这种自信让我回家之后把之前告诉自己以后有时间收拾的东西都收拾了,猫不回去的地方,我平常少触碰的死角。

就是这种自我认为自律,应该是诞生自极小的自控力的成功实施。比如我今天明明知道自己想吃,又饥饿又需要能量,但大脑告诉自己不能吃,并且控制住了,就产生了这种自我感知自律。但这种忽然的想做事的冲动又有一点像还债和亏欠,像about love里面男主被初恋女友邀请一夜情,男主拒绝了之后像女主求婚;像抖音看到的一个不知名的短片,男主遇到初恋并帮忙搬东西,然后回家给老婆买了一束花。

就是还挺有意思的,这种能够投入进去,去做之前不太愿意做的事情的状态,感觉自律爆棚,自信心爆棚,注意力集中;同时又有一点点像大脑为拒绝身体的欲望而做出的一点点补偿,有没有。

减肥路上还有很多荆棘,要克服太多次的肠胃的饥饿感,身体对能量的渴求欲望,以及渴求美食的贪婪。请务必继续加油!!

20年代的期望

  1. 体脂率降低到18%以下
  2. 自律有点大, 为了恢复我细致的皮肤, 早睡吧,全年2/3的时间能够23:30之前睡;
  3. 成为更有自我的人,坚持每天读几页书,不在多,一定要相信,趣闻、文字没用只是看的不够;
  4. 成为更有自我的人,坚持输出一些文字,技术上的思考也好,生活中的小趣闻、想法和点子也好,就是微博上感兴趣的话题也可以写一下;
  5. 工作效率再提高一些,早些下班,多一些生活的时间
  6. 成为更有自我的人,保持思考和创新,技术上每个月要有一些进步。

关于“成功 ” 这件事,我现在的状态是属于不刻意去追求,因为太缥缈了,活了二十几年,总是在别人的期望里成长,学生时代我的确收获颇多,毕竟目标单一所有人也没有额外的期望。但是到如今,外界的期望多种多样,我没法应付全,我也不想去迎合别人的期望和标准。今年才发现心态总是有一些失衡,思考太少自我太少,并不知道我是谁以及我想要什么。所以我想我自己有一套自己的“成功”的标准,标准应该尽量的关乎自我,和社会保持必要的独立性,不是不融入社会,而是融入社会但保持独立性。其实都不应该称之为成功,而是应该是一种自我追求和自我实现的几个目标,只是在现在这个大环境里,似乎自我追求和自我实现的终点就是“成功”,所以称为成功的标准吧。

说的有点虚,其实就是不只想以挣钱为目标,甚至不以挣钱为目标,毕竟真的挣钱是一件非常非常看运气的事情,我会努力工作努力思考和等待机会,但是我不应该去追求一件非常渺茫的事情。

现在看来,健康的身体,自律的习惯,独立思考的心性,良好的心理建设,自信的强大的内心,才是我所需求的。外界的世界太丰富了,时常让我误以为我自己也是一个丰富多彩的人,但是只是习惯性地把看到的观点转发过来转述过去,并没有太多自己的内在和灵魂,或者说自己的灵魂是寄托在外界的空虚的“信息” 里的 ,脱离于这些信息,自己并没有什么坚持去做,去更爱自己更在乎自己的事情觉得真正重要的东西。

今年一直在思考,人生、未来、自我这些事情,其实没有完全想明白,甚至觉得自己很陌生,有一种住在身体里的小人,有一天回家发现好像不是自家的房子,甚至觉得很陌生一样。

我想今年就从健身和自律开始去尝试装修这座房子,2020年就叫自律元年吧。并不简单的认为写一篇文章立一个flag就能做到的,每天的繁忙和平凡里坚持下来并不容易,但我坚持了撸铁三个月了,胸肌明显增大,腹肌也能看的见了,只要再坚持4个三个月就是下一年了,加油吧!

读书笔记之——Docker基础与实战(基础篇)

之前读过《第一本Docker书》,所以对docker的使用和概念都是大概清楚的,只是没有实际搭建使用过,这次读本书会配合把本博客使用docker部署,但这本书还是看的很快,笔记做的不一定易懂,不过也没想过是为其他人提供(为主)的,毕竟我做笔记主要是为了让自己阅读可以保持一个良好的习惯,增强自己的阅读效果。

因为是实用工具类的书,所以笔记还是会稍微长一点,也会转述很多书上的内容下来。

第一章、Docker

随着互联网的发展,服务器市场快速转向云环境,但大量服务器的购买和配置会很麻烦,于是出现了“不可变基础设施”的概念,指主机OS和服务器运行环境分离,设置一次环境便不用再设置,每次发布软件只需重新生成镜像就好了。

最初出现的是虚拟机,但虚拟机会对硬件虚拟化或半虚拟化,每个运行的软件打包要分别对OS、执行文件库和应用程序打包,软件的镜像会过分的大。于是Docker就出现了,Docker对操作系统而不是硬件进行抽象,更加轻量化,每个软件只需要库和应用程序的抽象,减小了镜像的体积。

Docker最初利用了linux提供的lxc这种系统级虚拟化,它又使用了chroot和cgroups隔离用户空间和硬件空间,从docker0.9版本开始,人们开始开发lxc的替代品libcontainer。

在配置时,可以进行切换,libcontainer表示为native,LXC表示为lxc。

Docker有容器和镜像的概念,镜像就是软件,容器就是一个运行中的镜像,一般开发人员开发好一个软件,然后打包相关的以来成镜像,交付给运维人员,运维人员用docker批量运行容器,大概是这样的一个关系。

Docker另一个非常有特色的地方在于,它使用了类似与git版本管理的方式保存镜像,每次只保存变化的部分,因此每一个更新软件的包都是非常小的。

读后感

和《第一本Docker书》同章节对比了一下,《第一本Docker书》的重点放在docker的介绍以及能干什么,而本书本章的重点放在和虚拟机的对比上,以及docker的优点是什么。

第二章、安装Docker

(略)

第三章、使用Docker

注意:必须总是以root权限运行Docker。

docker的指令都是以

$ docker <command>

运行的,例如docker run, docker push。
在学习基本用法前,先从Docker Hub下载并运行镜像。

Docker通过Docker Hub(https://registry.hub.docker.com)搭建镜像共享生态系统。著名的发行版都可以在这里找到镜像,与镜像相关的所有命令默认都设置可以使用Docker Hub。

1、docker search
使用docker search 命令在Docker Hub中搜索镜像。

[~]$ sudo docker search ubuntu
INDEX       NAME                                        DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/ubuntu                            Ubuntu is a Debian-based Linux operating s...   5013      [OK]       
docker.io   docker.io/ubuntu-upstart                    Upstart is an event-based replacement for ...   68        [OK]       
docker.io   docker.io/rastasheep/ubuntu-sshd            Dockerized SSH service, built on top of of...   47                   [OK]
docker.io   docker.io/consol/ubuntu-xfce-vnc            Ubuntu container with "headless" VNC sessi...   29                   [OK]
docker.io   docker.io/torusware/speedus-ubuntu          Always updated official Ubuntu docker imag...   27                   [OK]
docker.io   docker.io/ubuntu-debootstrap                debootstrap --variant=minbase --components...   27        [OK]       
docker.io   docker.io/ioft/armhf-ubuntu                 [ABR] Ubuntu Docker images for the ARMv7(a...   19                   [OK]
docker.io   docker.io/nickistre/ubuntu-lamp             LAMP server on Ubuntu                           10                   [OK]
docker.io   docker.io/nuagebec/ubuntu                   Simple always updated Ubuntu docker images...   9                    [OK]
docker.io   docker.io/nickistre/ubuntu-lamp-wordpress   LAMP on Ubuntu with wp-cli installed            7                    [OK]
docker.io   docker.io/nimmis/ubuntu                     This is a docker images different LTS vers...   5                    [OK]
docker.io   docker.io/maxexcloo/ubuntu                  Base image built on Ubuntu with init, Supe...   2                    [OK]
docker.io   docker.io/admiringworm/ubuntu               Base ubuntu images based on the official u...   1                    [OK]
docker.io   docker.io/darksheer/ubuntu                  Base Ubuntu Image -- Updated hourly             1                    [OK]
docker.io   docker.io/jordi/ubuntu                      Ubuntu Base Image                               1                    [OK]
docker.io   docker.io/datenbetrieb/ubuntu               custom flavor of the official ubuntu base ...   0                    [OK]
docker.io   docker.io/esycat/ubuntu                     Ubuntu LTS                                      0                    [OK]
docker.io   docker.io/konstruktoid/ubuntu               Ubuntu base image                               0                    [OK]
docker.io   docker.io/labengine/ubuntu                  Images base ubuntu                              0                    [OK]
docker.io   docker.io/lynxtp/ubuntu                     https://github.com/lynxtp/docker-ubuntu         0                    [OK]
docker.io   docker.io/teamrock/ubuntu                   TeamRock's Ubuntu image configured with AW...   0                    [OK]
docker.io   docker.io/ustclug/ubuntu                    ubuntu image for docker with USTC mirror        0                    [OK]
docker.io   docker.io/vcatechnology/ubuntu              A Ubuntu image that is updated daily            0                    [OK]
docker.io   docker.io/webhippie/ubuntu                  Docker images for ubuntu                        0                    [OK]
docker.io   docker.io/widerplan/ubuntu                  Our basic Ubuntu images.                        0                    [OK]

2、docker pull
从Docker Hub拉取镜像:

[~]$ sudo docker pull ubuntu:latest

就成功拉下来了ubuntu linux的镜像,接下来我就能在我的centos上拥有ubuntu的运行环境和库依赖了。
命令格式为:docker pull <镜像名称>:<标签>。标签latest最新版本,也可以是14.04, 12.10。另外镜像名字中可以在’/’之前制定用户名,比如:yylogo/ubuntu就是拉取我上传的ubuntu,官方镜像不会出现用户名。

3、docker images
可以列出本机已经下载的镜像。

[~]$ sudo docker images
[~]$ sudo docker images ubuntu

第一个命令查看本地已经下载的所有镜像,第二个查看镜像名称相同但标签不同的镜像。

4、docker run
创建容器,运行容器。
如前所述,本地已经拥有别人创建的镜像,现在需要使用镜像创建容器,并且将容器运行起来,需要使用的就是docker run命令。
命令格式:docker run <选项> <镜像名称> <要运行的文件>,如:

[~]$ sudo docker run -i -t --name hello ubuntu /bin/bash
root@7db6a454c06e:/#

其中有三个选项分别是-i, -t, –name.
他们的作用分别是:
使用-i(interactive) 选项将容器的STDIN开启,-t(Pseudo-tty)选项告诉docker为容器分配一个伪tty终端,这样新创建的容器才能提供一个交互式shell,若不要运行一个后台服务的容器,则这两个参数是最基本的参数。
这个–name用于指定容器名称。若不指定名称,Docker会自动生成名称并进行指定。
现在已经生成了一个和主机OS完全隔离的空间,可以使用exit退出,因为在ubuntu镜像中直接运行/bin/bash可执行文件,所以退出后容器也会终止(stop)。
7db6a454c06e是docker生成的容器ID。

5、使用ps命令查看容器列表

sudo docker ps # 查看所有正在运行的容器
sudo docker ps -a # 查看所有容器

6、使用start命令启动容器

sudo docker start hello
sudo docker ps

命令格式为:docker start <容器名称>,也可以使用容器ID代替容器名称。

7、使用restart命令重启容器
与重启OS类似,可以重启某个容器。

sudo docker restart hello

命令格式为:docker restart <容器名称>,也可以使用容器ID代替容器名称。

8、使用attach命令连接容器
docker容器启动的时候会按照docker run命令制定的参数来运行,因此启动后会运行一个交互式shell,可以用docker attach重新附着到该容器的会话上,执行:

sudo docker attach hello

但如果运行DB或服务应用程序将无法输入只能看到输出。

9、使用exec命令从外部运行容器内的命令
命令格式为:docker exec <容器名称> <命令 <命令参数> >,可以使用容器ID代替名字,只有在容器运行时本命令可用。

sudo socker exec hello echo "Hello World"

10、使用stop命令终止容器
命令格式为:docker stop <容器名称> 名称可用容器ID替代,效果可以使用docker ps查看。

11、使用rm命令删除容器
命令格式为:docker rm <容器名称> 也可以用容器ID替代,效果可以用docker ps查看。
记得必须使用root权限。

12、使用rmi命令删除镜像(images)
可以删除指定镜像。
命令格式为:docker rmi <镜像名称>:<标签>,也可以用镜像ID替代,效果用docker images查看。
如果不用标签则删除该镜像名称所有标签,如:docker rmi ubuntu。

读后感

和《第一本Docker书》同章节对比了一下,介绍的命令少一些,而且命令讲解上也输给《第一本Docker书》。

另外读到这里,别以为你会docker了,你只是会用docker的基本命令了。

第四章、创建Docker镜像

编写地一个Dockerfile:

[~]$ cd /tmp/
[tmp]$ mkdir example
[tmp]$ cd example/
[example]$ vim Dockerfile
#输入下面这些:
FROM ubuntu:latest
MAINTAINER Foo Bar <foo@bar.com>

RUN apt-get update
RUN apt-get install -y nginx
RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx

VOLUME ["/data", "/etc/nginx/site/enabled", "/var/log/nginx"]

WORKDIR /etc/nginx

CMD ["nginx"]

EXPOSE 80
EXPOSE 433

上述示例基于Ubuntu 创建Docker镜像,且安装nginx服务器。

FROM:指定基于的基础镜像。Docker镜像基于已创建的镜像。
MAINTAINER:维护者信息
RUN:运行shell脚本或命令。
VOLUME:要与主机共享的目录,也可以在docker run命令中使用-v选项进行设置。例如:-v /root/data:/data将主机的/root/data目录连接到Docker容器的/data目录。
CMD:指定容器启动时执行的文件或shell脚本。
WORKDIR:为CMD中设置的可执行文件设置运行目录。
EXPOSE:与主机相连的端口号。

创建镜像的命令是docker build,命令格式:docker build <选项>

sudo docker build --tag hello:0.1 .
sudo docker images #稍等片刻即可以生成镜像文件,显示镜像目录.
sudo docker run --name hello-nginx -d -p 80:80 -v /root/data:/data hello:0.1

最后一行的参数含义如下:
-d 选项在后台运行容器.
-p 80:80 选项将主机的80端口与容器的80端口连接起来,并暴露到外部,接下来使用<主机IP>:80就能访问容器的80端口(http://127.0.0.1:80/)了.
-v 在前面有介绍,将主机的目录映射到容器的目录中去。

第五章、查看Docker

1、使用history查看镜像历史:

sudo docker history hello:0.1

命令格式:docker history <镜像名称>:<标签>,可以用镜像ID代替名称。

2、使用cp命令复制文件
将容器中的目录复制出来

sudo docker cp hello-nginx:/etc/nginx/nginx.conf ./

命令格式:docker cp <容器名称>:<路径> <主机路径>

3、使用commit命令从容器修改中创建镜像
假设hello-nginx容器中的文件内容发生变化,将容器创建为镜像文件。

sudo docker commit -a "Foo Bar <foo@bar.com>" -m "add hello.txt" hello-nginx hello:0.2   # 用docker images查看效果

4、用diff命令检查容器文件的修改

sudo docker diff hello-nginx

命令格式为docker diff <容器名称>,也可以用容器ID替代名称。
其中A是添加的文件,C是修改的文件,D是删除的文件。

5、使用inspect命令查看详细信息
命令格式:docker inspect <容器名称 或 镜像名称> 可以用容器ID或镜像ID替换。

第六章、灵活使用Docker

6.1、搭建Docker私有仓库

docker命令默认使用Docker Hub,下面创建私有仓库服务器。
Docker仓库服务器名为Docker注册(registry)服务器,使用docker push上传,docker pull下载。
将镜像数据存储到本地使用的命令是:

sudo docker pull registry:latest  # 拉取注册服务器镜像
sudo docker run -d -p 5000:5000 --name hello-registry 
    -v /tmp/registry:/tmp/registry 
    registry      # 创建注册服务器容器并运行,运行端口是5000,并且将镜像文件保存在主机的/tmp/registry下

部署好了docker私有仓库如何使用呢?

sudo docker tag hello:0.1 localhost:5000/hello:0.1
sudo docker push localhost:5000/hello:0.1

创建标签的命令格式为:docker tag <镜像名称>:<标签> /<镜像名称>:<标签>
上传镜像的命令格式为:sudo docker push /<镜像名称>:<标签>
在上传之前一定要先新建一个tag, 相当与指定这个镜像是来自某个注册服务器,然后我的理解是,在任何一个命令,镜像名称前面都可以直接加上/。
后面提到了如何使用非本地数据存储如Amazon S3,应该是registry内置Amazon S3的支持,所以在运行时指定相应的环境变量即可。

6.2、连接Docker的容器

Docker创建镜像时,虽然可以把Web服务器,DB都安装在其中,但一般的做法是分别生成镜像。这样生成镜像时经常需要某个镜像的端口不对外暴露,那么会需要连接相邻的容器,比如Web服务器对外暴露端口,并且连接不对外暴露端口的DB,就可以做到良好封装的数据交换。

连接容器时要在docker run命令中使用–link选项,格式为–link <容器名称>:<别名>,之后在这个容器内使用<别名>:<端口号>就能直接连接到所link的那个容器了。

6.3、连接到其他服务器的Docker容器

前面说了,–link可以将统一服务器的多个容器连接在一起,下面介绍使用Ambassador容器链接不同服务器的容器。

如上图,Ambassador容器是运行在两个不同服务器的中间容器,可以在客户端容器和服务端容器不感知的情况下就能跨机器部署容器。
客户端容器连接客户端Ambassador容器,服务端Ambassador容器连接服务端容器,并且服务端Ambassador容器要对外暴露对应的端口。Ambassador容器是这样一个中间容器。

6.4、使用Docker数据卷

Docker一般的数据都是存储在容器内,使用Union File System进行管理,但使用数据卷就有一种插入了一块硬盘一样,将主机某个目录挂在进容器的某个目录下,容器对某目录的操作全部都会落实在主机上,并不会通过Union File System。

可以直接指定-v /data,设置容器内/data目录为数据卷,docker会自动分配一个路径给容器用于数据卷,可用docker inspect查看。
但一般的命令格式为-v <主机目录>:<容器目录>
可以让多个容器共享一个目录。

6.5、使用Docker数据卷容器

数据卷容器是设置数据卷的容器,专门提供数据卷供其他容器共享。从普通容器连接到数据卷容器后即可直接访问数据卷容器内的数据卷目录。

sudo docker run -i -t --name hello-volume -v /root/data:/data ubuntu /bin/bash  #创建数据卷容器
sudo docker run -i -t --volumes-from hello-volume --name hello ubuntu /bin/bash  #普通容器连接数据卷容器

主要在于–volumes-from <数据卷容器>,可以直接使用其它容器的数据卷

6.6、创建Docker基础镜像

一般创建镜像的方法都是基于Docker Hub提供的官方镜像,但docker提供创建基础镜像的命令:docker import,命令格式是docker import <URL或- > <镜像名称>:<标签>
觉得不太重要就不转具体细节上来了。

6.6、在Docker内运行Docker

书上说这是一个实验性质的功能,在最外曾的docker容器创建时加上–privileged,这个选项使得容器内部可以使用主机的所有Linux内核功能。启动了这个容器,这个容器内在创建容器就和正常创建是一样的了。

第七章、详细了解Dockerfile

Dockerfile是比较重要的内容,因为这个是自动化打包和部署所必须要了解的内容。
前面编写过一次Dockerfile,这里介绍一下细节,编写格式为<命令> <形式参数>,#是注释,命令不区分大小写,但一般使用大写字母。Docker会依据Dockerfile文件中的命令顺序依次执行命令,在Dockerfile中,命令总是以FROM开始,没有则无法创建镜像。
此外,命令是独立运行的,例如运行RUN cd /home/hello也不会对后面的命令产生影响。
创建镜像时,要在Dockerfile所在的目录使用docker build命令,使用–tag或-t选项设置镜像名称,若想上传到Docker Hub在/之前添加用户名即可。

7.1>.dockerignore

所有位于Dockerfile目录下的文件都称为上下文,特别是在创建镜像时,由于所有的上下文都会传送到Docker守护进程,所以请不要将非必要文件放在该目录,需要忽略文件时使用.dockerignore,类似与.gitingore。

7.2>FROM

命令格式:FROM <镜像>或FROM <镜像>:<标签>,前者默认使用latest。

7.3>MAINTAINER

设置镜像创造者信息,格式自由。

7.4>RUN

用于在FROM中设置的镜像上运行脚本或命令。RUN运行结果会生成新的镜像,运行的详细信息记录在镜像历史,是每一次RUN都会产生一个新的镜像,会影响容器的创建速度,因此一般会在层次和启动速度之间有一个平衡,有两种方式:
1、RUN <命令>,这种方式会用/bin/sh执行命令,若/bin/sh可执行文件不存在,则无法使用。
2、RUN [“<可执行文件>”, “<形式参数1>”, “<形式参数2>”…]

RUN apt-get install -y nginx
RUN echo "Hello Docker" > /tmp/hello
RUN ["apt-get", "install", "-y", "nginx"]
RUN ["/usr/local/bin/hello", "--help"]

7.5>CMD

用于设置容器启动时运行的脚本或命令,即使用docker run 命令创建容器或者使用docker start 命令启动容器时运行,有几种方式执行:
1、用/bin/sh运行命令:CMD <命令>
2、无shell直接运行:CMD [“<命令>”, “<形式参数1>”, “<形式参数2>”…]
3、使用ENTRYPOINT时:这个特殊一点,可执行程序是ENTRYPOINT指定,参数由CMD指定。

ENTRYPOINT ["echo"]
CMD ["hello"]
$ sudo docker build --tag example .
$ sudo docker run example
hello

7.6>ENTRYPOINT

虽然CMD和ENTRYPOINT都可以用于设置容器启动时要运行的命令,但docker run命令二者运行方式不同。
如下图:
>Dockerfile

FROM ubuntu:latest
CMD ["echo", "hello"]
###############

$ sudo docker build --tag example .
$ sudo docker run example echo world
world

从执行结果看,忽略了CMD的内容,下面用ENTRYPONT尝试一次
>Dockerfile

FROM ubuntu:latest
ENTRYPOINT ["echo", "hello"]
###############

$ sudo docker build --tag example .
$ sudo docker run example echo world
hello echo world

如果设置了ENTRYPOINT,则run后的参数会变成执行文件的参数。

7.7>EXPOSE

用于设置与主机相连的端口号,与docker run中的–expose一致。
注:只与主机连接,不对外暴露。对外暴露在docker run指定-p、-P选项。

7.8>ENV

设置环境变量,应用与RUN, CMD, ENTRYPOINT。

Dockerfile:
ENV GOPATH /go
ENV PATH /go/bin:$PATH

使用格式为ENV <环境变量><值>

7.9>ADD

用于向镜像添加文件,使用格式ADD <要复制的路径> <文件在镜像中的路径>。
Ps:1、要复制的路径以上下文目录为基准,不能使用上下文以外的文件、目录或绝对路径。
2、设置为目录时,会复制目录下所有文件。另外,也可以使用通配符。
3、也可以设置为网络文件URL。
4、解压缩位于本地的压缩文件。但是对于网络上的压缩文件,只进行解压缩,然后添加整个tar文件。
5、文件在镜像中的路径必须设置为绝对路径,并且若以/结尾,则创建目录并将文件复制到该目录。
6、像ADD ./ /hello这样添加当前目录时,.dockerignore文件设置的文件与目录被排除在外。

7.10>COPY

向镜像中添加文件,与ADD不同,添加压缩文件时不会解压缩,也不能使用URL,其他条款类似ADD。

7.11>VOLUME

用于将目录下的内容存储到主机而非容器。

Dockerfile
################
VOLUME /data
VOLUME ["/data", "/var/log/hello"]

使用格式:VOLUME <容器目录>或VOLUME [“容器目录1”, “容器目录2″…]
但VOLUME不能设置与主机的特定目录进行连接,若想连接必须在docker run命令中使用-v
选项指定.

7.12>USER

用于设置运行命令的用户帐号,该用户会运用与RUN, CMD, ENTRYPOINT,使用格式为:USER <帐号用户名>,USER后面所有的RUN,CMD,ENTRYPOINT都会得到应用,中间可以设置其他用户以更换用户。

7.13>WORKDIR

用于设置执行RUN, CMD, ENTRYPOINT命令的目录,使用格式为WORKDIR <路径>,WORKDIR后面所有的RUN,CMD,ENTRYPOINT都会得到应用,中间可以设置其他路径以更换目录。
可以使用绝对路径或者相对路径,相对路径是相对与上一个WORKDIR的路径,最初基准为/。

7.14>ONBUILD

将当前镜像作为基础镜像创建其他镜像时,ONBUILD指令用于执行一些要出发的操作。ONBUILD制定的命令在构建时不执行,而是在其他子镜像中执行。
指令格式为ONBUILD <Dockerfile命令><Dockerfile命令的形式参数>,除了MAINTAINER和ONBUILD之外的所有指令都可以使用。
可以用docker inspect命令查看镜像的ONBUILD指令中定义的内容。