DevOps 实战:Jenkins Docker

语言: CN / TW / HK

随时 Docker 的普及,云原生时代已经到来,开发工程师对应用环境的掌控力进一步加强,运维成本进一步降低。DevOps 采用 Docker 更是如虎添翼,持续集成更快更灵活,部署更简单。本课程主要讲解 Docker 服务器架构和技术要点,以及实战使用 Jenkins 构建 Docker。

本次腾讯云大学大咖分享课程邀请 CODING DevOps 架构师 杨周 分享关于“DevOps 实战:Jenkins Docker”课程的内容。

本次分享内容:

1、Docker 服务器架构 2、Docker 下载和构建加速 3、项目容器化的技术要点 4、DevOps 实战:Jenkins 构建 Docker

Docker 服务器架构

上节课我们讲了服务器架构从买服务器演进到了租服务器,再到云计算租一切,比如 云存储、云数据库、企业邮箱,分别属于 IaaS、PaaS、SaaS。

IaaS 是“基础设施即服务”,采用服务器集群虚拟化技术,面向运维人员,不用关心服务器怎么加内存、坏了怎么办,节约了硬件和网络维护成本;

PaaS 是“平台即服务”,提供数据库等软件服务,面向开发者编程调用,不需要自己搭建了,节约了运维成本,而运行环境能否标准化取代自建,是个问题;

SaaS 是“软件即服务”,提供企业邮箱、代码托管等软件服务,面向办公人士图形化界面操作,不需要运维也不需要开发。

如果租了台云服务器,在上面安装了数据库,这叫做 IaaS + 自建,缺点是:自己负责数据库备份,升级非常困难,运维成本很高,当然比以前买服务器有进步。

如果租了台云服务器,再租了台云数据库,然后搭建开源邮箱和代码库,这叫做 IaaS + PaaS + 自建,缺点是:自己负责邮箱和代码库的升级,运维成本中等,而且开源产品的图形界面往往比较难用,并且无人跟进及时升级导致安全隐患大、服务不稳定,运维自己搭的邮箱夜里出故障了,客户发的邮件丢了,没有人知道,而专门做企业邮箱的公司承诺 SLA,有专人值守。现在很少有公司自己搭邮箱了,是一大进步,但还是有不少公司自己搭代码库,浪费了很多人力物力,结果还难用降低了研发效率。

做工程的最佳实践是:不要重复造轮子,只要能买到就不要自己造自己搭,专注于产品业务。除非这个轮子是你的核心依赖,比如手机芯片,那属于科研,而不是工程。所以首先需要明确本公司是业务驱动,还是科研驱动。关于工程师和科学家的区别,推荐阅读硅谷创业之父写的《黑客与画家》

PaaS 提供的云数据库等标准化软件服务,非常方便,而标准化运行环境却没有流行起来,为什么?

2010 年,dotCloud 成立做 PaaS 运行环境,结果发展不好,把其中的 Docker 开源,却很受欢迎,大家可以阅读这段有趣的历史《Docker 传奇之 dotCloud》

PaaS 让开发者无需关心操作系统,比如云数据库后面是什么系统,开发者不用管,最多改个配置重启一下,很方便。而开发者用各种语言写的应用,都是定制化的,而不是标准化的,比如 Apache 配置不一样,开启的模块不一样,或者用的是 Nginx,所以开发者需要的是把 项目、语言环境 和 Apache 一起打包部署,甚至还有编译安装的组件,那就需要把整个系统打包。所以统一的应用运行环境无法满足,没有流行起来。

而 Docker 是一种轻量级虚拟机,解决了这个问题,非常方便。单机部署和运行 Docker 很简单,而互联网项目往往用户量大,需要多台服务器,如何部署集群并且自动伸缩,就需要集群管理工具。

Google 推出了 K8s,Docker 官方推出了 Swarm,经过两年的竞争,从 Google 搜索的关键词热度图可以看出 K8s 已经胜出,目前国内的云计算大厂也纷纷支持 K8s。

具体的技术对比,大家可以阅读 《揭秘腾讯云的PaaS技术选型策略》

Docker 属于操作系统层虚拟化,称为“容器”,它在 Linux 系统里创建一个虚拟层,共用一个 Linux 内核,既做到了隔离,速度又快于传统的硬件抽象层虚拟机(比如 VirtualBox,可以在 Windows 系统里创建 Linux 虚拟机)。

以前不管多么小的项目都要申请一台新服务器,因为多个项目部署在一起会冲突,比如语言版本不同、共用一个 Apache 导致上线重启时中断别的项目。

而 Docker 隔离了各个项目,一台服务器可以跑很多个 Docker,大幅度降低服务器成本,初期只需要买 1 台服务器,根据性能需求再增加。

第一步:安装 Docker,按照官方文档,结果内地非常慢,甚至安装失败。经过分析安装脚本的源码,发现官方支持加速,但文档里面没有写,很多人都不知道。

可以看到 Docker 用的是 Cloudflare 国际 CDN,这家 CDN 是有中国节点的,但在中国办网站需要备案,对于尚未在中国开展业务的公司,尤其是各种英语的技术服务,都不会来备案,所以内地开发者访问很慢,甚至超时。

