针对“互联网+”时代的业务增长、变化速度及大规模计算的需求,廉价的、高可扩展的分布式x86集群已成为标准解决方案,如Google已经在几千万台服务器上部署分布式系统。Docker及其相关技术的出现和发展,又给大规模集群管理带来了新的想象空间。
如何将二者进行有效地结合?
本人将以实验的角度来部署mesos + marathon的docker集群

一、谈谈mesos

Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。接下来将简单介绍mesos。

1.1 mesos中的基本术语解释

Mesos-master:Mesos master,主要负责管理各个framework和slave,并将slave上的资源分配给各个framework
Mesos-slave:Mesos slave,负责管理本节点上的各个mesos-task,比如:为各个executor分配资源
Framework:计算框架,如:Hadoop,Spark等,通过MesosSchedulerDiver接入Mesos
Executor:执行器,安装到mesos-slave上,用于启动计算框架中的task。

Mesos-master是整个系统的核心,负责管理接入mesos的各个framework(由frameworks_manager管理)和 slave(由slaves_manager管理),并将slave上的资源按照某种策略分配给framework(由独立插拔模块Allocator管 理)。

Mesos-slave负责接收并执行来自mesos-master的命令、管理节点上的mesos-task,并为各个task分配资源。 mesos-slave将自己的资源量发送给mesos-master,由mesos-master中的Allocator模块决定将资源分配给哪个 framework,当前考虑的资源有CPU和内存两种,也就是说,mesos-slave会将CPU个数和内存量发送给mesos-master,而用 户提交作业时,需要指定每个任务需要的CPU个数和内存量,这样,当任务运行时,mesos-slave会将任务放到包含固定资源的linux container中运行,以达到资源隔离的效果。很明显,master存在单点故障问题,为此,mesos采用了zookeeper解决该问题。

Framework是指外部的计算框架,如Hadoop,Mesos等,这些计算框架可通过注册的方式接入mesos,以便mesos进行统一管理 和资源分配。Mesos要求可接入的框架必须有一个调度器模块,该调度器负责框架内部的任务调度。当一个framework想要接入mesos时,需要修 改自己的调度器,以便向mesos注册,并获取mesos分配给自己的资源, 这样再由自己的调度器将这些资源分配给框架中的任务,也就是说,整个mesos系统采用了双层调度框架:第一层,由mesos将资源分配给框架;第二层, 框架自己的调度器将资源分配给自己内部的任务。当前Mesos支持三种语言编写的调度器,分别是C++,java和python,为了向各种调度器提供统 一的接入方式,Mesos内部采用C++实现了一个MesosSchedulerDriver(调度器驱动器),framework的调度器可调用该 driver中的接口与Mesos-master交互,完成一系列功能(如注册,资源分配等)。

Executor主要用于启动框架内部的task。由于不同的框架,启动task的接口或者方式不同,当一个新的框架要接入mesos时,需要编写 一个executor,告诉mesos如何启动该框架中的task。为了向各种框架提供统一的执行器编写方式,Mesos内部采用C++实现了一个 MesosExecutorDiver(执行器驱动器),framework可通过该驱动器的相关接口告诉mesos启动task的方法。

1.2 总体架构

上图展示了mesos的重要组成部分,mesoso由一个master进程管理运行着每个客户端节点的salve进程和跑任务的mesos计算框架。master进程通过计算框架可以很细致的管理cpu和内存等,从而提供资源。每个资源提供与包含了一个清单(slave ID, resource1: amount1, resource2, amount2, …),master会根据现有的政府决定提供每个计算框架多少资源,例如公平分享或者根据优先级分享。为了支持不同种的政策,master通过插件机制新增了一个allocation模块使之分配资源更简单方便。

一个计算框架运行在两个组件之上,一个是scheduler,他是master提供资源的注册中心,另一个是executor程序,用来发起在slave节点上运行计算框架的任务。master决定给每个计算框架提供多少计算资源,计算框架的的调度去选择使用哪个资源。当一个计算框架接受了提供的资源,他会通过mesos的任务描述运行程序,mesos也会在相应的slave上发起任务。

