简体   繁体   English

是否可以“构建”(“编译”)Docker镜像以不需要Docker?

[英]Can Docker images be “built” (“compiled”) to not require Docker?

I have a very small amount of experience with Docker for experimentation and development, and zero experience with Docker when it comes to staging and deployment - so forgive anything that sounds naive. 我在Docker上进行实验和开发的经验非常少,而在登台和部署方面,Docker的经验则为零,因此请原谅任何听起来很幼稚的事情。

The main question 主要问题

Suppose I have a Docker image (or even a docker-compose.yml file consisting of several images and services) which, when run, sets up the environment for my app and runs my app - allowing for connections on a publicly open port and responding to requests. 假设我有一个Docker映像(甚至是由几个映像和服务组成的docker-compose.yml文件),在运行时,它会为我的应用设置环境并运行我的应用-允许在公共开放端口上进行连接并响应要求。

In order to run this image in production (and therefore in order to run my app in production) the production server must have Docker installed. 为了在生产环境中运行此映像(并因此在生产环境中运行我的应用程序),生产服务器必须安装了Docker。 This feels like a violation of The Twelve-Factor App design. 这感觉像是违反了十二要素应用程序的设计。 Particularly when you consider the Port Binding tenet: 特别是当您考虑端口绑定原则时:

The twelve-factor app is completely self-contained 十二要素应用程序完全独立

Just as an app should not rely on Apache or nginx to be installed, should an app also not rely on Docker to be installed? 就像应用程序不应该依赖Apache或nginx来安装一样,应用程序也不应该依赖Docker吗?

This led me to wonder if there were a way to "package", "build", or otherwise "compile" the Docker runtime and the image into an executable binary. 这使我想知道是否有办法将Docker运行时和映像“打包”,“构建”或以其他方式“编译”为可执行二进制文件。 Something that could be deployed to any server and run as a single process without the need to install Docker first. 可以部署到任何服务器并可以作为单个进程运行的东西,而无需先安装Docker。

Now, it's possible I'm just thinking about this entirely wrong. 现在,可能我只是在考虑这完全错误。 For that reason, I've detailed the specifics of the concerns and issues I'm having below 因此,我在下面详细说明了所关注的问题和细节

What brought this up 是什么导致了这个

I have a web application project that I have previously been developing using Cloud9 . 我有一个以前使用Cloud9开发的Web应用程序项目。 When I push this project to production, I manually log into the production server via SSH and perform git pull , composer update , npm install , and gulp . 当我将该项目推向生产环境时,我会通过SSH手动登录生产服务器并执行git pullcomposer updatenpm installgulp I bit of a hassle, but for the very small scale I'm working at this has been sufficient and it's a hell of a lot better than uploading all of my dependencies via FTP. 我有点麻烦,但对于规模非常小的,我在这方面的工作已经足够了,这是一个很多比通过FTP上传我的所有依赖更好的地狱

I've occasionally run into challenges with external dependencies, however. 但是,我偶尔会遇到外部依赖项带来的挑战。 Something works fine in development, then when I push it to production I realize the production server has an out-dated version of MySQL. 某些东西在开发中工作正常,然后将其推向生产环境时,我意识到生产服务器具有过时的MySQL版本。 Or the version of pngquant installed on the production server has a bug. 或生产服务器上安装的pngquant版本有错误。 Or the nginx config on the server doesn't match the nginx config in development exactly and it's causing some edge case when routing malformed requests. 或者服务器上的nginx配置与开发中的nginx配置不完全匹配,并且在路由格式错误的请求时会导致一些边缘情况。

All of these problems hit at once today when I tried to load up my project in CodeAnywhere instead of Cloud9. 今天,当我尝试在CodeAnywhere而不是Cloud9中加载项目时,所有这些问题一下子解决了。 I had to ensure: 我必须确保:

  • The PHP version was update PHP版本已更新
  • NodeJS was updated NodeJS已更新
  • NPM was updated NPM已更新
  • cURL was installed cURL已安装
  • All of the required PHP extensions were installed 已安装所有必需的PHP扩展
  • Several GNU libraries were installed 安装了几个GNU库
  • etc 等等

