一个应用软件(BS/CS)往往会由多个上下游的服务进行配合工作。为了开发持续集成、自动弹性部署以降低成本提升效率,可以将应用dockerize(容器化,或rkt),然后使用kubernetes进行管理。

容器化的一般步骤:

一、下载官方镜像(基础依赖环境)

  1. 修改镜像源macbook安装的docker:perfereneces -> Daemon -> +Registry mirriors。下载站: https://hub.docker.com/(如果有代理),或国内镜像https://docker.mirrors.ustc.edu.cn/(中科大), 再或者公司内部registry,推荐中科大的镜像很好用。
  2. 搜索镜像,针对不同的应用搜索官方镜像,例如:前端应用(nginx)、Ruby On Rails(Ruby)、Golang(Golang)
  3. 下载镜像 docker pull xxx(xxx:latest 版本)

二、定制化镜像(修改Dockerfile)

  1. 阅读官方镜像的文档,了解启动和部署,以及内部环境(操作系统、二进制)和参数。
  2. 加入路径(例如nginx html路径)ADD outside_dir_path inside_dir_path,或者修改Dockerfile WORKDIR 绑定项目目录
  3. CMD 安装配置(如果需要安装依赖)
  4. 容器内部启动,暴露端口 EXPOSE

三、镜像手动部署和调试

  1. 在开发机上编写构建脚本
     docker build -t xxx -f Dockerfile .
     docker push xxx
    
  2. 在部署机上编写部署脚本
     docker pull xxx:latest
     docker stop xxx && docker rm xxx
     docker run -d --name xxx -p 8888:8888 -m 4G --memory-swap 16G xxx:latest
    
  3. 如果在build是出现错误,可以进到container中进行调试
     docker exec -ti xxx /bin/bash
    
  4. 调试好后 使用docker commit将修改提交,修改Dockerfile在build的时候保证正确

四、搭建部署Kubernetes集群进行管理

  1. TODO…

单页应用容器化:

一、开发:

为了开发和部署使用同一套代码,不用在开发和部署时来回切换修改相应的地址变量,可以使用NODEJS自带的进程环境变量process.env.NODE_ENV

var xxxhost = 'http://localhost'
if (process.env.NODE_ENV === 'production') {
    xxxhost = 'http://xxx.xxx.xxx.xxx'
}

类似的有RAILS_ENV在启动时指定,代码中Rails.env获取。

区分开发环境和生产环境,在 Dockerfile 和 部署脚本可以加上:

RUN export NODE_ENV=production

全局变量的妙用:localStorage.set(key, value)localStorage.get(key)

二、部署:

使用nginx的官方镜像。 首先打包npm run build,把打包好的单页应用放到nginx镜像的html路径下即可。

关于404问题,是因为默认的nginx配置会对url路径去寻找文件,而单页应用的url是js控制修改的,客户端(浏览器)只是第一次请求了nginx,拿到app的所有编译好的code,后面的请求都是js控制请求后端接口,然后渲染页面,看起来像是页面跳转其实获取html和js只对nginx请求了一次。nginx在$uri对应的文件路径下当然找不到了,所以应该去index.html找,nginx的try_files正好有这个功能加上一行:

try_files $uri $uri/ /index.html last;

如何调试container里的nginx?通过docker exec -ti xxx /bin/bash进入容器,修改/usr/local/nginx/conf/nginx.conf,然后重启 /usr/local/nginx/sbin/.nginx -s reload(centos下的路径,其它可能略有不同)。

配置通用可以通过docker commit 提交到镜像,或者docker build 重新打一个。下次用这个作为父镜像

Golang HTTP服务容器化

一、开发:

Golang程序包管理使用glide。使用方法跟Ruby的bundle类似。

二、部署:

Golang程序容器化有两种镜像可选:1.Golang 2.scratch,两种方式的区别是前者将代码放到容器内部编译然后运行,而后者直接编译好二进制然后放进容器。 前者的优势是开发方便,不用考虑兼容性,代码放进容器便可直接编译运行,但是镜像占用存储空间大。后者优势是镜像小,性能好,但是要考虑兼容性问题。 权衡之下,选择前者,因为更具兼容性,开发方便。

Rails HTTP服务容器化

一、开发:

使用Rails --api模式开发,具体可参考Rails Guide。 开发、生产使用同一套代码,和前端开发类似,增加系统变量:

export RAILS_ENV=production

代码中用Rails.env.production?判断。

二、部署:

容器化选用Ruby官方镜像,选择和本地开发Rails使用所支持最低Ruby版本以上即可。下载包可以使用代理或者修改为国内源。