Kubernetes 组件

本文介绍了Kubernetes集群所需的各种二进制组件。

Master 组件

Master组件提供集群的管理控制中心。

Master组件可以在集群中任何节点上运行。但是为了简单起见,通常在一台VM/机器上启动所有Master组件,并且不会在此VM/机器上运行用户容器。请参考 构建高可用群集以来构建multi-master-VM。

kube-apiserver

kube-apiserver用于暴露Kubernetes API。任何的资源请求/调用操作都是通过kube-apiserver提供的接口进行。请参阅构建高可用群集

ETCD

etcd是Kubernetes提供默认的存储系统,保存所有集群数据,使用时需要为etcd数据提供备份计划。

kube-controller-manager

kube-controller-manager运行管理控制器,它们是集群中处理常规任务的后台线程。逻辑上,每个控制器是一个单独的进程,但为了降低复杂性,它们都被编译成单个二进制文件,并在单个进程中运行。

这些控制器包括:

  • 节点(Node)控制器
  • 副本(Replication)控制器:负责维护系统中每个副本中的pod。
  • 端点(Endpoints)控制器:填充Endpoints对象(即连接Services&Pods)。
  • Service Account和Token控制器:为新的Namespace 创建默认帐户访问API Token。

cloud-controller-manager

云控制器管理器负责与底层云提供商的平台交互。云控制器管理器是Kubernetes版本1.6中引入的,目前还是Alpha的功能。

云控制器管理器仅运行云提供商特定的(controller loops)控制器循环。可以通过将--cloud-provider flag设置为external启动kube-controller-manager ,来禁用控制器循环。

cloud-controller-manager 具体功能:

  • 节点(Node)控制器
  • 路由(Route)控制器
  • Service控制器
  • 卷(Volume)控制器

kube-scheduler

kube-scheduler 监视新创建没有分配到NodePod,为Pod选择一个Node。

插件 addons

插件(addon)是实现集群pod和Services功能的 。Pod由Deployments,ReplicationController等进行管理。Namespace 插件对象是在kube-system Namespace中创建。

DNS

虽然不严格要求使用插件,但Kubernetes集群都应该具有集群 DNS。

群集 DNS是一个DNS服务器,能够为 Kubernetes services提供 DNS记录。

由Kubernetes启动的容器自动将这个DNS服务器包含在他们的DNS searches中。

了解更多详情

用户界面

kube-ui提供集群状态基础信息查看。更多详细信息,请参阅使用HTTP代理访问Kubernetes API

容器资源监测

容器资源监控提供一个UI浏览监控数据。

Cluster-level Logging

Cluster-level logging,负责保存容器日志,搜索/查看日志。

节点(Node)组件

节点组件运行在Node,提供Kubernetes运行时环境,以及维护Pod。

kubelet

kubelet是主要的节点代理,它会监视已分配给节点的pod,具体功能:

  • 安装Pod所需的volume。
  • 下载Pod的Secrets。
  • Pod中运行的 docker(或experimentally,rkt)容器。
  • 定期执行容器健康检查。
  • Reports the status of the pod back to the rest of the system, by creating a mirror pod if necessary.
  • Reports the status of the node back to the rest of the system.

kube-proxy

kube-proxy通过在主机上维护网络规则并执行连接转发来实现Kubernetes服务抽象。

docker

docker用于运行容器。

RKT

rkt运行容器,作为docker工具的替代方案。

supervisord

supervisord是一个轻量级的监控系统,用于保障kubelet和docker运行。

fluentd

fluentd是一个守护进程,可提供cluster-level logging.。

K8S中文社区微信公众号

Kubernetes是什么

Kubernetes是什么?

Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。

通过Kubernetes你可以:

  • 快速部署应用
  • 快速扩展应用
  • 无缝对接新的应用功能
  • 节省资源,优化硬件资源的使用

我们的目标是促进完善组件和工具的生态系统,以减轻应用程序在公有云或私有云中运行的负担。

Kubernetes 特点

  • 可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
  • 可扩展: 模块化, 插件化, 可挂载, 可组合
  • 自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展

Kubernetes是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本。

Why containers?

为什么要使用容器?通过以下两个图对比:

为什么是容器?

传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。

容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚机轻量、更“透明”,这更便于监控和管理。最后,