I spent hours trying to get this code running -- and it's code I wrote 我花了几个小时试图使此代码运行-这是编写的代码

Having all of these problems reminded me of The Twelve-Factor App design. 有所有这些问题使我想起了十二要素应用程序的设计。 So I hopped over to the website and did some thinking to figure out what I was doing wrong. 因此,我跳到该网站,并做了一些思考来弄清楚我做错了什么。

Note: I don't just develop solo and then deploy to production directly. 注意:我不只是单独开发然后直接部署到生产中。 I actually have this project set up in BitBucket, I use a ticketing system to track changes, a branch is created per ticket, and branches are checked out in a staging environment before being merged into master. 我实际上是在BitBucket中设置了这个项目,我使用票务系统跟踪更改,为每个票证创建了一个分支,并且在合并到master之前在临时环境中检出了分支。 So I've created a pretty robust system to managing changes to avoid bugs from slipping into production and to allow for agile development. 因此,我创建了一个相当强大的系统来管理更改,以避免错误渗入生产环境并允许进行敏捷开发。 However when it comes to checking out a branch in staging or production it's the same manual crap: git pull , composer update , npm install , gulp . 但是,在登台生产中签出分支时,它是相同的手动操作: git pullcomposer updatenpm installgulp

What I like about Docker 我喜欢Docker的什么

The ability to define my working environment in a source-controlled config file would eliminate the bulk of my issues. 在源代码控制的配置文件中定义我的工作环境的能力将消除我的大部分问题。 Never again would I need to ensure PHP was up to date, ensure NodeJS was up to date, ensure cURL was installed, etc. If the Docker image has all of the dependencies, then it will still have those dependencies when deployed in staging or production. 我再也不需要确保PHP是最新的,确保NodeJS是最新的,确保已安装cURL等。如果Docker映像具有所有依赖项,则在阶段或生产中部署时,它仍将具有那些依赖项。 Consistency of environment between all stages of development would make my life a lot easier. 发展的各个阶段之间的环境的一致性会让我的生活轻松了许多

Also, I haven't yet played around with anything this advanced, but I'm to understand that it's easy with Docker to set up automated deployment. 另外,我还没有玩过任何这种高级功能,但是我想了解到,使用Docker可以很容易地设置自动化部署。 If I could click on a branch in BitBucket then click "send to staging" and a minute later have it deployed and ready to test -- that would save me hours of time each week. 如果我可以单击BitBucket中的一个分支,然后单击“发送到暂存”,然后在一分钟后将其部署并准备进行测试-这样可以每周节省我数小时的时间。 If I could similarly have code automatically deployed to production when it was merged to master, that would not only save me time but would avoid the risk of finished features languishing in BitBucket and never getting in front of a client. 如果我可以类似地将代码合并到母版中时将代码自动部署到生产中,那不仅可以节省我的时间,而且可以避免完成的功能在BitBucket中失效并且永远不会出现在客户面前的风险。

Finally, and this may eventually be a moot point, I'm to understand that Docker makes green/blue deployment much easier. 最后,这最终可能是一个有争议的话题,我将了解Docker使绿色/蓝色部署更加容易。 Currently when I push a new change to production the production server goes offline briefly. 目前,当我对生产进行新更改时,生产服务器会暂时脱机。 Usually only for 15-20 seconds, but once it was an entire hour. 通常只持续15到20秒,但一次是一个小时。 During this 15-20 seconds window I'm running composer update , npm install , and gulp . 在这15到20秒的窗口中,我正在运行composer updatenpm installgulp The former two commands usually don't need to do anything (since my dependencies don't change often) and gulp usually completes within 15 seconds. 前两个命令通常不需要执行任何操作(因为我的依赖关系不会经常更改),并且gulp通常在15秒内完成。 However when dependencies do change or when there are larger issues (like needing to upgrade MySQL) the site can go down for an entire hour. 但是,当依赖关系确实发生变化或存在较大问题(例如需要升级MySQL)时,该站点可能会关闭一整小时。 If I could slowly and calmly deploy to a secondary production server then flip the switch in milliseconds when I verified it was working correctly, this would mean less down time and more happy customers. 如果我可以缓慢而从容地部署到辅助生产服务器,然后在验证运行正常的情况下以毫秒为单位切换该开关,则这将意味着减少停机时间并带来更多客户满意。

