2019年3月,伯克利的一篇论文《A Berkeley View on Serveless Computing》,预测了Serverless对未来10年云计算的影响;
2019年12月,AWS REInvent上发布了诸多Serverless相关的更新,反响热烈。
Serverless无疑已经成为学术界和工业界关注的焦点。
本文主要聊聊个人对Serverless的一些理解。
2019年3月,伯克利的一篇论文《A Berkeley View on Serveless Computing》,预测了Serverless对未来10年云计算的影响;
2019年12月,AWS REInvent上发布了诸多Serverless相关的更新,反响热烈。
Serverless无疑已经成为学术界和工业界关注的焦点。
本文主要聊聊个人对Serverless的一些理解。
本书的作者是香奈儿前CEO莫琳·希凯,书名《深度思考》,副标题 - 不断逼近问题的本质
。
这是一本关于提升逻辑思维能力的大作,也是有效提高写作和演讲水平的红宝书,
趁这几天宅在家里,前细后粗的读了一遍。(后面的太啰嗦,选择性放弃)
之前我们了解了如何打包,作为Pod中的容器运行,使用临时或者永久存储机制,设置配置项,接下来我们探讨如何部署和升级。
假定在K8S中存在这样的应用: * Service * 3个Pod * 使用ReplicaSet * Clients
初始情况,运行V1版本的应用。接下来,我们希望生成V2版本的镜像,并使用V2版本的Pod/容器进行升级。
存在两种方式:
* 先删除V1版本的应用,然后部署V2版本。
* 先新增V2版本的应用,然后删除V1版本。(对于V2版本的新增,可以选择 一次新增全部数量
,多次新增,每次部分数量
)
对于第一种方式:简单,但是存在部署的停机时间
对于第二种方式:系统需要同时处理两个版本的应用,尤其是数据Schema需要兼容新旧两个版本
几乎所有的应用程序都需要配置(实例的配置信息,外部系统的访问信息等),而这些配置显然不应该被打包到应用程序本身中。
本篇文章看看如何在Kubernetes中配置应用程序的信息。
命令行 最简单的应用配置方式,是使用命令行。
配置文件
随着配置信息增多,考虑到维护成本,可以将配置信息存储到配置文件中。但对于容器而言,使用配置文件的方式需要将配置项打包到镜像中,而且每次配置信息的变更都会导致重新生成镜像,重新部署,维护和变更成本较高。
在容器应用中,使用环境变量来实现配置,也是较普遍的一种做法,通过将参数传递给容器中的应用,变更容器运行期的配置信息,如MySQL官方的镜像就使用环境变量MYSQL_ROOT_PASSWORD
来修改超级用户root的密码。
另外,基于volume的方式获取配置信息也是一种可行的方式,如使用Git Repo存储配置信息,能有效的做到版本化管理会随时回退。
在K8S中,存储配置信息的资源被称ConfigMap,本部分将介绍ConfigMap、Secret的使用。
在Docker容器中,通常使用如下方式传递参数:
ENTRYPOINT
定义可执行命令CMD
传递参数在ENTRYPOINT中,可以使用如下两种方式启动应用:
ENTRYPOINT node app.js
ENTRYPOINT ["node", "app.js"]
注意: 这两种方式的区别在于前者是先启动Shell,由Shell调用node,而后者直接启动node应用。
在K8S中,可以通过配置文件中的command
和args
来设置容器中的ENTRYPOINT
和CMD
譬如
1 2 3 4 5 6 |
|
它们之间的区别如下图所示:
Docker | Kubernetes | 描述 |
---|---|---|
ENTRYPOINT | command | 在容器中执行命令 |
CMD | args | 给命令传递参数 |
在K8S中,使用env
设置镜像中定义的环境变量。
譬如,容器中存在如下脚本,其中的INTERVAL
使用环境变量进行设置:
1 2 3 4 5 6 |
|
在K8S中,其配置文件类似如下:
1 2 3 4 5 6 7 8 |
|
Kubernetes允许将配置项分离到一个称为ConfigMap
的单独对象中,它包含若干键/值对,并且值的范围可以从文本到整个配置文件。
应用程序不需要直接读取ConfigMap,甚至不需要知道它的存在。Map的内容可以作为环境变量或者卷传递给容器。
使用kubectl
创建ConfigMap的过程中,可以指定多样化的配置机制,类似如下所示:
1 2 3 4 5 |
|
接下来, 在如上环境变量的例子中,我们使用ConfigMap配置环境变量$INTERVAL
的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
在如上的例子中,读取ConfigMapfortune-config
中Keysleep-interval
对应的值,作为$INTERVAL
的值。
譬如有个ConfigMap,它有两个键,分别是foo、bar。您可以使用envFrom属性将它们全部公开为环境变量,而不是像在前面的示例中那样依次使用env。
如下所示:
1 2 3 4 5 6 7 8 |
|
CONFIG_作为前缀,将导出如下环境变量CONFIG_foo和CONFIG_bar。当然,前缀是可选的,如不设置,则容器中的环境变量为foo和bar。
接下来,让我们看看如何将ConfigMap中的值作为参数传递给容器中运行的进程。我们不能在pod.spec.containers.args字段中直接引用ConfigMap,但是可以从ConfigMap中初始化一个环境变量,然后引用参数中的值,相关代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
其关系如图所示:
ConfigMap除了可以作为环境变量以及命令行参数外,还可以包括整个目录中的配置文件。
譬如,在configmap-files
目录下存在如下2个文件:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1
|
|
接下来,使用命令创建ConfigMap
1
|
|
然后,我们可以使用volume将ConfigMap中的内容暴露给容器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
本篇文章主要介绍在K8S中,pod的容器如何访问外部磁盘存储,以及容器间如何实现共享存储,主要内容包括
在非k8s世界中,管理员可以通过在配置文件中指定IP地址或主机名,容许客户端访问,但在k8s中这种方式是行不通的。因为Pod 是有生命周期的,它们可以被创建或销毁。虽然通过 ReplicationController 能够动态地创建Pod,但当Pod被分配到某个节点时,K8s都会为其分配一个IP地址,而该IP地址不总是稳定可依赖的。因此,在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组backend的Pod呢?
Kubernetes中内建了很多controller(控制器),这些相当于一个状态机,用来控制Pod的具体状态和行为。
Pod是kubernetes中你可以创建和部署的最小也是最简的单位。Pod代表着集群中运行的进程。Pod中封装着应用的容器(1或多个容器)、存储、独立的网络IP,并管理着容器运行的策略选项。
K8s的网络介绍