容器优势总结:

  • 快速创建/部署应用:与VM虚拟机相比,容器镜像的创建更加容易。
  • 持续开发、集成和部署:提供可靠且频繁的容器镜像构建/部署,并使用快速和简单的回滚(由于镜像不可变性)。
  • 开发和运行相分离:在build或者release阶段创建容器镜像,使得应用和基础设施解耦。
  • 开发,测试和生产环境一致性:在本地或外网(生产环境)运行的一致性。
  • 云平台或其他操作系统:可以在 Ubuntu、RHEL、 CoreOS、on-prem、Google Container Engine或其它任何环境中运行。
  • Loosely coupled,分布式,弹性,微服务化:应用程序分为更小的、独立的部件,可以动态部署和管理。
  • 资源隔离
  • 资源利用:更高效

使用Kubernetes能做什么?

可以在物理或虚拟机的Kubernetes集群上运行容器化应用,Kubernetes能提供一个以“容器为中心的基础架构”,满足在生产环境中运行应用的一些常见需求,如:

Kubernetes不是什么?

Kubernetes并不是传统的PaaS(平台即服务)系统。

  • Kubernetes不限制支持应用的类型,不限制应用框架。不限制受支持的语言runtimes (例如, Java, Python, Ruby),满足12-factor applications 。不区分 “apps” 或者“services”。 Kubernetes支持不同负载应用,包括有状态、无状态、数据处理类型的应用。只要这个应用可以在容器里运行,那么就能很好的运行在Kubernetes上。
  • Kubernetes不提供中间件(如message buses)、数据处理框架(如Spark)、数据库(如Mysql)或者集群存储系统(如Ceph)作为内置服务。但这些应用都可以运行在Kubernetes上面。
  • Kubernetes不部署源码不编译应用。持续集成的 (CI)工作流方面,不同的用户有不同的需求和偏好的区域,因此,我们提供分层的 CI工作流,但并不定义它应该如何工作。
  • Kubernetes允许用户选择自己的日志、监控和报警系统。
  • Kubernetes不提供或授权一个全面的应用程序配置 语言/系统(例如,jsonnet)。
  • Kubernetes不提供任何机器配置、维护、管理或者自修复系统。

另一方面,大量的Paas系统都可以运行在Kubernetes上,比如Openshift、Deis、Gondor。可以构建自己的Paas平台,与自己选择的CI系统集成。

由于Kubernetes运行在应用级别而不是硬件级,因此提供了普通的Paas平台提供的一些通用功能,比如部署,扩展,负载均衡,日志,监控等。这些默认功能是可选的。

另外,Kubernetes不仅仅是一个“编排系统”;它消除了编排的需要。“编排”的定义是指执行一个预定的工作流:先执行A,之B,然C。相反,Kubernetes由一组独立的可组合控制进程组成。怎么样从A到C并不重要,达到目的就好。当然集中控制也是必不可少,方法更像排舞的过程。这使得系统更加易用、强大、弹性和可扩展。

Kubernetes是什么意思?K8S?

Kubernetes的名字来自希腊语,意思是“舵手” 或 “领航员”K8s是将8个字母“ubernete”替换为“8”的缩写。

K8S中文社区微信公众号

Kubernetes中使用Node授权

Node授权是一种特殊授权模式,专门授权由kubelet访问的API请求。

概述

Node授权器允许kubelet执行的API操作包括:

读:

  • services
  • endpoints
  • nodes
  • pods
  • secrets, configmaps, persistent volume claims and persistent volumes related to pods bound to the kubelet’s node

写:

  • Node和Node status(启用NodeRestriction准入插件限制kubelet仅修改当前的Node)
  • Pod和Pod status(启用NodeRestriction准入插件限制kubelet仅修改与当前绑定的pod)
  • events

Auth-related:

  • read/write access to the certificationsigningrequests API for TLS bootstrapping
  • the ability to create tokenreviews and subjectaccessreviews for delegated authentication/authorization checks

在以后的版本中,Node授权器支持添加或删除的权限。

为获得Node授权器的授权,kubelet需要使用system:nodes组中的用户名system:node:<nodeName>。

启用Node授权器方法:apiserver --authorization-mode=Node。

为了限制kubelets能够写入的API对象,可以启动--admission-control=...,NodeRestriction,...准入(admission)插件。

Migration considerations

外部Kubelets system:node组

Node授权模式不授权外部Kubelets system:node组。

使用RBAC来升级

使用RBAC升级,1.7之前按原样运行,因为system:nodes group binding 已经存在。

如果希望开始使用Node授权和NodeRestriction 准入插件来限制对API的访问,则执行:

  1. 启用Node授权模式(--authorization-mode=Node,RBAC)和NodeRestriction 准入插件
  2. 确保所有kubelet的证书符合 group/username 要求
  3. 检查apiserver日志,确保Node授权器接受kubelets的请求(不NODE DENY记录持久性消息)
  4. 删除system:node集群 role binding

RBAC Node权限

在1.6中,使用RBAC授权模式时,system:node群集角色(role)自动绑定到该system:nodes组。

在1.7中,由于Node授权器实现了相同的目的,因此不再支持system:nodes组与system:node角色的自动绑定,从而有利于对secret 和configmap访问的附加限制。

在1.8中,将不会创建binding。

使用RBAC时,将继续创建system:node集群角色,以便兼容使用deployment将其他users或groups绑定到集群角色的方法。

K8S中文社区微信公众号

Kubernetes中使用RBAC授权

基于角色的访问控制(“RBAC”)使用“rbac.authorization.k8s.io”API 组来实现授权控制,允许管理员通过Kubernetes API动态配置策略。

截至1.6 RBAC模式是beta版。启用RBAC:

apiserver --authorization-mode=RBAC。

API概述

RBAC API声明了四个最高级别的类型(本文介绍),RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户,让用户有权进行授权管理,这样就无需接触节点,直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作。

Role 和 ClusterRole

Role是一系列的权限的集合,例如一个Role可以包含读取 Pod 的权限和列出 Pod 的权限, ClusterRole 跟 Role 类似,但是可以在集群中全局使用。

Role只能授予单个namespace 中资源的访问权限。以下是Role“default”namespace 中的示例,用于授予对pod的访问权限:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ClusterRole授权 >= Role授予(与Role类似),但ClusterRole属于集群级别对象:

  • 集群范围(cluster-scoped)的资源访问控制(如:节点访问权限)
  • 非资源类型(如“/ healthz”)
  • 所有namespaces 中的namespaced 资源(如 pod)

ClusterRole示例:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding和ClusterRoleBinding

RoleBinding是将Role中定义的权限授予给用户或用户组。它包含一个subjects列表(users,groups ,service accounts),并引用该Role。RoleBinding在某个namespace 内授权,ClusterRoleBinding适用在集群范围内使用。

RoleBinding可以引用相同namespace下定义的Role。以下的RoleBinding在“default”namespace中将“pod-reader”Role授予用户“jane”。将允许“jane”在“default”namespace中读取pod权限。

# This role binding allows "jane" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RoleBinding还可以参考ClusterRole。将允许管理员为整个集群定义一组通用Role,然后在不同namespace中使用RoleBinding引用。

示例:

# This role binding allows "dave" to read secrets in the "development" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets
  namespace: development # This only grants permissions within the "development" namespace.
subjects:
- kind: User
  name: dave
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

最后,ClusterRoleBinding可以用于集群中所有命名空间中授予权限。以下ClusterRoleBinding允许组“manager”中的任何用户在任何命名空间中读取secrets。

# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Referring to Resources

大多数资源由name字符串的形式表示,例如“pod”。然而,一些Kubernetes API 涉及“子资源”,例如Pod的logs ,pod log endpoint 的URL:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这种情况下,“pod”是namespace中资源,“log”是pod的子资源,这种情况要在RBAC角色中表示,可以使用斜杠来划分资源和子资源。如下例子:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

资源也可以通过resourceNames列表的某些请求的资源名称来引用。如下例子:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

需要注意如果设置了resourceNames,那么verbs不能指定为list、watch、create或deletecollection。

Role 示例

只有rules部分定义显示在以下示例中。

允许在核心API Group中读取“pods”资源:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

允许在“extensions”和“apps”API Group中读/写“deployments”:

rules:
- apiGroups: ["extensions", "apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取 “Pod” 和 读/写 “jobs”:

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取名称为 “my-config” 的 ConfigMap:

rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

允许读取核心 Group中资源“Node”(Node属于集群范围,则必须将ClusterRole绑定ClusterRoleBinding):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

允许非资源型“/ healthz”和所有子路径进行 “GET”和“POST”请求:(必须将ClusterRole绑定ClusterRoleBinding):

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
  verbs: ["get", "post"]

Referring to Subjects

RoleBinding或ClusterRoleBinding可以将Role绑定到主体subjects。Subjects 可以是groups、users和service accounts。

用户名Users由字符串表示,可用的格式有,如纯字符“alice”,Emai格式“bob@example.com”或表示为字符串的数字。Users除了需要满足Kubernetes管理员配置的 authentication modules,对Users, RBAC授权系统没有做任何格式限定。除了前缀为system:是为Kubernetes系统使用而保留的用户名格式,除此之外RBAC授权系统可以使用任何格式的Users。

Kubernetes的Group 信息目前由Authenticator模块提供。和Users 一样,Group 由字符串表示,而且字符串没有格式要求,除了前缀system:是保留的。

Service Accounts使用system:serviceaccount:前缀的用户名,并且属于具有system:serviceaccounts:前缀的Group组。

Role Binding 示例

适合一个名为“alice@example.com”的用户:

subjects:
- kind: User
  name: "alice@example.com"
  apiGroup: rbac.authorization.k8s.io

适合一个名为“frontend-admins”的Group:

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

适合kube-system Namespace中的默认ServiceAccount:

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

适合“qa”Namespace中的所有ServiceAccount:

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

适合集群中所有ServiceAccount:

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

适合所有经过认证的用户(1.5版本以上):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

适合所有未经认证的用户(1.5版本以上):

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

适合所有用户(1.5版本以上):

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

默认Role和 Role Bindings

API Server会创建一组默认的ClusterRole和ClusterRoleBinding对象。其中许多都是system:前缀,表示这些资源属于系统基础组件。修改这些资源对象可能会引起一些未知错误。例如:是system:nodeClusterRole,此角色定义了kubelet的权限,如果角色被修改,将会引起kubelet无法工作。

Auto-reconciliation

在每次启动时,API Server会更新默认的cluster roles ,并更新默认ClusterRoleBinding各个角色绑定主体,这使集群能够修复某些意外修改情况。

RBAC授权器处于激活状态时,在Kubernetes 1.6版本会默认启用Auto-reconciliation功能。

Discovery Roles

Default ClusterRole Default ClusterRoleBinding Description
system:basic-user system:

authenticated和

system:unauthenticatedgroups

Allows a user read-only access to basic information about themselves.
system:discovery system:

authenticated 和system:unauthenticatedgroups

Allows read-only access to API discovery endpoints needed to discover and negotiate an API level

User-facing Roles

一些不以system:为前缀的角色是面向用户的Role 。它们包括超级用户Role (cluster-admin),ClusterRoleBindings (cluster-status),以及特定namespaces中授权的 RoleBinding( admin,edit,view )

Default ClusterRole Default ClusterRoleBinding Description
cluster-admin system:masters group Allows super-user access to perform any action on any resource. When used in a ClusterRoleBinding, it gives full control over every resource in the cluster and in all namespaces. When used in a RoleBinding, it gives full control over every resource in the rolebinding's namespace, including the namespace itself.
admin None Allows admin access, intended to be granted within a namespace using a RoleBinding. If used in a RoleBinding, allows read/write access to most resources in a namespace, including the ability to create roles and rolebindings within the namespace. It does not allow write access to resource quota or to the namespace itself.
edit None Allows read/write access to most objects in a namespace. It does not allow viewing or modifying roles or rolebindings
view None Allows read-only access to see most objects in a namespace. It does not allow viewing roles or rolebindings. It does not allow viewing secrets, since those are escalating

Core Component Roles

Default ClusterRole Default ClusterRoleBinding Description
system:kube-scheduler system:kube-scheduler user Allows access to the resources required by the kube-scheduler component.
system:kube-controller-manager system:kube-controller-manager user Allows access to the resources required by the kube-controller-manager component. The permissions required by individual control loops are contained in the controller roles.
system:node system:nodes group (deprecated in 1.7) Allows access to resources required by the kubelet component, including read access to all secrets, and write access to all pods. As of 1.7, use of the [Node authorizer](/docs/admin/authorization/node/) and [NodeRestriction admission plugin](/docs/admin/admission-controllers#NodeRestriction) is recommended instead of this role, and allow granting API access to kubelets based on the pods scheduled to run on them. As of 1.7, when the `Node` authorization mode is enabled, the automatic binding to the `system:nodes` group is not created.
system:node-proxier system:kube-proxy user Allows access to the resources required by the kube-proxy component

Other Component Roles

Default ClusterRole Default ClusterRoleBinding Description
system:auth-delegator None Allows delegated authentication and authorization checks. This is commonly used by add-on API servers for unified authentication and authorization.
system:heapster None Role for the Heapster component.
system:kube-aggregator None Role for the kube-aggregator component.
system:kube-dns kube-dns service account in the kube-system namespace Role for the kube-dns component.
system:node-bootstrapper None Allows access to the resources required to perform Kubelet TLS bootstrapping.
system:node-problem-detector None Role for the node-problem-detector component.
system:persistent-volume-provisioner None Allows access to the resources required by most dynamic volume provisioners.

Controller Roles

Kubernetes controller manager负责运行的核心控制循环(core control loops)。当调用--use-service-account-credentials时,每个control loops都使用一个单独的service account启动,每个control loops存在前缀为system:controller:的Roles。如果controller manager未启动--use-service-account-credentials选项,它将使用本身的凭证运行所有control loops,如果这样需要在RBAC模式中授权相关Role。这些角色包括:

  • system:controller:attachdetach-controller
  • system:controller:certificate-controller
  • system:controller:cronjob-controller
  • system:controller:daemon-set-controller
  • system:controller:deployment-controller
  • system:controller:disruption-controller
  • system:controller:endpoint-controller
  • system:controller:generic-garbage-collector
  • system:controller:horizontal-pod-autoscaler
  • system:controller:job-controller
  • system:controller:namespace-controller
  • system:controller:node-controller
  • system:controller:persistent-volume-binder
  • system:controller:pod-garbage-collector
  • system:controller:replicaset-controller
  • system:controller:replication-controller
  • system:controller:resourcequota-controller
  • system:controller:route-controller
  • system:controller:service-account-controller
  • system:controller:service-controller
  • system:controller:statefulset-controller
  • system:controller:ttl-controller

命令行工具

有两个kubectl命令,用于在单个namespace或整个集群中授权Roles 。

kubectl create rolebinding

授权特定namespace中的Role或ClusterRole。如下示例:

  • 在“acme” Namespace将admin ClusterRole授予用户“bob”:
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
  • 在“acme”Namespace将view ClusterRole授予用户为“myapp”的Service Account:
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme

kubectl create clusterrolebinding

在整个集群中所有Namespace下授予ClusterRole。如下示例:

  • 在整个集群中将cluster-admin ClusterRole授予用户“root”:
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
  • 在整个集群中将system:node ClusterRole授予用户“kubelet”:
kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet
  • 在整个集群中将view ClusterRole授予Namespace “acme”中的serviceaccount”myapp”:
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp

更多详细用法,请参考CLI说明

Service Account Permissions

默认RBAC策略限定的权限授予范围有control-plane组件、nodes和controllers,不会向“kube-system”Namespace之外的Service Account授予权限。

这允许你根据需要向特定的Service Account授予特定的Role 。细粒度角色绑定提供了更好的安全性,但需要更复杂的管理工作。更宽松的角色权限绑定可以提供不必要的API访问服务帐户权限,但更容易管理。

安全级别逐步降低:

1、应用指定Service Account授予特定的Role(最佳实践)

kubectl create rolebinding my-sa-view \
  --clusterrole=view \
  --serviceaccount=my-namespace:my-sa \
  --namespace=my-namespace

2、在Namespace中为“default”Service Account提供一个Role

kubectl create clusterrolebinding add-on-cluster-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:default

3、为Namespace中所有Service Account提供Role

kubectl create rolebinding serviceaccounts-view \
  --clusterrole=view \
  --group=system:serviceaccounts:my-namespace \
  --namespace=my-namespace

4、为所有Service Account授予Role(不推荐)

kubectl create clusterrolebinding serviceaccounts-view \
  --clusterrole=view \
  --group=system:serviceaccounts

5、授予超级用户权限对所有Service Account(强烈反对)

kubectl create clusterrolebinding serviceaccounts-cluster-admin \
  --clusterrole=cluster-admin \
  --group=system:serviceaccounts

从1.5版本升级

在Kubernetes 1.6之前,许多部署使用的ABAC策略,像有对Service Account授予全部的API访问权限。

默认RBAC策略限定的权限授予范围有control-plane组件、nodes和controllers,不会向“kube-system”Namespace之外的Service Account授予权限。

虽然安全性更高,但这可能应权限问题影响到某些工作负载。以下是管理两种权限的方法:

Parallel Authorizers

一起运行RBAC和ABAC授权(并包括旧版ABAC策略):

--authorization-mode=RBAC,ABAC --authorization-policy-file=mypolicy.json

RBAC授权器将首先尝试对请求授权,如果API请求被拒绝,那么将进行ABAC授权。

可以在apiserver(以2(-v=2)或更高的日志级别运行)的日志中看到RBAC授权被拒绝信息,使用该日志信息可以查看哪些Roles需要被授予哪些 users, groups, 或service accounts。如果向service accounts授予Roles,并且在服务器日志中查看到没有RBAC被拒绝的工作负载消息的时,则可以删除ABAC授权器。

Permissive RBAC Permissions

可以使用RBAC role bindings复制一个宽泛的策略。

警告:下面的策略允许所有Service Account充当集群管理员。在容器中运行的任何应用程序都会自动接收service account credentials ,并且可以对API执行任何操作,包括查看secrets、修改权限。默认不推荐使用。

kubectl create clusterrolebinding permissive-binding \
  --clusterrole=cluster-admin \
  --user=admin \
  --user=kubelet \
  --group=system:serviceaccounts
 了解更多RBAC授权策略:https://www.kubernetes.org.cn/1879.html
K8S中文社区微信公众号

Kubernetes 使用准入控制器(Admission Controllers)

准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数,在对kubernetes api服务器的请求过程中,先经过认证授权后,执行准入操作,在对目标对象进行操作。这个准入插件代码在apiserver中,而且必须被编译到二进制文件中才能被执行。

在对集群进行请求时,每个准入控制插件都按顺序运行,只有全部插件都通过的请求才会进入系统,如果序列中的任何插件拒绝请求,则整个请求将被拒绝,并返回错误信息。

在某些情况下,为了适用于应用系统的配置,准入逻辑可能会改变目标对象。此外,准入逻辑也会改变请求操作的一部分相关资源。

为什么需要准入控制?

在kubernetes中,一些高级特性正常运行的前提条件为,将一些准入模块处于enable状态。总结下,对于kubernetes apiserver,如果不适当的配置准入控制模块,他就不能称作是一个完整的server,某些功能也不会正常的生效。

如何运行准入控制插件?

在kubernetes apiserver中有一个flag:admission_control,他的值为一串用逗号连接起、有序的准入模块列表,设置后,就可在对象操作前执行一定顺序的准入模块调用。

每个插件都做什么的?

AlwaysAdmit

结束所有的请求。

AlwaysPullImages

该插件修改每个新的Pod,强制pull最新镜像,这在多租户群集中非常有用,以便私有镜像只能由拥有授权凭据的用户使用。

AlwaysDeny

拒绝所有请求,一般用于测试。

DenyExecOnPrivileged(已弃用)

该插件将拦截所有请求。如果pod有一个privileged container,将只执行这个pod中的命令。
如果自己的集群支持privileged container,自己又希望限制用户在这些privileged container上执行命令,那么强烈推荐使用它。

此功能已合并到DenyEscalatingExec中。

DenyEscalatingExec

禁止privileged container的exec和attach操作。

ImagePolicyWebhook

通过webhook决定image策略,需要同时配置--admission-control=ImagePolicyWebhook,配置文件格式如下。

配置文件格式

ImagePolicyWebhook使用admission配置文件--admission-control-config-file为Backend Behavior设置配置选项。该文件可以是json或yaml并具有以下格式:

{
  "imagePolicy": {
     "kubeConfigFile": "path/to/kubeconfig/for/backend",
     "allowTTL": 50,           // time in s to cache approval
     "denyTTL": 50,            // time in s to cache denial
     "retryBackoff": 500,      // time in ms to wait between retries
     "defaultAllow": true      // determines behavior if the webhook backend fails
  }
}

配置文件必须引用一个kubeconfig格式的文件,该文件设置与后端的连接,通过TLS进行通信。

kubeconfig文件的集群字段须指向remote service,users字段须包含returned authorizer。

# clusters refers to the remote service.
clusters:
- name: name-of-remote-imagepolicy-service
  cluster:
    certificate-authority: /path/to/ca.pem    # CA for verifying the remote service.
    server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.

# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
  user:
    client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
    client-key: /path/to/key.pem          # key matching the cert

其他HTTP配置,请参考kubeconfig文档。

ServiceAccount

该插件将serviceAccounts 实现了自动化。如果打算使用Kubernetes ServiceAccount对象,那么强烈建议使用此插件。

SecurityContextDeny

该插件会将使用了 SecurityContext的pod中定义的选项全部失效 。

ResourceQuota

该插件将会观察传入的所有请求,并确保它不会违反ResourceQuota对象中枚举的任何限制Namespace。如果在Kubernetes Deployment中使用了ResourceQuota对象,则必须使用此插件来约束Container。

更多详细信息,请参阅resourceQuota design docexample of Resource Quota

推荐在Admission Control参数列表中,这个插件排最后一个。

LimitRanger

该插件将会观察传入的所有请求,并确保它不会违反LimitRanger对象中枚举的任何限制Namespace,如果在Kubernetes Deployment中使用了LimitRanger对象,则必须使用此插件。LimitRanger还可使用Apply将default资源请求不指定任何的Pods; 目前LimitRanger对Default Namespace中的所有pod应用要求0.1 CPU

更多详细信息,请参阅limitRange design docexample of Limit Range 。

InitialResources(试验)

根据镜像的历史使用记录,为容器设置默认资源请求和limits。

更多详细信息,参考 InitialResouces proposal

NamespaceLifecycle

该插件确保处于Termination状态的Namespace不再接收新的对象创建请求,并拒绝请求不存在的Namespace。该插件还可以防止删除系统保留的Namespace:default,kube-system,kube-public。

DefaultStorageClass

该插件将观察PersistentVolumeClaim,并自动设置默认的Storage Class。

当没有配置默认Storage Class时,此插件不会执行任何操作。当有多个Storage Class被标记为默认值时,它也将拒绝任何创建,管理员必须重新访问StorageClass对象,并且只标记一个作为默认值。此插件不用于PersistentVolumeClaim的更新,仅用于创建。

更多详细信息,参考persistent volume

DefaultTolerationSeconds

该插件设置Pod的默认forgiveness toleration为5分钟。

PodSecurityPolicy

该插件用于创建和修改pod,使用Pod Security Policies时需要开启。

当 Kubernetes <1.6.0版本时,API服务器需要启用扩展名/ v1beta1 / podsecuritypolicy API扩展组(--runtime-config=extensions/v1beta1/podsecuritypolicy=true)。

更多信息,请参考Pod Security Policy documentation

NodeRestriction

此插件限制kubelet修改Node和Pod对象,这样的kubelets只允许修改绑定到Node的Pod API对象,以后版本可能会增加额外的限制。

限制kubelet仅可访问node、endpoint、pod、service以及secret、configmap、PV和PVC等相关的资源(仅适用于v1.7+)

对于Kubernetes> = 1.6.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds

对于Kubernetes> = 1.4.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota

对于Kubernetes> = 1.2.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota

对于Kubernetes> = 1.0.0 版本,建议运行以下的准入控制插件(需要按顺序进行):

--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,PersistentVolumeLabel,ResourceQuota
K8S中文社区微信公众号

使用Minikube在Kubernetes中运行应用

教程的目标是将简单的Hello World Node.js应用转换为在Kubernetes上运行的应用。本教程将学习如何使用自己开发的代码,将其转换为Docker容器镜像,然后在Minikube上运行该镜像。Minikube能够在本地非常简单的创建Kubernetes。

目标

  • 运行hello world Node.js应用。
  • 在Minikube上部署应用。
  • 查看应用日志
  • 更新应用镜像。

准备工作

创建Minikube集群

本教程使用Minikube创建本地集群,默认使用 Docker for Mac。如果在不同的平台(如Linux)上,或使用VirtualBox而不是Docker for Mac,则安装Minikube方式有些不同。有关Minikube的详细安装说明,请参考Minikube安装指南

使用curl下载并安装最新版本Minikube:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 && \
  chmod +x minikube && \
  sudo mv minikube /usr/local/bin/

使用Homebrew安装xhyve驱动程序并设置其权限:

brew install docker-machine-driver-xhyve
sudo chown root:wheel $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve
sudo chmod u+s $(brew --prefix)/opt/docker-machine-driver-xhyve/bin/docker-machine-driver-xhyve

使用Homebrew下载kubectl命令管理工具:

brew install kubectl

确定是否可以直接访问https://cloud.google.com/container-registry/网站(是否翻墙?)

curl --proxy "" https://cloud.google.com/container-registry/

如果不需代理,则启动Minikube集群:

minikube start --vm-driver=xhyve

如果需代理服务器,使用以下方法启动设置了代理的Minikube集群:

minikube start --vm-driver=xhyve --docker-env HTTP_PROXY=http://your-http-proxy-host:your-http-proxy-port  --docker-env HTTPS_PROXY=http(s)://your-https-proxy-host:your-https-proxy-port

--vm-driver=xhyve flag 指定Docker for Mac。默认的VM驱动程序VirtualBox。

设置Minikube 环境。可以在~/.kube/config文件中查看所有可用的环境 。

kubectl config use-context minikube

验证kubectl配置:

kubectl cluster-info

创建Node.js应用程序

下一步编写应用程序。将这段代码保存在一个名为hellonode的文件夹中,文件名server.js:

server.js

var http = require('http');

var handleRequest = function(request, response) {
  console.log('Received request for URL: ' + request.url);
  response.writeHead(200);
  response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);

运行应用:

node server.js

现在可以在http:// localhost:8080 / 中查看到“Hello World!”消息。

按Ctrl-C停止正在运行的Node.js服务器。

下一步将应用程序打包到Docker容器中。

创建Docker容器镜像

在hellonode文件夹中创建一个Dockerfile命名的文件。Dockerfile描述了build的镜像,通过现有的镜像扩展(extend)build Docker容器镜像,本教程中的镜像扩展(extend)了现有的Node.js镜像。

Dockerfile 

FROM node:6.9.2
EXPOSE 8080
COPY server.js .
CMD node server.js

 

本教程使用Minikube,而不是将Docker镜像push到registry,可以使用与Minikube VM相同的Docker主机构建镜像,以使镜像自动存在。为此,请确保使用Minikube Docker守护进程:

eval $(minikube docker-env)

注意:如果不在使用Minikube主机时,可以通过运行eval $(minikube docker-env -u)来撤消此更改。

使用Minikube Docker守护进程build Docker镜像:

docker build -t hello-node:v1 .

好了Minikube VM可以运行构建好的镜像。

创建Deployment

Kubernetes Pod是一个或多个容器组合在一起得共享资源,本教程中的Pod只有一个容器。Kubernetes Deployment 是检查Pod的健康状况,如果它终止,则重新启动一个Pod的容器,Deployment管理Pod的创建和扩展。

使用kubectl run命令创建Deployment来管理Pod。Pod根据hello-node:v1Docker运行容器镜像:

kubectl run hello-node --image=hello-node:v1 --port=8080

查看Deployment:

kubectl get deployments

输出:

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-node   1         1         1            1           3m

查看Pod:

kubectl get pods

输出:

NAME                         READY     STATUS    RESTARTS   AGE
hello-node-714049816-ztzrb   1/1       Running   0          6m

查看群集events:

kubectl get events

查看kubectl配置:

kubectl config view

有关kubectl命令的更多信息,请参阅 kubectl概述

创建Service

默认情况,这Pod只能通过Kubernetes群集内部IP访问。要使hello-node容器从Kubernetes虚拟网络外部访问,须要使用Kubernetes Service暴露Pod。

我们可以使用kubectl expose命令将Pod暴露到外部环境:

kubectl expose deployment hello-node --type=LoadBalancer

查看刚创建的Service:

kubectl get services

输出:

NAME         CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
hello-node   10.0.0.71    <pending>     8080/TCP   6m
kubernetes   10.0.0.1     <none>        443/TCP    14d

通过--type=LoadBalancer flag来在群集外暴露Service,在支持负载均衡的云提供商上,将配置外部IP地址来访问Service。在Minikube上,该LoadBalancer type使服务可以通过minikube Service 命令访问。

minikube service hello-node

将打开浏览器,在本地IP地址为应用提供服务,显示“Hello World”的消息。

最后可以查看到一些日志

kubectl logs <POD-NAME>

更新应用程序

编辑server.js文件以返回新消息:

response.end('Hello World Again!');

build新版本镜像

docker build -t hello-node:v2 .

Deployment更新镜像:

kubectl set image deployment/hello-node hello-node=hello-node:v2

再次运行应用以查看新消息:

minikube service hello-node

清理删除

现在可以删除在群集中创建的资源:

kubectl delete service hello-node
kubectl delete deployment hello-node

或者停止Minikube:

minikube stop

下一步

K8S中文社区微信公众号