Of course the last one may be a moot point because I'm currently not utilizing a "build" step (another part of the twelve-factor app), and all of these steps should be part of the "build" phase -- not the "deploy" phase. 当然,最后一个可能是有争议的,因为我目前没有使用“构建”步骤(十二要素应用程序的另一部分),并且所有这些步骤都应该是“构建”阶段的一部分-而不是“部署”阶段。

What I don't like about Docker 我不喜欢Docker的地方

It's yet one more tool to learn . 它是又一种学习工具 In order to understand and develop for my app you already need to understand: 为了了解和开发我的应用,您已经需要了解:

  • PHP 的PHP
  • Composer 作曲家
  • Symfony Symfony
  • Laravel 拉拉韦尔
  • NodeJS 节点JS
  • NPM NPM
  • Gulp 古尔普
  • Bootstrap 引导程序
  • VueJS VueJS
  • (probably many other things I can't think of right now) (可能我现在想不出的许多其他事情)

Adding "Docker" to that list just means this project gets that much harder to train someone on if I were to ever hand it off to another developer. 如果将“ Docker”添加到该列表中,则意味着如果我将其交付给其他开发人员,则该项目将很难培训某个人。 I want fewer dependencies, not more. 我想要更少的依赖关系,而不是更多。

Also, Docker doesn't come default with any operating system that I'm aware of. 另外,Docker并不是我所知道的任何默认操作系统。 So it's not like cURL where, while it's technically a third-party dependency, you can generally expect people have it. 因此,这与cURL不同,尽管从技术上讲它是第三方依赖项,但通常可以期望人们拥有它。 Instead it's a whole beast that has to be installed separately. 相反,它是一个完整的野兽,必须单独安装。

The former issue I can't really circumvent. 前一个问题我无法真正解决。 If I choose to use Docker, it means adding one more tool to my toolbox for this app. 如果我选择使用Docker,则意味着向该应用程序的工具箱中添加了一个工具。 However the latter issue could be avoided if Docker images can somehow be compiled to stand-alone binaries. 但是,如果可以将Docker映像以某种方式编译为独立的二进制文件,则可以避免后一个问题。

Strictly speaking, you can run containers from docker images without docker. 严格来说,您可以从没有docker的docker镜像运行容器。 Docker images are a well known format. Docker映像是一种众所周知的格式。 See https://github.com/opencontainers/image-spec for more details on this spec. 有关此规范的更多详细信息,请参见https://github.com/opencontainers/image-spec There are multiple implementations of the runtime for OCI images. OCI映像的运行时有多种实现。 Docker itself doesn't actually run containers, that task has been outsourced to containerd. Docker本身实际上并不运行容器,该任务已外包给容器。

However, images ship with a filesystem (also referred to as a bunch of tar files), but containers also expect namespaces to isolate the application. 但是,映像附带文件系统(也称为一堆tar文件),但是容器也希望使用命名空间来隔离应用程序。 You need some kind of runtime to implement this. 您需要某种运行时来实现这一点。 Containers are not just a method to package applications, but also a method to run them in isolation, and trying to pull these apart will be more work and create an even bigger thing to learn than docker itself. 容器不仅是打包应用程序的一种方法,而且是一种隔离运行它们的方法,尝试将它们拆开将比docker本身做更多的工作,并且需要学习的东西更大。

Docker images do indeed require docker installed on the machine, but it's a much smaller issue then having all the other dependencies you mentioned set up. Docker映像确实确实需要在计算机上安装docker,但这是一个小得多的问题,而要设置您提到的所有其他依赖项。

While it's probably possible to create some kind of self contained docker image, it would probably be less portable then docker images, as the binary will be os dependent. 虽然可能可以创建某种自包含的docker映像,但是它可能不如docker映像那样可移植,因为二进制文件将依赖于os。

also consider that if you use a cloud provider, they provide the ability to deploy docker images "directly on the cloud" - that is, you don't have to manage the underlying servers 还应考虑到,如果您使用云提供商,则它们可以“直接在云上”部署docker映像-也就是说,您不必管理底层服务器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM