标签 容器 下的文章

CGManager 是一个核心的特权守护进程,通过一个简单的 D-Bus API 管理你所有的 cgroup。它被设计用来处理嵌套的 LXC 容器以及接受无特权的请求,包括解析用户名称空间的 UID/GID。

组件

cgmanager

这个守护进程在宿主机上运行,​​将 cgroupfs 挂载到一个独立的挂载名称空间(所以它不能从宿主机上看到),绑定 /sys/fs/cgroup/cgmanager/sock 用于传入的 D-Bus 查询,并通常处理宿主机上直接运行的所有客户端。

cgmanager 既接受使用 D-Bus + SCM 凭证的身份验证请求,用于在命名空间之间转换 uid、gid 和 pid,也可以使用简单的 “unauthenticated”(只是初始的 ucred)D-Bus 来查询来自宿主机级别的查询。

cgproxy

你可能会在两种情况下看到这个守护进程运行。在宿主机上,如果你的内核老于 3.8(没有 pidns 连接支持)或处于容器中(只有 cgproxy 运行)。

cgproxy 本身并不做任何 cgroup 配置更改,而是如其名称所示,代理请求给主 cgmanager 进程。

这是必要的,所以一个进程可以直接使用 D-Bus(例如使用 dbus-send)与 /sys/fs/cgroup/cgmanager/sock 进行通信。

之后 cgproxy 将从该查询中得到 ucred,并对真正的 cgmanager 套接字进行身份验证的 SCM 查询,并通过 ucred 结构体传递参数,使它们能够正确地转换为 cgmanager 可以理解的宿主机命名空间 。

cgm

一个简单的命令行工具,与 D-Bus 服务通信,并允许你从命令行执行所有常见的 cgroup 操作。

通信协议

如上所述,cgmanager 和 cgproxy 使用 D-Bus。建议外部客户端(所以不要是 cgproxy)使用标准的 D-Bus API,不要试图实现 SCM creds 协议,因为它是不必要的,并且容易出错。

相反,只要简单假设与 /sys/fs/cgroup/cgmanager/sock 的通信总是正确的。

cgmanager API 仅在独立的 D-Bus 套接字上可用,cgmanager 本身不连接到系统总线,所以 cgmanager/cgproxy 不要求有运行中的 dbus 守护进程。

你可以在这里阅读更多关于 D-Bus API。

许可证

CGManager 是免费软件,大部分代码是根据 GNU LGPLv2.1+ 许可条款发布的,一些二进制文件是在 GNU GPLv2 许可下发布的。

该项目的默认许可证是 GNU LGPLv2.1+

支持

CGManager 的稳定版本支持依赖于 Linux 发行版以及它们自己承诺推出稳定修复和安全更新。

你可以从 Canonical Ltd 获得对 Ubuntu LTS 版本的 CGManager 的商业支持。


via: https://linuxcontainers.org/cgmanager/introduction/

作者:Canonical Ltd. 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

虽然大多数 Chromebook 已经能够运行 Android 应用程序,但似乎 Google 希望在其 Chrome OS 上增加在容器或虚拟机上运行 Linux 应用程序的支持。

一则 Reddit 消息,谷歌显然正在开发 Chrome OS 的 Crostini 项目,以在 Chrome OS 上支持 Linux 的虚拟机。这条消息指出,最近的 Chromium 提交 会解释一条新的设备策略,如果其设置为真,那么将允许在 Chrome OS 上运行 Linux 虚拟机。

“如果该策略未设置或设置为真,那么在 Chrome OS 上运行 Linux 虚拟机是允许的。未设置也是允许的意味着非管理的设备是允许运行 Linux 虚拟机的。此时,要让 Linux 虚拟机运行起来,也需要启用 Finch 试验性特性,当该特性完全启用后,Finch 控制逻辑将被移除。”

在 Chrome OS 上运行 Linux 应用将让多少人梦想成真

这表明在你的 Chromebook 上运行 Linux 应用的梦想终于要变成了真的。不会让你等待太久,当这个新策略逐步经历 Chrome OS 的 Dev、Beta 和 Stable 等频道之后,你就可以在 Chrome OS 上尝鲜 Linux 应用了。