1.3 资源提供的例子

让我们一起来熟悉下这个图上的流程步骤
1)slave 1 报告给master他拥有4核cpu和4G剩余内存,matser调用allocation政策模块,告诉salve 1 计算框架1应该被提供可用的资源。
2)master给计算框架1发送一个在slave1上可用的资源描述。
3)计算框架的调度器回复给master运行在slave上两个任务的相关信息,任务1需使用2个cpu,内存1G,任务2需使用1个cpu,2G内存。
4)最后,master发送任务给slave,分配适当的给计算框架执行器,继续发起两个任务(图上虚线处),因为仍有1个cpu和1G内存未分配,allocation模块现在或许提供剩下的资源给计算框架2。
除此之外,当任务完成,新的资源成为空闲时,这个资源提供程序将会重复。

二、学习zookeeper

2.1 Zookeeper简介

ZooKeeper是用来给集群服务维护配置信息,域名服务,提供分布式同步和提供组服务。所有这些类型的服务都使用某种形式的分布式应用程序。是一个分布式的,开放源码的协调服务,是的Chubby一个的实现,是Hadoop和Hbase的重要组件。

2.2角色

领导者(leader):领导者负责投票发起和决议,更新系统状态
跟随者(follwoer):follower用于接收客户请求并向客户端返回结果,在选主过程中参与投票
观察者:ObServer可以接受客户端连接,将写请求转发给leader节点,但ObServer不参加投票过程,只同步leader的状态,ObServer的目的是为了拓展系统,提高读取速度。
客户端:请求发起方

2.3 ZooKeeper的工作原理

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。
每个Server在工作过程中有三种状态:

  • LOOKING:当前Server不知道leader是谁,正在搜寻
  • LEADING:当前Server即为选举出来的leader
  • FOLLOWING:leader已经选举出来,当前Server与之同步

2.4 选主流程

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。先介绍basic paxos流程:
1)选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
2)选举线程首先向所有Server发起一次询问(包括自己);
3)选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
4)收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
5)线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.
每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。选主的具体流程图如下所示:

fast paxos流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。其流程图如下所示:

2.5 同步流程

选完leader以后,zk就进入状态同步过程。
1)leader等待server连接;
2)Follower连接leader,将最大的zxid发送给leader;
3)Leader根据follower的zxid确定同步点;
4)完成同步后通知follower 已经成为uptodate状态;
5)Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
流程图如下所示:

2.6 工作流程

2.6.1 Leader工作流程

Leader主要有三个功能:
1)恢复数据;
2)维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
3)Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。
PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
Leader的工作流程简图如下所示,在实际实现中,流程要比下图复杂得多,启动了三个线程来实现功能。

2.6.2 Follower工作流程

Follower主要有四个功能:
1)向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
2)接收Leader消息并进行处理;
3)接收Client的请求,如果为写请求,发送给Leader进行投票;
4)返回Client结果。
Follower的消息循环处理如下几种来自Leader的消息:
1)PING消息: 心跳消息;
2)PROPOSAL消息:Leader发起的提案,要求Follower投票;
3)COMMIT消息:服务器端最新一次提案的信息;
4)UPTODATE消息:表明同步完成;
5)REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
6)SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
Follower的工作流程简图如下所示,在实际实现中,Follower是通过5个线程来实现功能的。

三、搞懂marathon

marathon是一个mesos框架,能够支持运行长服务,比如web应用等。是集群的分布式Init.d,能够原样运行任何Linux二进制发布版本,如Tomcat Play等等,可以集群的多进程管理。也是一种私有的Pass,实现服务的发现,为部署提供提供REST API服务,有授权和SSL、配置约束,通过HAProxy实现服务发现和负载平衡。


我们可以如同一台Linux主机一样管理数千台服务器,它们的对应原理如下图,使用Marathon类似Linux主机内的init Systemd等外壳管理,而Mesos则不只包含一个Linux核,可以调度数千台服务器的Linux核,实际是一个数据中心的内核:

四、引入docker

来看看我另外一个博客吧
http://www.cnblogs.com/caoxiaojian/p/5101753.html

五、实战准备

5.1 系统准备

两台Centos7.1系统
主机名:docker-master IP地址:192.168.100.5 描述:Mesos Master Mesos Slave Marathon
主机名:docker-slave IP地址:192.168.100.6 描述:Zookeeper Mesos Slave
系统环境
  1. [root@docker-slave ~]# cat /etc/redhat-release
  2. CentOS Linux release 7.1.1503 (Core)
  3. [root@docker-slave ~]# uname -r
  4. 3.10.0-229.4.2.el7.x86_64
  5. [root@docker-slave ~]# uname -m
  6. x86_64
  7. [root@docker-slave ~]# uname -a
  8. Linux docker-slave 3.10.0-229.4.2.el7.x86_64 #1 SMP Wed May 13 10:06:09 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
  9. [root@docker-slave ~]# cat /etc/sysconfig/network
  10. HOSTNAME=docker-slave
  11. [root@docker-slave ~]# ping docker-salve
  12. ping: unknown host docker-salve
  13. [root@docker-slave ~]# ping docker-slave
  14. PING docker-slave (192.168.100.6) 56(84) bytes of data.
  15. 64 bytes from docker-slave (192.168.100.6): icmp_seq=1 ttl=64 time=0.058 ms

5.2 部署Zookeeper

准备java环境
  1. [root@docker-slave ~]# yum install -y java
  2. [root@docker-slave ~]# cd /usr/local/src/
  3. [root@docker-slave src]# wget https://www.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
  4. [root@docker-slave src]# tar zxf zookeeper-3.4.6.tar.gz
  5. [root@docker-slave src]# mv zookeeper-3.4.6 /usr/local/
  6. [root@docker-slave src]# ln -s /usr/local/zookeeper-3.4.6/ /usr/local/zookeeper
编辑配置文件
修改配置文件,由于虚拟机数量限制,这里采用了伪集群的配置方式,只能用不同端口实现通信,生产环境不建议采纳。
  1. [root@docker-slave src]# cd /usr/local/zookeeper/conf/
  2. [root@docker-slave conf]# cp zoo_sample.cfg zoo.cfg
  3. [root@docker-slave conf]# grep '^[a-z]' zoo.cfg
  4. tickTime=2000
  5. #Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  6. initLimit=10
  7. #Zookeeper的Leader 接受客户端(Follower)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 5个心跳的时间(也就是tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
  8. syncLimit=5
  9. #表示 Leader 与 Follower 之间发送消息时请求和应答时间长度,最长不能超过多少个tickTime 的时间长度,总的时间长度就是 2*2000=4 秒
  10. dataDir=/data/zk1
  11. #数据存放目录
  12. clientPort=2181
  13. #客户端连接端口
  14. #A 是一个数字,表示这个是第几号服务器;
  15. #B 是这个服务器的 ip 地址;
  16. #C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;
  17. #D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
  18. server.1=192.168.100.6:3181:4181
  19. server.2=192.168.100.6:3182:4182
  20. server.3=192.168.100.6:3183:4183
  21. # 配置文件最终配置
  22. [root@docker-slave conf]# grep '^[a-z]' zoo.cfg
  23. tickTime=2000
  24. initLimit=10
  25. syncLimit=5
  26. dataDir=/data/zk1
  27. clientPort=2181
  28. server.1=192.168.100.6:3181:4181
  29. server.2=192.168.100.6:3182:4182
  30. server.3=192.168.100.6:3183:4183
创建三个目录来存放zookeeper的数据文件
  1. [root@docker-slave conf]# mkdir -p /data/zk1 /data/zk2 /data/zk3
  2. [root@docker-slave conf]# echo "1" >/data/zk1/myid
  3. [root@docker-slave conf]# echo "2" >/data/zk2/myid
  4. [root@docker-slave conf]# echo "3" >/data/zk3/myid
生成三份zookeeper配置文件
  1. [root@docker-slave conf]# cp zoo.cfg zk1.cfg
  2. [root@docker-slave conf]# cp zoo.cfg zk2.cfg
  3. [root@docker-slave conf]# cp zoo.cfg zk3.cfg
修改zk2、zk3的配置,使用对应的数据目录和端口
  1. [root@docker-slave conf]# sed -i 's/zk1/zk2/g' zk2.cfg
  2. [root@docker-slave conf]# sed -i 's/zk1/zk3/g' zk3.cfg
  3. [root@docker-slave conf]# sed -i 's/2181/2182/g' zk2.cfg
  4. [root@docker-slave conf]# sed -i 's/2181/2183/g' zk3.cfg
启动Zookeeper并查看角色
  1. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk1.cfg
  2. JMX enabled by default
  3. Using config: /usr/local/zookeeper/conf/zk1.cfg
  4. Starting zookeeper ... STARTED
  5. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk2.cfg
  6. JMX enabled by default
  7. Using config: /usr/local/zookeeper/conf/zk2.cfg
  8. Starting zookeeper ... STARTED
  9. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zk3.cfg
  10. JMX enabled by default
  11. Using config: /usr/local/zookeeper/conf/zk3.cfg
  12. Starting zookeeper ... STARTED
  13. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk1.cfg
  14. JMX enabled by default
  15. Using config: /usr/local/zookeeper/conf/zk1.cfg
  16. Mode: follower
  17. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk2.cfg
  18. JMX enabled by default
  19. Using config: /usr/local/zookeeper/conf/zk2.cfg
  20. Mode: leader
  21. [root@docker-slave conf]# /usr/local/zookeeper/bin/zkServer.sh status /usr/local/zookeeper/conf/zk3.cfg
  22. JMX enabled by default
  23. Using config: /usr/local/zookeeper/conf/zk3.cfg
  24. Mode: follower
从以上状态来看目前zk2是leader,其它两个节点是follower
连接Zookeeper
[root@docker-slave conf]# /usr/local/zookeeper/bin/zkCli.sh -server 192.168.100.6:2181
5.3:部署mesos
安装mesosphere仓库,需要在Mesos Master和MesosSlave节点均安装
  1. [root@docker-master ~]# rpm -ivh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
  2. [root@docker-slave conf]# rpm -ivh http://repos.mesosphere.com/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm
在node1部署mesos和marathon
  1. [root@docker-master ~]# yum -y install mesos marathon
增加zookeeper配置
  1. [root@docker-master ~]# cat /etc/mesos/zk
  2. zk://192.168.100.6:2181,192.168.100.6:2182,192.168.100.6:2183/mesos
启动mesos master slave 和marathon
  1. [root@docker-master ~]# systemctl enable mesos-master mesos-slave
  2. [root@docker-master ~]# systemctl start mesos-master mesos-slave
  3. [root@docker-master ~]# systemctl enable marathon
  4. [root@docker-master ~]# systemctl start marathon
slave上部署mesos
  1. [root@docker-slave conf]# yum -y install mesos
此时打开Mesos的Web管理界面,这时候你将得到下图的页面但可能在‘Tasks’表格没有任何的条目。
运行第一mesos任务,可以在web界面查看到task
  1. [root@docker-master ~]# MASTER=$(mesos-resolve `cat /etc/mesos/zk`)
  2. [root@docker-master ~]# mesos-execute --master=$MASTER --name="cluster-test" --command="sleep 60"
 

5.4:使用marathon调用mesos管理docker容器

下载docker,并pull下来nginx镜像(两个node均操作)
  1. [root@docker-slave ~]# yum install -y docker
  2. [root@docker-master ~]# systemctl enable docker
  3. [root@docker-master ~]# systemctl start docker
  4. [root@docker-master ~]# docker pull nginx
再所有mesos-slave上增加配置参数,并重启
  1. [root@docker-master ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers
  2. [root@docker-master ~]# systemctl restart mesos-slave
  3. [root@docker-slave ~]# echo 'docker,mesos' | tee /etc/mesos-slave/containerizers
  4. [root@docker-slave ~]# systemctl restart mesos-slave
通过mesos调度,使用marathon来创建一个nginx镜像的docker容器,matathon默认监听8080端口,如图:
matathon通过zookeeper,marathon启动的时候会读取/etc/mesos/zk配置文件,通过Zookeeper来找到Mesos Master。marathon有自己的REST API,我们通过API的方式来创建一个nginx的docker容器。首先创建如下的配置文件nginx.json:
  1. [root@docker-master ~]# cat nginx.json
  2. {
  3. "id":"nginx",
  4. "cpus":0.2,
  5. "mem":20.0,
  6. "instances": 1,
  7. "constraints": [["hostname", "UNIQUE",""]],
  8. "container": {
  9. "type":"DOCKER",
  10. "docker": {
  11. "image": "nginx",
  12. "network": "BRIDGE",
  13. "portMappings": [
  14. {"containerPort": 80, "hostPort": 0,"servicePort": 0, "protocol": "tcp" }
  15. ]
  16. }
  17. }
  18. }
使用curl的方式调用测试
  1. [root@docker-master ~]# curl -X POST http://192.168.100.5:8080/v2/apps -d @/root/nginx.json -H "Content-type: application/json"
  2. {"id":"/nginx","cmd":null,"args":null,"user":null,"env":{},"instances":1,"cpus":0.2,"mem":20,"disk":0,"executor":"","constraints":[["hostname","UNIQUE",""]],"uris":[],"fetch":[],"storeUrls":[],"ports":[0],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"nginx","network":"BRIDGE","portMappings":[{"containerPort":80,"hostPort":0,"servicePort":0,"protocol":"tcp"}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"labels":{},"acceptedResourceRoles":null,"ipAddress":null,"version":"2016-03-01T07:19:44.339Z","tasksStaged":0,"tasksRunning":0,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[{"id":"502712f0-dc3a-44f8-a9cf-0dfa7407ec94"}],"tasks":[]}
查看通过API和手动创建的容器
现在你就可以通过31705来访问到nginx了。当然了,你也可以在mesos-slave上来寻找一下这个容器:
  1. [root@docker-master ~]# docker ps -a
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 2e333092a383 nginx "nginx -g 'daemon off" About a minute ago Up About a minute 443/tcp, 0.0.0.0:31705->80/tcp mesos-46abb5e7-3775-4383-b953-c5b2b9ae5c9f-S0.00229c83-5505-400d-984f-4849e9850b71
访问31705端口,查看nginx
  1. [root@docker-master ~]# curl 192.168.100.5:31705
在marathonweb界面查看
在mesos的web界面查看

  如果你想创建同样的容器,可以点击上图中德Scale Application来体验一下。同样的,你也可以通过marathon的Web界面来进行容器的创建、扩展和销毁。

Docker云Paas平台部署:Docker+Mesos+Marathon的更多相关文章

  1. centos7部署PaaS平台环境(mesos+marathon)

    假如有5台主机可以使用,ip地址如下 规划(2master+3slave) master: 192.168.248.205 ---master1 192.168.248.206 ---master2 ...

  2. 开源协同办公平台部署教程:O2OA PAAS平台部署

    一.镜像制作1.将安装介质o2server-5.0.3-linux.zip上传至镜像制作服务器上.(上传目录为/paas/xxhpaas/moka/o2oa)2.使用unzip命令解压安装包,参考命令 ...

  3. 【Docker】(3)---linux部署Docker、Docker常用命令

    linux部署Docker.Docker常用命令 本次部署Linux版本:CentOS 7.4 64位. 说明: 因为Docker是基于Linux 64bit的 所以Docker要求64位的系统且内核 ...

  4. docker(二)部署docker容器虚拟化平台

    yum安装方法参考:https://www.cnblogs.com/yufeng218/p/8370670.html https://www.cnblogs.com/straycats/p/84112 ...

  5. Docker系列五: docker-compose部署Docker容器

    Docker使用Dockerfile来实现对现有镜像的修改来创建新的镜像, 那docker-compose则完成镜像的自动部署, 可以实现多个容器同时部署 Dockerfile可以让用户管理一个单独的 ...

  6. Docker推出了Docker云,给大家介绍下哈!

    Docker推出了Docker云,给大家介绍下哈. 收到了Docker官网的邮件邀请,他们推出了Docker云:https://cloud.docker.com 账号信息栏目下有: 云提供商:眼下支持 ...

  7. PaaS平台的尴尬与变革

    当今时代只要提到云计算这个词语,一定会提到云计算分为IaaS.PaaS.SaaS 这三个层面,现阶段云环境中IaaS和SaaS都实现了商品化.但是,PaaS作为云计算的服务模式之一,既不像IaaS那样 ...

  8. PaaS 平台的网络需求

    在使用 Docker 构建 PaaS 平台的过程中,我们首先遇到的问题是需要选择一个满足需求的网络模型: 让每个容器拥有自己的网络栈,特别是独立的 IP 地址 能够进行跨服务器的容器间通讯,同时不依赖 ...

  9. 【Docker学习之一】初始Docker

    一.云计算的概念 PaaS(Platform-as-a-Service:平台即服务),把应用服务的运行和开发环境作为一种服务.SaaS(Software-as-a-Service),意思为软件即服务, ...

随机推荐

  1. 任意类型转换为IntPtr

    之前,将数组.结构体等转换为IntPtr使用的是Marshal.Copy().Marshal.StructureToPtr(),但是有个问题自定义的结构体数组没法这样转化,一般网上给出的解决方法就是通 ...

  2. basket.js 源码分析

    basket.js 源码分析 一.前言 basket.js 可以用来加载js脚本并且保存到 LocalStorage 上,使我们可以更加精准地控制缓存,即使是在 http 缓存过期之后也可以使用.因此 ...

  3. android在Data目录内置可删除的APP

    一.准备工作:make_ext4fs.mkuserimg.sh.simg2img,把它们跟要修改的 .img.ext4(或.img)文件放置到同一个目录下 二.转换源文件为img格式( .img则略过 ...

  4. IOS单例

    单例就是只有一个实例. 两种常见的创建方法: 1. : static A *a = nil; + (A *)shareInstance { if (!a) a = [[self alloc] init ...

  5. 【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层

    iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...

  6. 小波说雨燕 第三季 构建 swift UI 之 度假清单 学习笔记

    最终的效果: <1>第一个场景: 1.本地化 界面简体中文化 Supporting Files - info.plist Localization native development r ...

  7. CentOS6.5安装mysql5.1.73

    思路: 1.查看有无安装过mysql rpm -qa|grep mysql

  8. Effective Java 14 In public classes, use accessor methods, not public fields

    Principle To offer the benefits of encapsulation you should always expose private field with public ...

  9. HttpClient使用方法(包括POST文件)

    最近在做跨系统的数据交互业务,从.Net的系统提交数据到Java的系统. 简单的表单Get.POST都没问题,但是有个功能是要提交普通文本和文件,试了好多都有问题,最后用HttpClient小折腾了一 ...

  10. XMLHttpRequest的跨域请求

    缘起 由于浏览器的同源策略,非同源不可请求. 但是,在实践当中,经常会出现需要跨域请求资源的情况,比较典型的例如某个子域名向负责进行用户验证的子域名请求用户信息等应用. 以前要实现跨域访问,可以通过J ...