,金山西山居资深Unity开发工程师,Unity开发框架KSFramework作者,关注Web开发全栈、DevOps
最近,跟一个大学金融系的同学交流,发现他对科技发展的动态非常了解,然而对于一些技术关键字的应用并不是很理解。对于普通不懂技术的小白来说,如果去咨询一些IT行业技术大牛,他们往往会获得一个一脸茫然的回答。比如说,他问我“云计算”是什么?百度百科:
云计算(cloud computing)是基于互联网的相关服务的增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。
别说一个技术小白了,就算现在我看完这句话,我也是一脸茫然,难为大家了。站在技术小白的角度,去看看网上的一些“云计算”的解释,你会发现,还是那么的难以理解。用产品的口吻来说:用户体验不好。我尝试给他作出类比:
“古时候,人们家里做一口井,水从井里打出来,而现在,我们扭开水龙头,水就来了; 10年前,你要装软件,得跑去电脑城买光碟,而现在,连上网打开应用商店,软件尽在眼前——这就是云计算”。
当然了,本来“云计算”就是一个很广的问题,这样的解释无非是拿出其中之一的应用场景作类比。但是它能帮助普通人更好的理解。我觉得这是一个非常有趣的过程:用跨界思维,用拟物或拟人的方式,去提炼简化一些看起来很复杂、枯燥的技术关键词。
Docker是什么?
回归正题,我们讨论Docker。估计喜欢浏览技术新闻资讯站的同学,都会知道Docker——传说中改变世界的东西,它改变了应用的部署运维。那么Docker是什么?来看看百度百科:
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
当初,看完它的解释后,我的第一反应依旧是蒙圈,因为它跟我们脑海中常见的物理机、虚拟机的概念相比,是一种未曾想象过的新事物。鉴于所在工作环境周围,还没见过应用Docker在开发环境的同学(希望大牛云集的项目不要鄙视),而我又觉得用通俗化的思路去解释Docker思维是有价值的一件事,这也是本文的成文目的。
Docker图标,小鲸鱼
这是Docker的官方图标——一只大鲸鱼,上面有各种各样的集装箱;鲸鱼就像一个操作系统,上面装着各种各样的集装箱——软件。也许你会问,这不跟我们iPhone应用一样吗?手机操作系统(鲸鱼),里面有各种各样的App(集装箱)。但是,仔细想想,iPhone上的App,Android上能运行吗?——不行。因为iPhone使用IPA格式的App包装方法,而Android使用APK格式的App包装方法,两者部署上是非常的不一样的。
能不能在Android上,运行iPhone应用,而又不使用损耗资源的虚拟机技术? 这就是Docker——它应用在PC平台上的,可以让不同的操作系统平台,占用很少的资源,运行同样的软件程序。
它就像一个提供开发型软件的应用商店。以往,我们需要安装MySQL数据库,我们首先要想,我的操作系统是Windows?我的CPU是64位? 然后我们找到了MySQL Windows 64位版本进行下载,然后开始安装,安装在C盘?安装完成后,把数据库账号密码设置好?而在Docker时代,我们只需要下载MySQL的Docker镜像安装就可以了。这个思路推而广之,Android上利用Docker运行iPhone应用什么时候可以做到?这是技术上可行的,但这里不作过多幻想了。
Docker不是什么新生事物,早在2013年就诞生了,而它的核心技术cgroup早在2006年就写进Linux内核了,直到这2年,才渐渐开始广泛的应用。Docker常见的场景,是部署和运维。今天,我们抛开技术细节、理论、运维需求,简单谈谈Docker怎么应用到我们日常游戏开发环境当中,并让团队的工作流程起到什么样的优化。
快速搭建MySQL+Redis开发环境
Laradock是一个PHP的Docker开发环境,使用它可以极其方便的快速搭建PHP开发环境。 它不但包含了PHP语言执行环境,还包括了一系列相关工具,其中包括我们非常常用的MySQL、Redis。在Laradock的官方文档中,就有这样的一句话:
Use Docker first and learn about it later.
先使用Docker,然后再学习它。
是的,先使用它,然后再深入学习Docker的一些很原理,一个自上而下的学习过程,可以让你更加快速的理解和应用Docker。应用Laradock是一个很好的Docker学习起点。要使用Laradock,首先你得安装Docker。 一般有可以选择下载Windows版Docker或下载Mac版Docker,跟着安装步骤安装即可。而在国内,访问Docker的镜像仓库非常的慢,因此,需要设置国内的加速镜像仓库。
小鲸鱼托盘图标
安装好Docker以后,会有小鲸鱼的图标出现在系统托盘上。右击出现菜单(macOS系统则是左击),并选择“Settings”。
Docker加速器
Windows环境时,选中“Docker Daemon”界面,往”registry-mirrors”字段里添加镜像仓库的地址。
为什么要配置镜像仓库地址?像前面所说的,Docker有点像应用商店——把需要的开发软件,下载并安装。因此镜像仓库(Docker Hub)上储存着各种各样的“镜像”,可理解成别人预先制作好的开发软件。包括我们常见的MySQL、CentOS,其官方都会维护一份Docker镜像。
使用Laradock,你可以使用它在GitHub上托管的源码:
git clone
https://github.com/laradock/laradock
cd laradock
docker-compose up -d nginx mysql redis memcached
或者,如果连命令都不想输入(或者git都还没安装),下载
https://github.com/mr-kelly/laradock/archive/master.zip ,解压后,在安装好Windows环境双击执行start.bat批处理。
这样的一条命令,呼叫Laradock下载、启动了nginx、MySQL、redis、memcached四个主要容器。这几个不同的Docker容器互相组合,并映射端口到本地。比如把localhost:80端口映射到nginx容器的80端口,把localhost:3306端口映射到MySQL容器的3306端口。这时候,使用你的MySQL数据库工具(比如Navicat),输入连接地址localhost,账号root,密码root,你就能连上了MySQL容器中的MySQL数据库程序了。
为什么我会使用Laradock?
在以往,我一般会使用XAMPP来当作我的PHP HTTP开发环境——它内置了Apache、MySQL等开发组件,并且能以“绿色”软件的方式安装运行在我的电脑上。 直到有一次,XAMPP在我的macOS上,出现phpredis扩展无法访问Redis的问题,折腾很久也没找到具体的原因,最终转而使用Docker搭建开发环境。
在日常的工作中,我们其实经常遇到这种情况:因为一些跟业务工作的一些小问题,比如装系统啊、环境配置的坑啊等等,会耗费我们非常多的精力。要真正的应用Docker到您的开发环境,需要根据项目业务、技术选型,来自定义Docker镜像,比如说,一个使用Java+MySQL的项目,除了MySQL镜像外,还需要Java运行时镜像,多个镜像互相组合。
可能你会疑惑,为什么要弄成多个镜像?使用一个Linux发行版镜像,然后在上面安装好Java、MySQL,再制作一个完整的镜像不就行了吗? 是的,这也是可行的,只是说这样做法,类似于编程开发中的“耦合度高”,就是当这样一个完整的开发环境镜像在某一天需要修改时,比如说其中的MySQL版本更新了,就需要对这个镜像进行重新制作。而拆分成多个镜像互相组合,则只需要使用官方对应版本的新镜像即可。
怎么使用Docker进行镜像的制作,官方的文档很多,这里就不重复“造轮子”了。Laradock的Github地址laradock/laradock: A Docker PHP development environment. ,上面有其更加详细的使用方法。
应用Docker开发环境的场景
一个新人入职
新人工程师走进公司,会有一个熟悉工作环境的过程,其中一个耗时的环节,就是安装开发环境。这是一个非常折腾人的过程,如果你是使用大型IDE的开发者,比如说安装MySQL、SQLServer、Android SDK等大型开发软件,这将是一个耗时的过程——首先你得找到软件包,然后再进入漫长的安装过程。最常见的实践是公司内部共享,把这些常用软件都共享出来,让大家安装。然而大家的习惯不同的,操作系统也不同,过程中依然会遇到种种兼容问题。
曾经一个做Android开发的朋友,在入职公司的第一周内——花了一周的时间,终于把开发环境搭建完成,让Java工程编译通过。
游戏策划跑单服
游戏团队开发的过程中,免不了出现非技术人员需要在自己机器上启动游戏服务器进行测试的情况。因此,“搭建开发环境”这个技能,会出现非技术人员身上。跟程序员相比,非技术人员“搭建开发环境”或“配置服务器环境”是相对更加难的事情,他们最需要的是有一种“双击就能运行”的单服运行体验。 有一些非技术人员和程序员之间对话,是我们经常听见的:
“嗯,这个功能我提交前测试是正常的——你的环境干净吗?需要的数据都干净地重新生成了吗?第三方库的二进制文件更新了吗?你们几个人测试的版本一致吗?要不你 Cleanup / 重启 / 重新保存 / 重新建个账号试试?”(引自厚积薄发 | 游戏引擎技术点滴)
然而实际的开发过程中,程序、策划之间是缺乏换位思考的,程序员更喜欢直接在自己的工作上开码,而不是为非自己工作范围内的体验进行优化。因此,“技术流”策划甚是常见,不但了解软连接硬链接的创建删除、还熟悉各种各样的SQL数据库、还会通过Visual Studio编译程序,甚至有很多都能直接编程的。
开发软件
那么能不能把装好软件的开发机整个做一个Ghost系统镜像?
这确实是我前两年项目所使用的方法:在一台电脑上,装好所有开发环境软件,然后使用Ghost打包一个系统镜像。想法很美好,但是实际过程却很难执行。一个镜像大小动辄10多GB的占用,克隆慢,恢复镜像也慢;更要命的是,开发环境在研发过程中经常的变化,比方说想把旧有镜像中的MySQL 4升级成MySQL 5,怎么做? 不停的重新构建虚拟机镜像? 太艰难。
后来我为了达到这样的目的,完整的MySQL执行程序、MongoDB执行程序直接放到SVN上传。从程序员角度来看,这是肮脏的,把一些无关重要的二进制文件进入到了代码库;但是从用户体验的角度来看,这是提高了非技术人员的使用体验。
类似这个情况如果应用Docker后,我们大可以只需要把MySQL或MongoDB的Dockerfile定义文件上传到SVN,非技术人员在首次启动时就会自动从容器仓库(内网或外网均可)拉取到对应的容器并启动,快速并且规避兼容性问题。
一些Linux-only的程序
redis对Windows的支持非常有限,skynet游戏框架不支持Windows平台,但是对于使用Windows的人来说,会使用一台虚拟机来进行开发。
而使用Docker,则可以改善这样的开发环境:部署一个Linux容器,并把本地代码文件映射到容器中,做到使用本地环境编辑代码、使用Docker运行程序;Redis官方提供Docker版本,体积非常小,让Windows下运行不再困难。
导入真实玩家数据
在项目运营中,出现的一些BUG,我们希望能模拟玩家的数据进行测试,这时候需要把一些玩家的数据导入,进行测试。一般来说,我们需要把数据库的数据导出,然后再在开发环境中导入。
而如果运营的项目是使用Docker容器进行部署的,那我们只需要把这个容器整个拖回到本地执行,我们就能完整的模拟到真实数据环境了。 同样,应用这样的思路也可以进行数据库的备份。
DevOps
说起Docker,总是免不了DevOps——开发运维一体化。这是一个很大很抽象的思想话题,但我们这里只简单的介绍其中一种应用:开发所使用的Docker容器,直接丢到生产服务器,极简部署。
比方说,我所在项目使用C#进行游戏服务器的开发,在Windows上使用.net Framework跑,实际运维环境则使用Mono。也就是说,实际运维环境中,如果出现了有.net Framework和Mono不同兼容性的BUG,这些BUG对开发人员来说都是前所未见、难以理解的——因为开发环境,跟运营环境,是完全不一样的,这会引领开发人员进入另一场爬坑游戏。
Docker原理
Docker的两大核心基础技术是namespace和cgroup,它们早在2006年的就被写进如Linux内核。
抽象来说,跟虚拟机不一样的是,虚拟机技术,把CPU、内存等所有硬件用软件化进行虚拟,形成一个虚拟的计算机环境;而Docker,则有点像“CPU中的虚拟CPU”、“内存中的虚拟内存”来对计算机进行资源隔离。
Vagrant
在使用Docker之前,我一直使用Vagrant来进行开发环境快速部署。它们的目的很相像,但是又不是那么一回事。Vagrant说白了,就是一个VirtualBox虚拟机的快速管理工具。以往使用虚拟机,我们需要安装VirtualBox,需要下载Linux发行版镜像,需要安装,安装后再安装各种开发软件。
而使用Vagrant,就像Docker一样,只需要一条命令,就可以完成以上所有的工作了。 只是,说白了,Vagrant就是一个虚拟机管理工具,它就类似于你使用了一个CentOS Docker容器,然后在里面安装好所有的开发软件。在Web开发领域,看到很多程序员已经应用上Docker用于开发环境了;目前身边的游戏开发中还没看到,也希望Docker慢慢普及开来。本文只是非常片面的展现了Docker应用的冰山一角——搭建简单开发环境。谨供你参考。
via:CSDN
相关阅读:
程序员经验分享:咋样才能做个有意思的怪物AI?