CNCF 会重蹈 OpenStack 的覆辙吗?|航海日志 Vol.25


➤ CNCF 会重蹈 OpenStack 的覆辙吗?


CNCF(Cloud Native Computing Foundation),即云原生计算基金会,于 2015 年 7 月成立,隶属于 Linux 基金会,初衷围绕“云原生”服务云计算,致力于维护和集成开源技术,支持编排容器化微服务架构应用。html


因为最近大佬级别的云提供商的加入,云原生计算基金会(CNCF)很快就站在了开源容器世界的中心。在过去的几个星期里, CNCF 吸引了微软和亚马逊的 Web 服务 (AWS)的加入。他们的加入对于这个原本就隶属于 Linux 基金会的组织来讲,无疑是如虎添翼。web

而伴随着 Kubernetes 的成功,和市场对于容器技术的需求逐渐扩大,CNCF 的声势也日渐浩大。微软和 AWS 相继加入 CNCF,对于 CNCF、开源和 Kubernetes 来讲, 也是一个巨大的胜利。docker


尽管这些会给 CNCF 带来规模和潜在的影响,但组织仍然面临挑战。数据库


CNCF 执行董事 Dan Kohn 表示:npm


CNCF 一直很是专一于确保全部成员在迅速扩张的组织中都有各自的表明性。CNCF 的最大优点是他们足够新兴,因此他们可以向前人学习,其的愿景是只犯新的错误, 而不是照搬过去的错误。因此推断 CNCF 会重蹈 OpenStack 的覆辙,这样的论断是错误的。api


而对 OpenStack 来讲,许多运营商早期的时候使用 OpenStack 来实现他们的 SDN 计划,而如今供应商社区则没法提供所需的解决方案。同时,OpenStack 存在的一些问题还归咎于它没法处理一些较大成员的不一样需求。安全


而为了规避这样的问题,CNCF 留出了在供应商之上添加更多产品的余地,让社区来决定其有用性。这样他们的生存和死亡由自身的优点决定,但 OpenStack 社区人为地支撑着将死的平台。bash


同时,Dan Kohn 也认可 Kubernetes 一直处于爆炸性增加的状态。若是能管理这一增加,则能实现组织目前最大的成就。网络

➤ Kubernetes 1.7.4 版本发布


8 月 17 日, Kubernetes 1.7.4 版本发布,相比 1.7.3 版本共有 17 处明显变化,例如:架构


  • 修复建立或更新 ELB 会修改全局定义的 Security Group Bug

  • 修复 kubefed 在不一样版本 RBAC 建立问题

  • 修复 API Server Watch Cache 中一个 Bug

  • Azure:容许 VNet 在一个单独的资源组中

  • Cluster Autoscaler -修复了与 taints 相关的问题,并更新了 kube – proxy cpu请求

  • 以 Stackdriver 模式收集来自 Heapster 的 Metrics

  • GCE:Bump GLBC 版本更新到 0.9.6

  • 更新 Heapster 版本 1.4.1


➤ Docker Tips:将容器的文件重定向到您的 Docker 主机


每隔一段时间,我都须要将容器的文件转存到个人 Docker 主机上。在这里向你们提供一种简单的方法。

有时为了调试,您可能想将容器内部的配置文件的内容复制到 Docker 主机,以便您在本身喜欢的代码编辑器中打开它,或将其发送给别人。这对于已经运行的 Docker 容器来讲很是方便,而且您不但愿用 volume 从新启动它,由于你想要马上就获取这个文件。

完成如下两点你就能够达成目的:

# 重写那个镜像的 Dockerfile 的 CMD, 来cat到你想要的文件
docker run --rm alpine cat /etc/hosts复制代码

以上步骤将打印出容器的 /etc/hosts 文件的内容

# 修改命令将该输出重定向到 Docker 主机上的新文件。
docker run --rm alpine cat /etc/hosts > /tmp/alpinehosts复制代码

你能够运行命令ls -la /tmp | grep alpinehosts来进行验证。

固然,若是您在 Docker 主机上运行 Windows 而不是 MacOS 或 Linux,则你的命令须要进行一些小的调整。例如,在 Windows 上不起做用。若是您使用 PowerShell 等,您将须要 Google 一下如何将输出重定向到文件。

另外,在这两种状况下,您都须要将Cat指令安装在 Docker 镜像中,但全部主要的 Linux 版本都已经默认安装了(包括 Alpine)。


➤ 从环境变量到 Docker secrets

12 Factor app

12 Factor app 中的第三项告诉咱们要将配置存储在环境中。

它还提供了如下内容的示例:

  • 资源处理数据库,Memcached 和其余后台服务

  • 对外部服务的认证,如 Amazon S3 或 Twitter

  • 部署的规范主机名

咱们想知道现在是否仍然推荐这种方法,而且使用它的风险程度。在这篇文章中,咱们将一个简单的应用程序为例,看看如何修改它以更安全的方式来处理这些敏感的信息。

在 Docker 世界运行的应用

在过去的几年中,咱们看到了许多应用在开发和部署方面都产生了变化。这主要是由于Docker 平台的流行。应用程序如今主要采用微服务体系结构:它们由多个隔离式服务组成。使用 Docker Compose 文件格式定义微服务应用程序如今很是广泛。此格式定义了服务及其使用的组件(网络,卷,...)。如下是用于定义由如下组成的 Web 应用程序的 Docker Compose 文件(其默认名称为 docker-compose.yml)的简单示例:

version: "3.3"
services:
  db:
    image: mongo:3.4
    network:
      - backend
    volumes:
      — mongo-data:/data/db
    deploy:
      restart_policy:
        condition: on-failure
  api:
    image: lucj/api:1.0
    networks:
      - backend    
    deploy:
      restart_policy:
        condition: on-failure
  web:
    image: lucj/web:1.0
    networks:
      - frontend
      - backend    
    deploy:
      restart_policy:
        condition: on-failure    
volumes:
  mongo-data:
networks:
  frontend:  
  backend:复制代码

使用环境变量处理 AWS 凭据

当咱们深刻了解 api 服务,假设这须要 AWS S3 的一些凭据。api 服务是在 Node.js 中编写的。使用 aws-sdk npm 模块链接到 Amazon API 的代码相似于如下内容。

// Middleware handling user's profile images const AWS = require('aws-sdk'), config = require(‘../config’), aws_config = config.amazon; // Configure AWS SDK AWS.config.update(aws_config.credentials); // Define S3 bucket var s3Bucket = new AWS.S3( { params: {Bucket: aws_config.bucket} } ) ... // Upload image object s3Bucket.putObject(obj, function(err){ if (err) { log.error(err); return next(err); } else { return next(); } }复制代码

以上代码中所需的配置模块在一些其余配置内容中定义了 AWS 凭据。咱们在这里看到,每一个元素从一个环境变量获取它的值。

// config.js
module.exports = {
...
  "amazon":{
    "credentials": {
      "accessKeyID": process.env.AWS_ACCESS_KEY_ID,
      "secretAccessKey": process.env.AWS_SECRET_ACCESS_KEY,
    },
    "bucketName": process.env.AWS_BUCKET_NAME
  }
};复制代码

而后,当经过 Docker Compose 运行应用程序时,咱们经过环境键指定这些环境变量。

api:
 image: lucj/api:1.0
networks:
      - backend    
    deploy:
      restart_policy:
        condition: on-failure
 environment:
   — AWS_BUCKET_NAME=BucketName
   — AWS_ACCESS_KEY_ID=AccessKeyID
   — AWS_SECRET_ACCESS_KEY=SecretAccessKey复制代码

这的确是处理这个问题的一个方式,可是,将这些敏感信息以纯文本格式化是很是危险的。

处理具备 Docker secrets 的 AWS 凭据

有几种方式能够以安全的方式处理这些信息。使用 Docker secrets 就是其中之一。

咱们再也不在环境变量中以纯文本定义凭据信息,而是从中建立 docker secrets。

$ echo "BucketName"| docker secret create AWS_BUCKET_NAME -
vjp5zh8hwb9dqkvohtyvtifl1
$ echo "AccessKeyID" | docker secret create AWS_ACCESS_KEY_ID -
5txxg3fslf9g5z1o4i19vvmcr
$echo "SecretAccessKey"|docker secret create AWS_SECRET_ACCESS_KEY -
v8g65iwcx1eb6uuwsjzknyi7g复制代码

secrets 建立成功。使用docker secret ls

$ docker secret ls
ID NAME CREATED UPDATED
5x..vm AWS_ACCESS_KEY_ID About a minute ago About a minute ago
v8..7g AWS_SECRET_ACCESS_KEY About a minute ago About a minute ago
vj..l1 AWS_BUCKET_NAME About a minute ago About a minute ago复制代码

但他们的内容没法被检索。例如,若是咱们检查与关键字 AWS

ACCESS
KEY_ID 相关联的 secret,咱们只会获取元数据,而不是其实际内容。

$ docker secret inspect 5txxg3fslf9g5z1o4i19vvmcr
[
  {
    "ID": "5txxg3fslf9g5z1o4i19vvmcr",
    "Version": {
      "Index": 12
    },
    "CreatedAt": "2017–08–13T12:58:50.54021338Z",
    "UpdatedAt": "2017–08–13T12:58:50.54021338Z",
    "Spec": {
      "Name": "AWS_ACCESS_KEY_ID",
      "Labels": {}
    }
  }
]复制代码

建立了 secret 之后,咱们就能够在 Docker Compose 文件中引用它们。

secrets:
  AWS_BUCKET_NAME:
    external: true
  AWS_ACCESS_KEY_ID:
    external: true
  AWS_SECRET_ACCESS_KEY:
    external: true 
 
复制代码

在 Docker Compose 文件中,咱们还须要修改 api 服务的描述,以便使用这些 secrets。

api:
 image: lucj/api:2.0
 secrets:
   — AWS_BUCKET_NAME
   — AWS_ACCESS_KEY_ID
   — AWS_SECRET_ACCESS_KEY
 networks:
   — backend
 deploy:
   restart_policy:
     condition: on-failure复制代码

当一个服务须要访问一个 secret 时,默认状况下,它被安装在该服务的每一个容器中的临时文件系统中。


因为咱们的应用程序仅在此阶段检查环境变量,所以须要进行更新。


这能够用一个简单的模块来实现,只须要从`/run/secrets`中读取一个 secret。这在如下代码中说明。

// secrets.js
const fs = require("fs"),
      util = require("util");
module.exports = {
  // Get a secret from its name
  get(secret){
    try{
      // Swarm secret are accessible within tmpfs /run/secrets dir
      return fs.readFileSync(util.format(“/run/secrets/%s”, secret), "utf8").trim();
     }
     catch(e){
       return false;
     }
  }
};复制代码

而后,咱们能够修改配置文件,以便它使用 secrets.js 模块的 get 函数:

...
"amazon":{
  "credentials": {
    "accessKeyId": secrets.get(“AWS_ACCESS_KEY_ID”) || process.env.AWS_ACCESS_KEY_ID,
    "secretAccessKey": secrets.get(“AWS_SECRET_ACCESS_KEY”) || process.env.AWS_SECRET_ACCESS_KEY,
  },
 "bucket": secrets.get("AWS_BUCKET_NAME") || process.env.AWS_BUCKET_NAME
 }复制代码

对于每一个 key,咱们首先检查它是否做为 secret 存在。若是没有的话,咱们仍然使用环境变量。

这一期的『航海日志』就到这里,下期再浪~


参考连接


做者介绍

莫非 Beck:DaoCloud 微服务攻城狮,吃饱了就困的一流段子手。

刘玺元 Boring:DaoCloud 市场部门(伪)程序猿。


Discussion | 你对今天的哪条新闻最感兴趣?

  • 你对今天的哪条新闻最感兴趣?你有什么独到的看法?

  • 本周你还有什么更具爆炸性的容器圈新闻吗?欢迎在留言区爆料!


点这儿,回顾一下船长的过去

相关文章
相关标签/搜索