ChromeUnboxed 的消息,该特性或许出现在五月份早一些的时候 Chrome OS 66 发布时。显然这是首次在 Chrome OS 上支持容器化的 Linux 应用,我们对此功能表示无比的高兴,而这也将进一步让更多的人去使用 Chrome OS。

Chromebook 操作系统的当前版本是 Google 上个月发布的 Chrome OS 64,它支持并行运行 Android 应用,以及一些其它的核心功能,而且这个补丁也为 Chromebook 解决了 Meltdown 和 Spectre 安全缺陷影响

当你正在创建 LXD 容器的时候,你希望它们能被预先配置好。例如在容器一启动就自动执行 apt update来安装一些软件包,或者运行一些命令。

这篇文章将讲述如何用 cloud-init 来对 LXD 容器进行进行早期初始化

接下来,我们将创建一个包含cloud-init指令的LXD profile,然后启动一个新的容器来使用这个profile。

如何创建一个新的 LXD profile

查看已经存在的 profile:

$ lxc profile list
+---------|---------+
| NAME    | USED BY |
+---------|---------+
| default | 11      |
+---------|---------+

我们把名叫 default 的 profile 复制一份,然后在其内添加新的指令:

$ lxc profile copy default devprofile

$ lxc profile list
+------------|---------+
| NAME       | USED BY |
+------------|---------+
| default    | 11      |
+------------|---------+
| devprofile | 0       |
+------------|---------+

我们就得到了一个新的 profile: devprofile。下面是它的详情:

$ lxc profile show devprofile
config:
 environment.TZ: ""
description: Default LXD profile
devices:
 eth0:
 nictype: bridged
 parent: lxdbr0
 type: nic
 root:
 path: /
 pool: default
 type: disk
name: devprofile
used_by: []

注意这几个部分: config:description:devices:name:used_by:,当你修改这些内容的时候注意不要搞错缩进。(LCTT 译注:因为这些内容是 YAML 格式的,缩进是语法的一部分)

如何把 cloud-init 添加到 LXD profile 里

cloud-init 可以添加到 LXD profile 的 config 里。当这些指令将被传递给容器后,会在容器第一次启动的时候执行。

下面是用在示例中的指令:

 package_upgrade: true
 packages:
 - build-essential
 locale: es_ES.UTF-8
 timezone: Europe/Madrid
 runcmd:
 - [touch, /tmp/simos_was_here]

package_upgrade: true 是指当容器第一次被启动时,我们想要 cloud-init 运行 sudo apt upgradepackages: 列出了我们想要自动安装的软件。然后我们设置了 localetimezone。在 Ubuntu 容器的镜像里,root 用户默认的 localeC.UTF-8,而 ubuntu 用户则是 en_US.UTF-8。此外,我们把时区设置为 Etc/UTC。最后,我们展示了如何使用 runcmd 来运行一个 Unix 命令

我们需要关注如何将 cloud-init 指令插入 LXD profile。

我首选的方法是:

$ lxc profile edit devprofile

它会打开一个文本编辑器,以便你将指令粘贴进去。结果应该是这样的

$ lxc profile show devprofile
config:
  environment.TZ: ""
  user.user-data: |
    #cloud-config
    package_upgrade: true
    packages:
      - build-essential
    locale: es_ES.UTF-8
    timezone: Europe/Madrid
    runcmd:
      - [touch, /tmp/simos_was_here]
description: Default LXD profile
devices:
  eth0:
    nictype: bridged
    parent: lxdbr0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: devprofile
used_by: []

如何使用 LXD profile 启动一个容器

使用 profile devprofile 来启动一个新容器:

$ lxc launch --profile devprofile ubuntu:x mydev

然后访问该容器来查看我们的指令是否生效:

$ lxc exec mydev bash
root@mydev:~# ps ax
 PID TTY STAT TIME COMMAND
 1 ? Ss 0:00 /sbin/init
 ...
 427 ? Ss 0:00 /usr/bin/python3 /usr/bin/cloud-init modules --mode=f
 430 ? S 0:00 /bin/sh -c tee -a /var/log/cloud-init-output.log
 431 ? S 0:00 tee -a /var/log/cloud-init-output.log
 432 ? S 0:00 /usr/bin/apt-get --option=Dpkg::Options::=--force-con
 437 ? S 0:00 /usr/lib/apt/methods/http
 438 ? S 0:00 /usr/lib/apt/methods/http
 440 ? S 0:00 /usr/lib/apt/methods/gpgv
 570 ? Ss 0:00 bash
 624 ? S 0:00 /usr/lib/apt/methods/store
 625 ? R+ 0:00 ps ax
root@mydev:~#

如果我们连接得够快,通过 ps ax 将能够看到系统正在更新软件。我们可以从 /var/log/cloud-init-output.log 看到完整的日志:

Generating locales (this might take a while)...
 es_ES.UTF-8... done
Generation complete.

以上可以看出 locale 已经被更改了。root 用户还是保持默认的 C.UTF-8,只有非 root 用户 ubuntu 使用了新的locale 设置。

Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB]

以上是安装软件包之前执行的 apt update

The following packages will be upgraded:
 libdrm2 libseccomp2 squashfs-tools unattended-upgrades
4 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 211 kB of archives.

以上是在执行 package_upgrade: true 和安装软件包。

The following NEW packages will be installed:
 binutils build-essential cpp cpp-5 dpkg-dev fakeroot g++ g++-5 gcc gcc-5
 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl

以上是我们安装 build-essential 软件包的指令。

runcmd 执行的结果如何?

root@mydev:~# ls -l /tmp/
total 1
-rw-r--r-- 1 root root 0 Jan 3 15:23 simos_was_here
root@mydev:~#

可见它已经生效了!

结论

当我们启动 LXD 容器的时候,我们常常需要默认启用一些配置,并且希望能够避免重复工作。通常解决这个问题的方法是创建 LXD profile,然后把需要的配置添加进去。最后,当我们启动新的容器时,只需要应用该 LXD profile 即可。


via: https://blog.simos.info/how-to-preconfigure-lxd-containers-with-cloud-init/

作者:Simos Xenitellis 译者:kaneg 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

提要:想要知道开源许可证对 Linux 容器有什么影响吗?以下问题您需要了解。

尽管目前开源软件已经成为主流,但是不断涌现的软件新技术以及重新流行的旧技术有时也会引发对开源许可证的强烈担忧。大多数情况下,大家关注的焦点是 GPL 许可证,特别是经常(有时是误导性的)被描述为 GPL 衍生作品问题的 左版 copyleft 范围问题。

将该问题结构化的一个不完美方式是:遵循 GPL 许可证的代码在某种意义上与专有代码相结合,形成一个单独的修改后作品,是否可以解释为该专有代码受到 GPL 许可证的约束?虽然我们还没有看到很多针对 Linux 容器的问题,但随着容器的采用持续增长,我们预计会有更多的问题提出来。不过,有相当简单的方式可以表明,容器不会引发新的或有关 GPL 范围的问题。

法规和判例在解释类似 GPL 这样的许可证方面几乎没有什么帮助。另一方面,即使是在自由软件基金会(FSF)不是相关软件版权持有者的典型情况下,我们中的许多人也重视 FSF 作为 GPL 起草者和管理者的解释性观点。除了作为许可证文本的作者之外,FSF 多年来一直致力于向社区提供有关许可证的评论和指导。基于自由软件政策的公共利益使命和领导力,FSF 的观点具有特殊的可信度和影响力。

FSF 关于 GPL 解释的现有指导,有助于理解在容器中将 GPL 代码和非 GPL 代码包含在内所产生的效果。FSF 在界定左版范围时重点考虑了进程的边界,以及多个软件组件之间的通信机制和语义,以确定它们的紧密集成程度是否足以被视为 GPL 意义下的单个程序。例如,GNU 许可证常见问题解答认为,在没有足够 “密切” intimate 通信的情况下,管道、套接字和命令行参数通常可以被隐含认为是具备独立性的机制

考虑容器中有 GPL 代码和专有代码可能共存并执行的情况,实际上,容器是一个孤立的用户空间栈。在 OCI 容器映像格式中,代码被打包为一组文件系统的变更层,基本层通常是一个没有内核的精简传统 Linux 发行版。与非容器化的 Linux 发行版的用户空间一样,这些基本层包括许多遵循 GPL 许可证(GPL v2 以及 GPL v3)的软件包,以及许多遵循被认为与 GPL 不兼容许可证的软件包,并且通常作为专有以及开源应用的运行环境。GPL v2 中“ 单纯聚合 mere aggregation ”条款(以及 GPL v3 中有关“聚合”的条款)表明,这种组合通常是可以被接受的,在 GPL 中进行了特别考虑,如果不兼容的被许可组件是分离和独立的,就不会影响两个程序的许可。

当然,在特定情况下,两个组件之间的关系可能不是“单纯聚合”,但是在 Linux 系统上的非容器化用户空间中运行的软件也是如此。容器或容器映像的技术构成中没有任何暗示表明需要应用特殊形式的左版范围分析。

因此,当考察运行在容器中的代码和运行在容器外面的代码之间的关系时,几乎肯定会满足“分离和独立”的标准。代码将作为单独的进程运行,使用容器的整个技术要点是与运行在系统上的其他软件隔离。

现在考虑两个组件的情况,其中一个遵循 GPL 许可证,另一个为专有软件,它们运行在分离但可能交互的容器中,也许作为使用微服务体系结构设计的应用程序的一部分。在没有特别不寻常事实的情况下,我们不应该期望看到左版的范围跨越多个容器。分离的容器涉及分离的进程。通过网络接口在容器之间进行通信类似于管道、套接字等机制,多容器微服务场景似乎排除了 FSF 所定义的“密切”通信。使用多个容器的应用程序的组成可能不是 GPL 范围问题的决定因素,但它使组件之间的技术边界更加明显,并为争论“分离性”提供了强有力的基础。这其中也没有容器的技术特征暗示对左版的范围分析应用不同或更严格的方法。

过度关心分发 GPL 代码潜在影响的企业可能会试图禁止其开发人员将任何此类代码添加到计划分发的容器映像中,目的就是为了避免依据 GPL 许可证分发代码,但这是一个容易受到质疑的策略。如上所述,常规容器映像的基础层将包含多个遵循 GPL 的组件。如果该公司将容器映像推送到注册表中,通常无法保证这其中不包含基础层,即使它被广泛共享。

另一方面,通过隔离 GPL 代码和专有代码,企业可能会决定采用容器化作为减少左版范围影响的一种手段,虽然人们希望基于技术上的益处,而不是莫须有的对 GPL 焦虑所带来的法律担忧来推动该决策。而在非容器化环境中,两个相互作用的软件组件之间的关系往往是单纯聚合,容器化所提供的“分离性”证据可能让那些担心 GPL 范围的人们感到安慰。

共享容器映像时,可能会出现开源许可证合规义务问题。但是,对于容器来说,没有什么技术上的不同或独一无二的东西可以改变这些义务的性质,或者使它们更难满足。关于左版的范围,容器化应该能够缓解过度的担忧。


作者简介:Richard Fontana 是红帽公司法律部门产品和技术团队的高级商业顾问。 他的大部分工作都集中在开源相关的法律问题上。

译者简介:薛亮,集慧智佳知识产权咨询公司高级咨询师,擅长专利检索、专利分析、竞争对手跟踪、FTO分析、开源软件知识产权风险分析,致力于为互联网企业、高科技公司提供知识产权咨询服务。

在我刚开始学习 Kubernetes(大约是一年半以前吧?)时,我真的不明白为什么应该去关注它。

在我使用 Kubernetes 全职工作了三个多月后,我才逐渐明白了为什么我应该使用它。(我距离成为一个 Kubernetes 专家还很远!)希望这篇文章对你理解 Kubernetes 能做什么会有帮助!

我将尝试去解释我对 Kubernetes 感兴趣的一些原因,而不去使用 “ 原生云 cloud native ”、“ 编排系统 orchestration ”、“ 容器 container ”,或者任何 Kubernetes 专用的术语 :)。我去解释的这些观点主要来自一位 Kubernetes 操作者/基础设施工程师,因为,我现在的工作就是去配置 Kubernetes 和让它工作的更好。

我不会去尝试解决一些如 “你应该在你的生产系统中使用 Kubernetes 吗?”这样的问题。那是非常复杂的问题。(不仅是因为“生产系统”根据你的用途而总是有不同的要求)

Kubernetes 可以让你无需设置一台新的服务器即可在生产系统中运行代码

我首次被说教使用 Kubernetes 是与我的伙伴 Kamal 的下面的谈话:

大致是这样的:

  • Kamal: 使用 Kubernetes 你可以通过一条命令就能设置一台新的服务器。
  • Julia: 我觉得不太可能吧。
  • Kamal: 像这样,你写一个配置文件,然后应用它,这时候,你就在生产系统中运行了一个 HTTP 服务。
  • Julia: 但是,现在我需要去创建一个新的 AWS 实例,明确地写一个 Puppet 清单,设置服务发现,配置负载均衡,配置我们的部署软件,并且确保 DNS 正常工作,如果没有什么问题的话,至少在 4 小时后才能投入使用。
  • Kamal: 是的,使用 Kubernetes 你不需要做那么多事情,你可以在 5 分钟内设置一台新的 HTTP 服务,并且它将自动运行。只要你的集群中有空闲的资源它就能正常工作!
  • Julia: 这儿一定是一个“坑”。

这里有一种陷阱,设置一个生产用 Kubernetes 集群(在我的经险中)确实并不容易。(查看 Kubernetes 艰难之旅 中去开始使用时有哪些复杂的东西)但是,我们现在并不深入讨论它。

因此,Kubernetes 第一个很酷的事情是,它可能使那些想在生产系统中部署新开发的软件的方式变得更容易。那是很酷的事,而且它真的是这样,因此,一旦你使用一个运作中的 Kubernetes 集群,你真的可以仅使用一个配置文件就在生产系统中设置一台 HTTP 服务(在 5 分钟内运行这个应用程序,设置一个负载均衡,给它一个 DNS 名字,等等)。看起来真的很有趣。

对于运行在生产系统中的代码,Kubernetes 可以提供更好的可见性和可管理性

在我看来,在理解 etcd 之前,你可能不会理解 Kubernetes 的。因此,让我们先讨论 etcd!

想像一下,如果现在我这样问你,“告诉我你运行在生产系统中的每个应用程序,它运行在哪台主机上?它是否状态很好?是否为它分配了一个 DNS 名字?”我并不知道这些,但是,我可能需要到很多不同的地方去查询来回答这些问题,并且,我需要花很长的时间才能搞定。我现在可以很确定地说不需要查询,仅一个 API 就可以搞定它们。

在 Kubernetes 中,你的集群的所有状态 – 运行中的应用程序 (“pod”)、节点、DNS 名字、 cron 任务、 等等 —— 都保存在一个单一的数据库中(etcd)。每个 Kubernetes 组件是无状态的,并且基本是通过下列方式工作的:

  • 从 etcd 中读取状态(比如,“分配给节点 1 的 pod 列表”)
  • 产生变化(比如,“在节点 1 上运行 pod A”)
  • 更新 etcd 中的状态(比如,“设置 pod A 的状态为 ‘running’”)

这意味着,如果你想去回答诸如 “在那个可用区中有多少台运行着 nginx 的 pod?” 这样的问题时,你可以通过查询一个统一的 API(Kubernetes API)去回答它。并且,你可以在每个其它 Kubernetes 组件上运行那个 API 去进行同样的访问。

这也意味着,你可以很容易地去管理每个运行在 Kubernetes 中的任何东西。比如说,如果你想要:

  • 部署实现一个复杂的定制的部署策略(部署一个东西,等待 2 分钟,部署 5 个以上,等待 3.7 分钟,等等)
  • 每当推送到 github 上一个分支,自动化 启动一个新的 web 服务器
  • 监视所有你的运行的应用程序,确保它们有一个合理的内存使用限制。

这些你只需要写一个程序与 Kubernetes API(“controller”)通讯就可以了。

另一个关于 Kubernetes API 的令人激动的事情是,你不会局限于 Kubernetes 所提供的现有功能!如果对于你要部署/创建/监视的软件有你自己的方案,那么,你可以使用 Kubernetes API 去写一些代码去达到你的目的!它可以让你做到你想做的任何事情。

即便每个 Kubernetes 组件都“挂了”,你的代码将仍然保持运行

关于 Kubernetes 我(在各种博客文章中 :))承诺的一件事情是,“如果 Kubernetes API 服务和其它组件‘挂了’也没事,你的代码将一直保持运行状态”。我认为理论上这听起来很酷,但是我不确定它是否真是这样的。

到目前为止,这似乎是真的!

我已经断开了一些正在运行的 etcd,发生了这些情况:

  1. 所有的代码继续保持运行状态
  2. 不能做 新的 事情(你不能部署新的代码或者生成变更,cron 作业将停止工作)
  3. 当它恢复时,集群将赶上这期间它错过的内容

这样做意味着如果 etcd 宕掉,并且你的应用程序的其中之一崩溃或者发生其它事情,在 etcd 恢复之前,它不能够恢复。

Kubernetes 的设计对 bug 很有弹性

与任何软件一样,Kubernetes 也会有 bug。例如,到目前为止,我们的集群控制管理器有内存泄漏,并且,调度器经常崩溃。bug 当然不好,但是,我发现 Kubernetes 的设计可以帮助减轻它的许多核心组件中的错误的影响。

如果你重启动任何组件,将会发生:

  • 从 etcd 中读取所有的与它相关的状态
  • 基于那些状态(调度 pod、回收完成的 pod、调度 cron 作业、按需部署等等),它会去做那些它认为必须要做的事情

因为,所有的组件并不会在内存中保持状态,你在任何时候都可以重启它们,这可以帮助你减轻各种 bug 的影响。

例如,如果在你的控制管理器中有内存泄露。因为,控制管理器是无状态的,你可以每小时定期去重启它,或者,在感觉到可能导致任何不一致的问题发生时重启它。又或者,在调度器中遇到了一个 bug,它有时忘记了某个 pod,从来不去调度它们。你可以每隔 10 分钟来重启调度器来缓减这种情况。(我们并不会这么做,而是去修复这个 bug,但是,你可以这样做 :))

因此,我觉得即使在它的核心组件中有 bug,我仍然可以信任 Kubernetes 的设计可以让我确保集群状态的一致性。并且,总在来说,随着时间的推移软件质量会提高。唯一你必须去操作的有状态的东西就是 etcd。

不用过多地讨论“状态”这个东西 —— 而我认为在 Kubernetes 中很酷的一件事情是,唯一需要去做备份/恢复计划的东西是 etcd (除非为你的 pod 使用了持久化存储的卷)。我认为这样可以使 Kubernetes 运维比你想的更容易一些。

在 Kubernetes 之上实现新的分布式系统是非常容易的

假设你想去实现一个分布式 cron 作业调度系统!从零开始做工作量非常大。但是,在 Kubernetes 里面实现一个分布式 cron 作业调度系统是非常容易的!(仍然没那么简单,毕竟它是一个分布式系统)

我第一次读到 Kubernetes 的 cron 作业控制器的代码时,我对它是如此的简单感到由衷高兴。去读读看,其主要的逻辑大约是 400 行的 Go 代码。去读它吧! => cronjob\_controller.go <=

cron 作业控制器基本上做的是:

  • 每 10 秒钟:

    • 列出所有已存在的 cron 作业
    • 检查是否有需要现在去运行的任务
    • 如果有,创建一个新的作业对象去调度,并通过其它的 Kubernetes 控制器实际运行它
    • 清理已完成的作业
    • 重复以上工作

Kubernetes 模型是很受限制的(它有定义在 etcd 中的资源模式,控制器读取这个资源并更新 etcd),我认为这种相关的固有的/受限制的模型,可以使它更容易地在 Kubernetes 框架中开发你自己的分布式系统。

Kamal 给我说的是 “Kubernetes 是一个写你自己的分布式系统的很好的平台” ,而不是“ Kubernetes 是一个你可以使用的分布式系统”,并且,我觉得它真的很有意思。他做了一个 为你推送到 GitHub 的每个分支运行一个 HTTP 服务的系统 的原型。这花了他一个周末的时间,大约 800 行 Go 代码,我认为它真不可思议!

Kubernetes 可以使你做一些非常神奇的事情(但并不容易)

我一开始就说 “kubernetes 可以让你做一些很神奇的事情,你可以用一个配置文件来做这么多的基础设施,它太神奇了”。这是真的!

为什么说 “Kubernetes 并不容易”呢?是因为 Kubernetes 有很多部分,学习怎么去成功地运营一个高可用的 Kubernetes 集群要做很多的工作。就像我发现它给我了许多抽象的东西,我需要去理解这些抽象的东西才能调试问题和正确地配置它们。我喜欢学习新东西,因此,它并不会使我发狂或者生气,但是我认为了解这一点很重要 :)

对于 “我不能仅依靠抽象概念” 的一个具体的例子是,我努力学习了许多 Linux 上网络是如何工作的,才让我对设置 Kubernetes 网络稍有信心,这比我以前学过的关于网络的知识要多很多。这种方式很有意思但是非常费时间。在以后的某个时间,我或许写更多的关于设置 Kubernetes 网络的困难/有趣的事情。

或者,为了成功设置我的 Kubernetes CA,我写了一篇 2000 字的博客文章,述及了我不得不学习 Kubernetes 不同方式的 CA 的各种细节。

我觉得,像 GKE (Google 的 Kubernetes 产品) 这样的一些监管的 Kubernetes 的系统可能更简单,因为,他们为你做了许多的决定,但是,我没有尝试过它们。


via: https://jvns.ca/blog/2017/10/05/reasons-kubernetes-is-cool/

作者:Julia Evans 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

微服务与容器天生匹配,但是你需要避开一些常见的陷阱。

因为微服务和容器是 天生的“一对”,所以一起来使用它们,似乎也就不会有什么问题。当我们将这对“天作之合”投入到生产系统后,你就会发现,随着你的 IT 基础的提升,等待你的将是大幅上升的成本。是不是这样的?

(让我们等一下,等人们笑声过去)

是的,很遗憾,这并不是你所希望的结果。虽然这两种技术的组合是非常强大的,但是,如果没有很好的规划和适配,它们并不能发挥出强大的性能来。在前面的文章中,我们整理了如果你想 使用它们你应该掌握的知识。但是,那些都是组织在容器中使用微服务时所遇到的常见问题。

事先了解这些可能出现的问题,能够帮你避免这些问题,为你的成功奠定更坚实的基础。

微服务和容器技术的出现是基于组织的需要、知识、资源等等更多的现实的要求。Mac Browning 说,“他们最常犯的一个 [错误] 是试图一次就想‘搞定’一切”,他是 DigitalOcean 的工程部经理。“而真正需要面对的问题是,你的公司应该采用什么样的容器和微服务。”

努力向你的老板和同事去解释什么是微服务?阅读我们的入门读本[如何简单明了地解释微服务。]

Browning 和其他的 IT 专业人员分享了他们遇到的,在组织中使用容器化微服务时的五个陷阱,特别是在他们的生产系统生命周期的早期时候。在你的组织中需要去部署微服务和容器时,了解这些知识,将有助于你去评估微服务和容器化的部署策略。

1、 在部署微服务和容器化上,试图同时从零开始

如果你刚开始从完全的单例应用开始改变,或者如果你的组织在微服务和容器化上还没有足够的知识储备,那么,请记住:微服务和容器化并不是拴在一起、不可分别部署的。这就意味着,你可以发挥你公司内部专家的技术特长,先从部署其中的一个开始。Sungard Availability Services]5 的资深 CTO 架构师 Kevin McGrath 建议,通过首先使用容器化来为你的团队建立知识和技能储备,通过对现有应用或者新应用进行容器化部署,接着再将它们迁移到微服务架构,这样才能最终感受到它们的优势所在。

