文章目录
- 当前 Cloud Provider 工作原理
- Kubelet 必须配置 –cloud-provider=external`,并且 `kube-apiserver` 和 `kube-controller-manager` 必须不配置 cloud provider。 kube-apiserver 的准入控制选项不能包含 PersistentVolumeLabel。 cloud-controller-manager 独立运行,并开启 InitializerConifguration。 Kubelet 可以通过 provider-id 选项配置 ExternalID,启动后会自动给 Node 添加 taint node.cloudprovider.kubernetes.io/uninitialized=NoSchedule。 cloud-controller-manager 在收到 Node 注册的事件后再次初始化 Node 配置,添加 zone、类型等信息,并删除上一步 Kubelet 自动创建的 taint。 主要逻辑(也就是合并了 kube-apiserver 和 kube-controller-manager 跟云相关的逻辑) Node 控制器检查 Node 所在 VM 的状态。当 VM 删除后自动从 API Server 中删除该 Node。 Volume 控制器向云提供商创建和删除持久化存储卷,并按需要挂载或卸载到指定的 VM 上。 Route 控制器给所有已注册的 Nodes 配置云路由。 Service 控制器给 LoadBalancer 类型的服务创建负载均衡器并更新服务的外网 IP。 PersistentVolumeLable 准入控制负责 PV 标签 PersistentVolumeClainResize 准入控制动态扩展 PV 大小
当前 Cloud Provider 工作原理
- apiserver,kubelet,controller-manager 都配置 cloud provider 选项
- Kubelet
- 通过 Cloud Provider 接口查询 nodename
- 向 API Server 注册 Node 时查询 InstanceID、ProviderID、ExternalID 和 Zone 等信息
- 定期查询 Node 是否新增了 IP 地址
- 设置无法调度的条件(condition),直到云服务商的路由配置完成
- kube-apiserver
- 向所有 Node 分发 SSH 密钥以便建立 SSH 隧道
- PersistentVolumeLabel 负责 PV 标签
- PersistentVolumeClainResize 动态扩展 PV 的大小
- kube-controller-manager
- Node 控制器检查 Node 所在 VM 的状态。当 VM 删除后自动从 API Server 中删除该 Node。
- Volume 控制器向云提供商创建和删除持久化存储卷,并按需要挂载或卸载到指定的 VM 上。
- Route 控制器给所有已注册的 Nodes 配置云路由。
- Service 控制器给 LoadBalancer 类型的服务创建负载均衡器并更新服务的外网 IP。
- Kubelet 必须配置
--cloud-provider=external`,并且 `kube-apiserver` 和 `kube-controller-manager` 必须不配置 cloud provider。
kube-apiserver 的准入控制选项不能包含 PersistentVolumeLabel。
cloud-controller-manager 独立运行,并开启 InitializerConifguration。
- Kubelet 可以通过
provider-id 选项配置 ExternalID,启动后会自动给 Node 添加 taint node.cloudprovider.kubernetes.io/uninitialized=NoSchedule。
cloud-controller-manager 在收到 Node 注册的事件后再次初始化 Node 配置,添加 zone、类型等信息,并删除上一步 Kubelet 自动创建的 taint。
- 主要逻辑(也就是合并了 kube-apiserver 和 kube-controller-manager 跟云相关的逻辑)
- Node 控制器检查 Node 所在 VM 的状态。当 VM 删除后自动从 API Server 中删除该 Node。
- Volume 控制器向云提供商创建和删除持久化存储卷,并按需要挂载或卸载到指定的 VM 上。
- Route 控制器给所有已注册的 Nodes 配置云路由。
- Service 控制器给 LoadBalancer 类型的服务创建负载均衡器并更新服务的外网 IP。
- PersistentVolumeLable 准入控制负责 PV 标签
- PersistentVolumeClainResize 准入控制动态扩展 PV 大小
--cloud-provider=external`,并且 `kube-apiserver` 和 `kube-controller-manager` 必须不配置 cloud provider。kube-apiserver 的准入控制选项不能包含 PersistentVolumeLabel。cloud-controller-manager 独立运行,并开启 InitializerConifguration。provider-id 选项配置 ExternalID,启动后会自动给 Node 添加 taint node.cloudprovider.kubernetes.io/uninitialized=NoSchedule。cloud-controller-manager 在收到 Node 注册的事件后再次初始化 Node 配置,添加 zone、类型等信息,并删除上一步 Kubelet 自动创建的 taint。- Node 控制器检查 Node 所在 VM 的状态。当 VM 删除后自动从 API Server 中删除该 Node。
- Volume 控制器向云提供商创建和删除持久化存储卷,并按需要挂载或卸载到指定的 VM 上。
- Route 控制器给所有已注册的 Nodes 配置云路由。
- Service 控制器给 LoadBalancer 类型的服务创建负载均衡器并更新服务的外网 IP。
- PersistentVolumeLable 准入控制负责 PV 标签
- PersistentVolumeClainResize 准入控制动态扩展 PV 大小
如何开发 Cloud Provider 扩展
Kubernetes 的 Cloud Provider 目前正在重构中
- v1.6 添加了独立的
cloud-controller-manager服务,云提供商可以构建自己的cloud-controller-manager而无须修改 Kubernetes 核心代码 - v1.7 和 v1.8 进一步重构
cloud-controller-manager,解耦了 Controller Manager 与 Cloud Controller 的代码逻辑
构建一个新的云提供商的 Cloud Provider 步骤为
- 编写实现 cloudprovider.Interface 的 cloudprovider 代码
- 将该 cloudprovider 链接到
cloud-controller-manager- 在
cloud-controller-manager中导入新的 cloudprovider:import "pkg/new-cloud-provider" - 初始化时传入新 cloudprovider 的名字,如
cloudprovider.InitCloudProvider("rancher", s.CloudConfigFile)
- 在
- 配置 kube-controller-manager
--cloud-provider=external - 启动
cloud-controller-manager
具体实现方法可以参考 rancher-cloud-controller-manager 和 cloud-controller-manager。
实现自己的CCM也比较简单,举例如下:
package main
import (
…
"k8s.io/kubernetes/cmd/cloud-controller-manager/app"
"k8s.io/kubernetes/cmd/cloud-controller-manager/app/options"
// (1)初始化原来Cloud Provider的相关逻辑,读取cloud配置、初始化云厂商的Clod SDK。
_ "k8s.io/cloud-provider-baiducloud/pkg/cloud-provider"
)
func main() {
goflag.CommandLine.Parse([]string{})
// (2) 初始化一个默认的CCM配置
s, _ := options.NewCloudControllerManagerOptions()
if err != nil {
glog.Fatalf("unable to initialize command options: %v", err)
}
// (3) CCM启动命令
cmd := &cobra.Command{
Use: "cloud-controller-manager",
Long: `The Cloud controller manager is a daemon that embeds the cloud specific control loops shipped with Kubernetes.`,
Run: func(cmd *cobra.Command, args []string) {
c, err := s.Config()
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
// (4) Run里会运行相关controller loops:CloudNode Controller、PersistentVolumeLabel Controller、Service Controller、Route Controller
if err := app.Run(c.Complete()); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
},
}
s.AddFlags(cmd.Flags())
pflag.CommandLine.SetNormalizeFunc(flag.WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
logs.InitLogs()
defer logs.FlushLogs()
if err := c.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}
———————
5.1 总体要求
云厂商提供给CCM的API需要有认证鉴权机制,防止恶意行为。
因为CCM运行在集群内,所以需要RBAC规则去跟kube-apiserver通讯
CCM为了高可用,可开启选主功能
5.2 k8s相关组件的启动配置变化
将Cloud Provider改为CCM后,相关组件启动的配置需要修改。
5.2.1 kube-controller-manager启动配置变化
不指定cloud-provider。
5.2.2 kube-apiserver启动配置变化
(1)不指定cloud-provider
(2)admission-control中删去PersistentVolumeLabel,因为CCM将接手PersistentVolumeLabel
(3)admission-control中增加Initializers
(4)runtime-config中增加admissionregistration.k8s.io/v1alpha1
5.2.3 kubelet启动配置变化
指定cloud-provider=external,告诉kubelet,在它开始调度工作前,需要被CCM初始化。(node会被打上 Taints:node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule)
5.3 启动CCM举例
5.3.1 启用initializers并添加InitializerConifguration
CCM为了给PV打标签需要:
(1)启用initializers(https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#enable-initializers-alpha-feature)
(2)添加InitializerConifguration:persistent-volume-label-initializer-config.yaml如下:
admin/cloud/pvl-initializer-config.yaml
kind: InitializerConfiguration
apiVersion: admissionregistration.k8s.io/v1alpha1
metadata:
name: pvlabel.kubernetes.io
initializers:
– name: pvlabel.kubernetes.io
rules:
– apiGroups:
– ""
apiVersions:
– "*"
resources:
– persistentvolumes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
———————
发表回复