pull/402/head
Jimmy song 2020-06-08 20:32:34 +08:00
parent b3af7d2b04
commit b0c129cda2
14 changed files with 365 additions and 508 deletions

View File

@ -1,8 +1,8 @@
## Aggregated API Server
# Aggregated API Server
Aggregated聚合的API server是为了将原来的API server这个巨石monolithic应用给拆分成为了方便用户开发自己的API server集成进来而不用直接修改kubernetes官方仓库的代码这样一来也能将API server解耦方便用户使用实验特性。这些API server可以跟core API server无缝衔接使用kubectl也可以管理它们。
### 架构
## 架构
我们需要创建一个新的组件,名为`kube-aggregator`,它需要负责以下几件事:
@ -14,7 +14,7 @@ Aggregated聚合的API server是为了将原来的API server这个巨石
关于聚合的API server的更多信息请参考[Aggregated API Server](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/aggregated-api-servers.md)
### 安装配置聚合的API server
## 安装配置聚合的API server
有两种方式来启用`kube-aggregator`

View File

@ -6,14 +6,9 @@ Annotation顾名思义就是注解。Annotation可以将Kubernetes资源
Label 和 Annotation 都可以将元数据关联到 Kubernetes 资源对象。Label 主要用于选择对象可以挑选出满足特定条件的对象。相比之下annotation 不能用于标识及选择对象。annotation 中的元数据可多可少,可以是结构化的或非结构化的,也可以包含 label 中不允许出现的字符。
annotation和label一样都是key/value键值对映射结构:
Annotation 和 label 一样都是 key/value 键值对映射结构:
```json
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
```
```json"annotations": {"key1":"value1","key2":"value2"}```
以下列出了一些可以记录在 annotation 中的对象信息:

View File