McGrath 说,“微服务要想运行的很好,需要公司经过多年的反复迭代,这样才能实现快速部署和迁移”,“如果组织不能实现快速迁移,那么支持微服务将很困难。实现快速迁移,容器化可以帮助你,这样就不用担心业务整体停机”。

2、 从一个面向客户的或者关键的业务应用开始

对组织来说,一个相关陷阱恰恰就是从容器、微服务、或者两者同时起步:在尝试征服一片丛林中的雄狮之前,你应该先去征服处于食物链底端的一些小动物,以取得一些实践经验。

在你的学习过程中可以预期会有一些错误出现 —— 你是希望这些错误发生在面向客户的关键业务应用上,还是,仅对 IT 或者其他内部团队可见的低风险应用上?

DigitalOcean 的 Browning 说,“如果整个生态系统都是新的,为了获取一些微服务和容器方面的操作经验,那么,将它们先应用到影响面较低的区域,比如像你的持续集成系统或者内部工具,可能是一个低风险的做法。”你获得这方面的经验以后,当然会将这些技术应用到为客户提供服务的生产系统上。而现实情况是,不论你准备的如何周全,都不可避免会遇到问题,因此,需要提前为可能出现的问题制定应对之策。

3、 在没有合适的团队之前引入了太多的复杂性

由于微服务架构的弹性,它可能会产生复杂的管理需求。

作为 Red Hat 技术的狂热拥护者,Gordon Haff 最近写道,“一个符合 OCI 标准的容器运行时本身管理单个容器是很擅长的,但是,当你开始使用多个容器和容器化应用时,并将它们分解为成百上千个节点后,管理和编配它们将变得极为复杂。最终,你将需要回过头来将容器分组来提供服务 —— 比如,跨容器的网络、安全、测控”。

Haff 提示说,“幸运的是,由于容器是可移植的,并且,与之相关的管理栈也是可移植的”。“这时出现的编配技术,比如像 Kubernetes ,使得这种 IT 需求变得简单化了”(更多内容请查阅 Haff 的文章:容器化为编写应用带来的 5 个优势)。

另外,你需要合适的团队去做这些事情。如果你已经有 DevOps shop,那么,你可能比较适合做这种转换。因为,从一开始你已经聚集了相关技能的人才。

Mike Kavis 说,“随着时间的推移,部署了越来越多的服务,管理起来会变得很不方便”,他是 Cloud Technology Partners 的副总裁兼首席云架构设计师。他说,“在 DevOps 的关键过程中,确保各个领域的专家 —— 开发、测试、安全、运营等等 —— 全部都参与进来,并且在基于容器的微服务中,在构建、部署、运行、安全方面实现协作。”

4、 忽视重要的需求:自动化

除了具有一个合适的团队之外,那些在基于容器化的微服务部署比较成功的组织都倾向于以“实现尽可能多的自动化”来解决固有的复杂性。

Carlos Sanchez 说,“实现分布式架构并不容易,一些常见的挑战,像数据持久性、日志、排错等等,在微服务架构中都会变得很复杂”,他是 CloudBees 的资深软件工程师。根据定义,Sanchez 提到的分布式架构,随着业务的增长,将变成一个巨大无比的繁重的运营任务。“服务和组件的增殖,将使得运营自动化变成一项非常强烈的需求”。Sanchez 警告说。“手动管理将限制服务的规模”。

5、 随着时间的推移,微服务变得越来越臃肿

在一个容器中运行一个服务或者软件组件并不神奇。但是,这样做并不能证明你就一定在使用微服务。Manual Nedbal, ShieldX Networks 的 CTO,他警告说,IT 专业人员要确保,随着时间的推移,微服务仍然是微服务。

Nedbal 说,“随着时间的推移,一些软件组件积累了大量的代码和特性,将它们放在一个容器中将会产生并不需要的微服务,也不会带来相同的优势”,也就是说,“随着组件的变大,工程师需要找到合适的时机将它们再次分解”。


via: https://enterprisersproject.com/article/2017/9/using-microservices-containers-wisely-5-pitfalls-avoid

作者:Kevin Casey 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出