这时候就需要有人提供国内镜像加速,这是个吃力不讨好的事情,目前只有 163 一家提供免注册的 Docker 公网加速,非常感谢。从图中可以看到,拉取成功,速度挺快。

项目容器化需要开发者写一个 Dockerfile,基于各个语言的官方镜像再安装需要的库和包,比如我们通过加速下载了 PHP 官方的 php:7.4-apache 镜像,需要 apt 安装一些库,结果 docker build 的时候卡住了,这时候有个很好的调试方法:docker run 登录进去,就是我们熟悉的 Linux 系统了,执行 Dockerfile 里面的那些步骤,看看哪一步慢。看图片右下角,可以发现 apt update 很慢,才 10 KB/s。这时候就要想办法加速 apt 了。

Docker 下载和构建加速

apt 加速有大厂提供了,composer install 也有了,但没人提供 get composer,所以我做了个开源项目提供加速服务,大家课后可扫码了解。

项目容器化的技术要点

项目容器化的技术要点有4个:

  • 国内加速,掌握各种软件源的国内加速。
  • HTTPS,SSL证书不要放在Docker里,应放在Docker里,应放在云计算提供的负载均衡里。Docker只提供HTTP服务即可。
  • 云存储,文件不要上传到Docker里,重启就丢了,应上传到云存储。
  • Log采集,Log不要记录在Docker里的文件中,而应该输出到STDOUT和STDERR,再使用Log采集工具。

有一个 Laravel 项目在本地运行,Apache 也配好了,如何对它进行 Docker 化?

第一步:搜索框架官方的 Docker 镜像,如果没有,再寻找语言官方镜像。比如 Laravel 没有官方镜像,那就用 PHP 镜像,安装一些组件即可。

把本地项目的依赖包删除,然后挂载到 Docker 里,进行依赖安装,逐个解决报错,比如图中 composer install 报错缺少 zip,那就需要通过 apt 安装。

apt 安装需要使用国内加速,请看最上面一行代码。apt 安装完毕,再进行项目包安装,最后把所有的依赖都装好,项目终于跑了起来。

Docker 始终在前台运行,镜像无状态,重启就会丢失所有文件,所以 log 应该通过标准输出,而不应该保存为文件。可以看到 Apache 已经把 log 文件指向了标准输出。

项目中会记录业务 log,也需要改造为标准输出。左边是项目的 log 配置,右边是业务代码打 log,下面是最终运行效果。

最后中国版的 Dockerfile 是这样的,黄色的部分用来国内加速,其余部分是国际通用的。

DevOps 实战:Jenkins 构建 Docker

以前持续集成依赖厂商提供的语言环境,不支持某些语言或者版本过时经常发生,而到了 Docker 时代,持续集成环境根据开发者的 Dockerfile 进行搭建,可以支持任何环境,开发者的掌控力进一步加强,厂商也无需投入资金去支持各种语言了,达到了双赢。

部署 Docker 镜像的成本也很低,尤其是 K8s 弹性集群,不需要购买服务器,根据性能自动伸缩,很多网站夜间访问量很低,可降低到一两台,比包年包月的服务器便宜。

可以看出需要3个服务:持续集成、私有 Docker 仓库、K8s 集群管理。如果自己搭建,维护成本很高,不符合云计算的理念,采用 PaaS 最合适。

第一步,寻找 Jenkins 云服务和制品仓库,比如 coding.net

这个项目的代码很简单,就是一个 Laravel demo,大家可以提交自己熟悉的语言 demo,然后创建制品库。

创建了 Docker 制品库,就会获得一个仓库链接,用来推送和拉取镜像。

然后配置一下 Jenkins,建议调试阶段使用在线静态 Jenkinsfile,调试通过以后,再保存到代码库里。

CODING Jenkins 图形化编辑器

Jenkins 构建 Docker 很简单,和本地一样,只是要掌握一些 Jenkins 语法。需要注意的是:要判断分支,比如只构建 master。

构建成功后,可以在制品库中看到镜像。下一步就是把它部署到 K8s 集群里。

找一家云计算厂商,如腾讯云,创建 K8s 集群,会获得一个 KubeConfig,放在本地即可使用 kubectl 命令远程操作。

不过 K8s 来自 Google,官网在国外,内地无法下载,所以需要国内加速。对 kubectl 命令不熟悉的话,也可以使用云计算网页后台创建网站,比如图中用 apache 官方镜像创建了一个网站。

把 K8s 密钥录入 CODING,授权给持续集成。

看图中高亮的代码,先在 K8s 中创建一个密钥用来保存私有 Docker 仓库的地址、用户名、密码,然后部署时指定私有镜像和密钥即可。

Jenkins 运行成功,在本地使用 kubectl get pods 命令可以看到正在创建一个新容器,老的容器继续运行。

还可以通过 kubectl edit deploy web 命令查看目前的配置。

从第一张图可以看到 K8s 配置里有了私有镜像和仓库密钥。

第二张图可以看到新容器创建成功以后,老的容器才会被删除,不像传统上线那样导致服务中断。

第三张图是部署成功的项目首页。

 

课程源码:http://codes-farm.coding.net/p/laravel-demo/d/laravel-demo/git