@ -35,9 +35,7 @@ spec:
```bash
kubectl get apiservice v1alpha1.custom-metrics.metrics.k8s.io -o yaml
```
```yaml
``````yaml
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:

View File

@ -1,108 +0,0 @@
# 云原生应用
## 云原生应用的基本概念
云原生应用,是指原生为在云平台上部署运行而设计开发的应用。公平的说,大多数传统的应用,不做任何改动,都是可以在云平台运行起来的,只要云平台支持这个传统应用所运行的计算机架构和操作系统。只不过这种运行模式,仅仅是把虚拟机当物理机一样使用,不能够真正利用起来云平台的能力。
## 云原生应用与相关技术理念的关系
### 云原生应用与云平台的关系
云平台是用来部署、管理和运行SaaS云应用的。SaaS是云计算的三种服务模型之一即跟业务相关的应用即服务。云计算最根本的特性是提供按需分配资源和弹性计算的能力而云原生应用的设计理念就是让部署到云平台的应用能够利用到云平台的能力实现按需使用计算资源和弹性伸缩成为一个合格的SaaS应用。
### 云原生应用与12要素的关系
12要素是PaaS平台Haroku团队提出的应用设计理念是有关SaaS应用设计理念的红宝书可以说12要素应用就是云原生应用的同义词。
### 云原生应用与Stateless和Share Nothing架构的关系
为了实现水平伸缩的能力云原生应用应该是Stateless和Share Nothing的。
### 云原生应用与微服务架构的关系
微服务架构是实现企业分布式系统的一种架构模式,即将一个复杂的单体应用按照业务的限定上下文,分解成多个独立部署的组件。这些独立部署的组件,就称为微服务。而在谈论云原生应用与微服务架构关系的时候,根据上下文不同可能是有两种不同的含义。一种含义是宏观的云原生应用,即将整个分布式系统看作一个应用,这种语境下,微服务架构是实现云原生应用的一种架构模式;另一种含义是微观的云原生应用,即每个微服务是一个应用,这种语境下,每个微服务要按照云原生应用的设计理念去设计,才能真正实现微服务架构所要达到的目的,即让分布式系统具备按需使用计算资源和弹性伸缩的能力,这里“应用”和“服务”变成了同义词。
### 云原生应用与宠物和牲畜的关系
云原生应用的设计理念是希望把应用当作牲畜来养,而不是当作宠物来养。部署一个云原生应用的集群,就好像圈养了一大群奶牛,目的主要是为了产奶,对待每头牛就像对待机器一样没有什么感情,死了一头就再养一头,而不会像对待宠物那样细心呵护。而传统应用,因为往往因为对运行环境依赖严重,运维人员需要细心照顾、维护,万一出现宕机,一般要在原来的服务器上修复问题再恢复运行;如果恢复不了,整个应用系统就瘫痪了,因此会令运维人员像“宠物死了”一样伤心。
## 云原生应用的设计理念——12要素
### 一个应用对应一套代码多次部署
这一理念主要是强调应用应该清晰明确地区分什么是应用,什么是部署。一个应用对应的就是一个代码仓库,一个软件产品;一次部署对应的是一个运行起来的应用;因此应用与部署的关系是一对多。这种一对多的关系也体现了应用代码的可重用性,一套代码可以重用到多次的部署中去;不同部署之间的区分是配置,而代码是共享的。对应用架构来说,最基本的是要区分运行时行为和非运行时行为,一个应用的非运行时的代表就是一个代码仓库,它可能有多个运行时实例,每个实例就是一次部署。
### 明确地声明并隔离依赖的程序库
不管用什么语言开发应用,编程语言一定都有管理程序库的机制。这一理念强调所有依赖库一定要明确的声明出来,因为只有这样,在运行应用的时候,才能保证所有运行所需要的程序库都正确部署到了云环境中。
### 将配置存储到部署环境中
正像前面所说一个应用的不同部署之间是共享一套代码的不同之处是配置。代码是存储到代码仓库中的那自然配置不应该是存到代码仓库中。每次部署都有自己独立的部署环境每次部署所对应的配置要存到这次部署所对应的部署环境中去因此配置的另一个同义词就是环境变量。这里的部署不包括应用内部的配置例如Java的Properties文件或者是Servlet的映射配置文件web.xml等这些算作是代码而不是配置。这是一个容易令人混淆的地方那到底什么算代码什么算配置判断的标准很简单就是变化的频率。变动导致产品版本更新的就是代码每次部署都可能变更而每次变动不导致产品版本更新的就是配置就是环境变量。
### 将后端支撑服务作为挂载资源来使用
这一理念强调应用使用后台支撑服务的方式。不同的服务之间的区别就只是资源的URL不同也就是设定这个资源的相关环境变量不同。不管是本地资源还是远程资源应用程序都可以正常使用区别只是环境变量的值不同而应用本身并不会因为环境变量不同而有所区别。最常用的后台支撑服务就是数据库、缓存、消息队列等服务。这一理念可以保证应用在任何环境都可以正常运行不会因为后台支撑服务的变化而导致应用无法运行。
### 严格区分构建阶段和运行阶段
这一理念跟区分应用和部署类似,本质上也是要严格区分应用的非运行时行为和运行时行为。构建是将应用的代码仓库编译打包成可运行的软件的过程,是非运行时行为。因此说,这一理念另一方面也说明要防止在运行阶段改代码的行为,这样才能够保证运行中应用的稳定性。
### 将应用作为无状态的进程来运行
这一理念要求所有的用户数据都要通过后端支撑服务来存储,而应用本身是无状态的,因为只有这样,应用才能做到水平伸缩,从而利用云平台弹性伸缩的能力。
### 仅需要绑定一个端口就可以对外发布一个服务
这一理念强调应用本身对于发布服务的环境不应该有过多的要求,而应该是完全自包含的,也就是说不需要依赖云平台提供应用运行容器,而只需要云平台分配某个端口对外发布服务。这一理念保证应用可以使用云平台中任意分配的端口发布服务。
### 可以像UNIX进程一样水平扩展
在UNIX操作系统上不同的进程彼此独立地运行着共享这整个操作系统管理的计算机资源。云原生应用在云平台上的运行模式也是类似的云平台就是分布式操作系统不同的云原生应用彼此独立互补干扰的运行在一个云平台上可以充分利用云平台的整体计算能力。
### 可以快速启动和优雅地关闭
快速启动是为了能充分利用云平台根据需要调度资源的能力,能够在需要的时候,以最小的延时扩展计算能力提供服务。优雅地关闭,一方面是为了释放资源,将不再使用的计算资源归还云平台;另一方面也是为了保证应用逻辑的完整性,将该完成的任务正确完成,未能完成的任务重新交回到系统由其它应用的运行实例来继续完成。要假设云原生应用的目标工作环境中随时有大量同样的应用实例在运行、启动和关闭,因此快速启动和优雅关闭对高性能和稳定的系统非常重要。
### 保持开发环境、预发布环境和生产环境尽量一致
保持环境一致,是为了提高开发单元测试、功能测试和集成测试的有效性,避免出现开发测试中正常而在生产环境中出现问题的情况。
### 将日志作为事件流来处理
云原生应用运行在复杂的分布式基础设施之上,如果日志不通过简单统一的模式来管理,将给系统排错或通过日志挖掘信息带来很大困难。同时,如果应用将日志输出到系统的文件中,也会给系统的存储空间造成压力,增加系统运维的复杂性。因此这一理念推荐应用将日志输出到标准输出,然后由云平台统一收集处理。
### 将应用管理任务当作一次性进程来运行
将应用的管理任务与应用的业务请求以相似的方式运行,以同样的方式进行调度、日志和监控,将有利于系统的稳定性和分析系统的整体行为。
## 云原生应用的挑战
### 处理分布式系统的网络通信问题
云原生应用必须要针对分布式系统中网络通信的复杂性进行设计。对于分布式系统,如果还像单一进程应用那样考虑问题,就会进入所谓的“分布式系统的认识误区”,包括武断地认为:网络是可靠的;网络的延时为零;网络带宽是无限大的;网络是安全的;网络拓扑是不变的;系统中只有一个管理员和网络环境都是统一一致的。也许现在很少会有人幼稚到真的认为分布式环境中的交互处理和运行在单一进程中的函数调用是一样的;但开发的复杂度、功能上线的压力,经常会使开发人员把这些复杂问题暂时放在一边,不断积累起越来越多的“技术负债”。
### 处理分布式系统的状态一致性问题
分布式系统的CAP理论认为在分布式系统中系统的一致性、可用性和分区容忍性三者不可能同时兼顾。当然实际在分布式系统中由于网络通信固有的不稳定分区容忍性是必须要存在的因此在设计应用的时候就要在一致性和可用性之间权衡选择。
### 最终一致性
很多情况下在一致性和可用性之间云原生应用比传统应用更加偏向可用性而采用最终一致性代替传统用事务交易保证的ACID一致性。传统的ACID一致性编程模型与业务无关开发人员对它经验丰富而最终一致性的交互模式与业务相关必须通过业务的合理性来校验阶段不一致的合理性这使得最终一致性比ACID一致性复杂得多。
### 服务发现和负载均衡
云原生应用的运行实例随时可能关闭和启动,因此需要机制使得访问应用服务的客户端随时都能找到健康运行的实例,放弃对宕机实例的访问,这就是服务发现的问题。与服务发现同时存在的,是在多个健康实例中选择一个实例真正为某个客户请求提供服务的过程,这就是负载均衡。
### 任务分解和数据分片
大的任务要分解成很多小任务,分配到各个运行实例上去执行,然后再将执行结果汇总,这就是任务分解。数据分布到各个实例上做处理和存储,这个就是数据分片。这些都需要适应云计算环境的机制去支持。
### 主控角色选举
不管是任务分解还是数据分片,每个应用实例上负责的子任务和数据分片虽然是不同的,但如何分解、谁负责谁这种分配映射表一定是完全相同的;因此在这种情况下,需要负责计算分配映射表的主控角色;而因为云计算环境下没有实例是永远保证健康运行的,主控角色不可能是永远固定的;这就需要主控角色选举的机制,能够在主控角色空白或出现故障宕机的情况下,自选举出新的主控角色。
像设计模式解决面向对象设计中的复杂问题一样,面对云原生应用的复杂应用场景,我们也需要一些典型的设计模式能够可重用地解决一些特定场景的问题。这些我们将在本系列文章的后面结合应用案例予以介绍。
[1] http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-applications-part02

View File

@ -9,8 +9,7 @@ Kubernetes源码的`vendor/github.com/containernetworking/cni/libcni`目录中
CNI 的接口中包括以下几个方法:
```go
type CNI interface {
AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
type CNI interface {AddNetworkList (net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
DelNetworkList (net *NetworkConfigList, rt *RuntimeConf) error
AddNetwork (net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
@ -48,24 +47,24 @@ CNI插件必须支持以下操作
参数:
- **版本**调用者正在使用的CNI规范容器管理系统或调用插件的版本。
- **容器ID **由运行时分配的容器的唯一明文标识符。一定不能是空的。
- **网络命名空间路径**要添加的网络名称空间的路径,即`/proc/[pid]/ns/net`或绑定挂载/链接。
- **网络配置**描述容器可以加入的网络的JSON文档。架构如下所述。
- **额外的参数**这提供了一个替代机制允许在每个容器上简单配置CNI插件。
- **容器内接口的名称**这是应该分配给容器网络命名空间内创建的接口的名称因此它必须符合Linux接口名称上的标准限制。
- **版本**调用者正在使用的 CNI 规范(容器管理系统或调用插件)的版本。
- **容器 ID**由运行时分配的容器的唯一明文标识符。一定不能是空的。
- **网络命名空间路径**要添加的网络名称空间的路径,即 `/proc/[pid]/ns/net` 或绑定挂载 / 链接。
- **网络配置**描述容器可以加入的网络的 JSON 文档。架构如下所述。
- **额外的参数**这提供了一个替代机制,允许在每个容器上简单配置 CNI 插件。
- **容器内接口的名称**这是应该分配给容器(网络命名空间)内创建的接口的名称;因此它必须符合 Linux 接口名称上的标准限制。
结果:
- **接口列表**根据插件的不同,这可以包括沙箱(例如容器或管理程序)接口名称和/或主机接口名称,每个接口的硬件地址以及接口所在的沙箱(如果有的话)的详细信息。
- **分配给每个接口的IP配置**分配给沙箱和/或主机接口的IPv4和/或IPv6地址网关和路由。
- **DNS信息**包含nameserver、domain、search domain和option的DNS信息的字典。
- **接口列表**根据插件的不同,这可以包括沙箱(例如容器或管理程序)接口名称和 / 或主机接口名称,每个接口的硬件地址以及接口所在的沙箱(如果有的话)的详细信息。
- **分配给每个接口的 IP 配置**分配给沙箱和 / 或主机接口的 IPv4 / IPv6 地址,网关和路由。
- **DNS 信息**包含 nameserver、domain、search domain option DNS 信息的字典。
#### 从网络中删除容器
参数:
- **版本**调用者正在使用的CNI规范容器管理系统或调用插件的版本。
- **版本**调用者正在使用的 CNI 规范(容器管理系统或调用插件)的版本。
- **容器 ID **,如上所述。
- **网络命名空间路径 **,如上定义。
- **网络配置 **,如上所述。
@ -82,8 +81,7 @@ CNI插件必须支持以下操作
- 结果:插件支持的 CNI 规范版本信息。
```json
{
“cniVersion”“0.3.1”,//此输出使用的CNI规范的版本
{“cniVersion”“0.3.1”,// 此输出使用的 CNI 规范的版本
“supportedVersions”[“0.1.0”“0.2.0”“0.3.0”“0.3.1”] // 此插件支持的 CNI 规范版本列表
}
```

View File

@ -132,5 +132,6 @@ Kubernetes在1.3版本中发布了alpha版的基于角色的访问控制Role-
按照分布式系统一致性算法 Paxos 发明人计算机科学家 [Leslie Lamport](http://research.microsoft.com/users/lamport/pubs/pubs.html) 的理念,一个分布式系统有两类特性:安全性 Safety 和活性 Liveness。安全性保证系统的稳定保证系统不会崩溃不会出现业务错误不会做坏事是严格约束的活性使得系统可以提供功能提高性能增加易用性让系统可以在用户 “看到的时间内” 做些好事是尽力而为的。Kubernetes 系统的设计理念正好与 Lamport 安全性与活性的理念不谋而合,也正是因为 Kubernetes 在引入功能和技术的时候,非常好地划分了安全性和活性,才可以让 Kubernetes 能有这么快版本迭代,快速引入像 RBAC、Federation 和 PetSet 这种新功能。
原文地址:[《Kubernetes与云原生应用》系列之Kubernetes的系统架构与设计理念](http://www.infoq.com/cn/articles/kubernetes-and-cloud-native-applications-part01)
## 参考
- [《Kubernetes 与云原生应用》系列之 Kubernetes 的系统架构与设计理念](https://www.infoq.cn/article/kubernetes-and-cloud-native-applications-part01/)

View File

@ -26,7 +26,7 @@ Kubernetes中不仅支持CPU、内存为指标的HPA还支持自定义指标
确认您的kubernetes版本在1.7或以上,修改以下配置:
- 将kube-controller-manager的启动参数中`--horizontal-pod-autoscaler-use-rest-clients`设置为true并指定`--master`为API server地址如`--master=http://172.20.0.113:8080
- 将kube-controller-manager的启动参数中`--horizontal-pod-autoscaler-use-rest-clients`设置为true并指定`--master`为API server地址如`--master=http://172.20.0.113:8080`
- 修改kube-apiserver的配置文件apiserver增加一条配置`--requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem --requestheader-allowed-names=aggregator --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=/etc/kubernetes/ssl/kubernetes.pem --proxy-client-key-file=/etc/kubernetes/ssl/kubernetes-key.pem`用来配置aggregator的CA证书。
已经内置了`apiregistration.k8s.io/v1beta1` API可以直接定义APIService

View File

@ -41,12 +41,10 @@ metadata:
description: "A specification of a Pod to run on a cron style schedule"
versions:
- name: v1
```
然后使用`kubectl create`命令创建该资源这样就可以创建出一个API端点`/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/...`。
```然后使用`kubectl create`命令创建该资源,这样就可以创建出一个 API 端点`/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/...`。
下面是在 [Linkerd](https://linkerd.io) 中的一个实际应用Linkerd 中的一个名为 namerd 的组件使用了 TPR定义如下
```yaml
```yaml
---
kind: ThirdPartyResource
apiVersion: extensions/v1beta1
@ -84,17 +82,9 @@ spec:
# CLI 中使用的资源简称
shortNames:
- ct
```
创建该CRD
```bash
```创建该 CRD```bash
kubectl create -f resourcedefinition.yaml
```
访问RESTful API端点如<http://172.20.0.113:8080>将看到如下API端点已创建
```bash
```访问 RESTful API 端点如 <http://172.20.0.113:8080> 将看到如下 API 端点已创建:```bash
/apis/stable.example.com/v1/namespaces/*/crontabs/...
```

View File

@ -2,14 +2,14 @@
## 简述
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括:
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义declarative方法用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括:
- 定义 Deployment 来创建 Pod 和 ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续 Deployment
比如一个简单的nginx应用可以定义为
比如一个简单的 nginx 应用可以定义为
```yaml
apiVersion: extensions/v1beta1
@ -28,29 +28,13 @@ spec:
image: nginx:1.7.9
ports:
- containerPort: 80
```
扩容:
```
```扩容:```
kubectl scale deployment nginx-deployment --replicas 10
```
如果集群支持 horizontal pod autoscaling 的话还可以为Deployment设置自动扩展
```
```如果集群支持 horizontal pod autoscaling 的话,还可以为 Deployment 设置自动扩展:```
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
```
更新镜像也比较简单:
```
```更新镜像也比较简单:```
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
```
回滚:
```
```回滚:```
kubectl rollout undo deployment/nginx-deployment
```
@ -188,7 +172,7 @@ nginx-deployment-1564180365 3 3 0 6s
nginx-deployment-2035384211 0 0 0 36s
```
执行 `get pods`只会看到当前的新的 pod:
执行`get pods`只会看到当前的新的 pod
```bash
$ kubectl get pods
@ -480,6 +464,7 @@ NAME DESIRED CURRENT READY AGE
nginx-deployment-1989198191 7 7 0 7m
nginx-deployment-618515232 11 11 11 7m
```
## 删除 autoscale
```bash
@ -695,7 +680,6 @@ Conditions:
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
```
`Type=Available``Status=True` 意味着您的 Deployment 有最小可用性。 最小可用性是在 Deployment 策略中指定的参数。`Type=Progressing` 、 `Status=True` 意味着您的 Deployment 或者在部署过程中,或者已经成功部署,达到了期望的最少的可用 replica 数量(查看特定状态的 Reason—— 在我们的例子中 `Reason=NewReplicaSetAvailable` 意味着 Deployment 已经完成)。
@ -809,4 +793,3 @@ Deployment revision history存储在它控制的ReplicaSets中。
### Paused
`.spec.paused` 是可以可选配置项boolean 值。用来指定暂停和恢复 Deployment。Paused 和没有 paused 的 Deployment 之间的唯一区别就是,所有对 paused deployment 中的 PodTemplateSpec 的修改都不会触发新的 rollout。Deployment 被创建之后默认是非 paused。