Skip to content

Commit

Permalink
Merge branch 'master' into release-1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
steveperry-53 committed Sep 28, 2017
2 parents 23e9d47 + 88d3ed8 commit 793dd13
Show file tree
Hide file tree
Showing 16 changed files with 3,223 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
title: 理解 Kubernetes 对象

redirect_from:
- "/docs/concepts/abstractions/overview/"
- "/docs/concepts/abstractions/overview.html"
---

{% capture overview %}

本页说明了 Kubernetes 对象在 Kubernetes API 中是如何表示的,以及如何在 `.yaml` 格式的文件中表示。
{% endcapture %}

{% capture body %}




## 理解 Kubernetes 对象

在 Kubernetes 系统中,*Kubernetes 对象* 是持久化的实体。Kubernetes 使用这些实体去表示整个集群的状态。特别地,它们描述了如下信息:

* 哪些容器化应用在运行(以及在哪个 Node 上)
* 可以被应用使用的资源
* 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略



Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,本质上是在告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 **期望状态(Desired State)**

操作 Kubernetes 对象 —— 是否创建、修改,或者删除 —— 需要使用 [Kubernetes API](https://git.k8s.io/community/contributors/devel/api-conventions.md)。比如,当使用 `kubectl` 命令行接口时,CLI 会执行必要的 Kubernetes API 调用,也可以在程序中直接调用 Kubernetes API。为了实现该目标,Kubernetes 当前提供了一个 `golang` [客户端库](https://github.com/kubernetes/client-go)
,其它语言库(例如[Python](https://github.com/kubernetes-incubator/client-python))也正在开发中。



### 对象规约(Spec)与状态(Status)

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 *spec* 和 对象 *status*
*spec* 是必需的,它描述了对象的 *期望状态(Desired State)* —— 希望对象所具有的特征。
*status* 描述了对象的 *实际状态(Actual State)*,它是由 Kubernetes 系统提供和更新的。在任何时刻,Kubernetes 控制面一直努力地管理着对象的实际状态以与期望状态相匹配。



例如,Kubernetes Deployment 对象能够表示运行在集群中的应用。
当创建 Deployment 时,可能需要设置 Deployment 的规约,以指定该应用需要有 3 个副本在运行。
Kubernetes 系统读取 Deployment 规约,并启动我们所期望的该应用的 3 个实例 —— 更新状态以与规约相匹配。
如果那些实例中有失败的(一种状态变更),Kubernetes 系统通过修正来响应规约和状态之间的不一致 —— 这种情况,会启动一个新的实例来替换。

关于对象 spec、status 和 metadata 的更多信息,查看 [Kubernetes API 约定](https://git.k8s.io/community/contributors/devel/api-conventions.md)



### 描述 Kubernetes 对象

当创建 KUbernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。
当使用 KUbernetes API 创建对象时(或者直接创建,或者基于`kubectl`),API 请求必须在请求体中包含 JSON 格式的信息。
**大多数情况下,需要在 .yaml 文件中为 `kubectl` 提供这些信息**
`kubectl` 在发起 API 请求时,将这些信息转换成 JSON 格式。

这里有一个 `.yaml` 示例文件,展示了 KUbernetes Deployment 的必需字段和对象规约:

{% include code.html language="yaml" file="nginx-deployment.yaml" ghlink="/docs/concepts/overview/working-with-objects/nginx-deployment.yaml" %}

使用类似于上面的 `.yaml` 文件来创建 Deployment,一种方式是使用 `kubectl` 命令行接口(CLI)中的 [`kubectl create`](/docs/user-guide/kubectl/v1.7/#create) 命令,将 `.yaml` 文件作为参数。下面是一个示例:

```shell
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
```


输出类似如下这样:

```shell
deployment "nginx-deployment" created
```



### 必需字段

在想要创建的 KUbernetes 对象对应的 `.yaml` 文件中,需要配置如下的字段:

* `apiVersion` - 创建该对象所使用的 Kubernetes API 的版本
* `kind` - 想要创建的对象的类型
* `metadata` - 帮助识别对象唯一性的数据,包括一个 `name` 字符串、UID 和可选的 `namespace`



也需要提供对象的 `spec` 字段。对象 `spec` 的精确格式对每个 Kubernetes 对象来说是不同的,包含了特定于该对象的嵌套字段。[Kubernetes API 参考](/docs/api/)能够帮助我们找到任何我们想创建的对象的 spec 格式。

{% endcapture %}

{% capture whatsnext %}

* 了解最重要的基本 Kubernetes 对象,例如 [Pod](/docs/concepts/abstractions/pod/)
{% endcapture %}

{% include templates/concept.md %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
221 changes: 221 additions & 0 deletions cn/docs/concepts/policy/pod-security-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
---
assignees:
- pweil-
title: Pod 安全策略
redirect_from:
- "/docs/user-guide/pod-security-policy/"
- "/docs/user-guide/pod-security-policy/index.html"
---



`PodSecurityPolicy` 类型的对象能够控制,是否可以向 Pod 发送请求,该 Pod 能够影响被应用到 Pod 和容器的 `SecurityContext`
查看 [Pod 安全策略建议](https://git.k8s.io/community/contributors/design-proposals/security-context-constraints.md) 获取更多信息。

* TOC
{:toc}



## 什么是 Pod 安全策略?

_Pod 安全策略_ 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。
`PodSecurityPolicy` 对象定义了一组条件,指示 Pod 必须按系统所能接受的顺序运行。
它们允许管理员控制如下方面:



| 控制面 | 字段名称 |
| ------------------------------------------------------------- | --------------------------------- |
| 已授权容器的运行 | `privileged` |
| 为容器添加默认的一组能力 | `defaultAddCapabilities` |
| 为容器去掉某些能力 | `requiredDropCapabilities` |
| 容器能够请求添加某些能力 | `allowedCapabilities` |
| 控制卷类型的使用 | [`volumes`](#controlling-volumes) |
| 主机网络的使用 | [`hostNetwork`](#host-network) |
| 主机端口的使用 | `hostPorts` |
| 主机 PID namespace 的使用 | `hostPID` |
| 主机 IPC namespace 的使用 | `hostIPC` |
| 主机路径的使用 | [`allowedHostPaths`](#allowed-host-paths) |
| 容器的 SELinux 上下文 | [`seLinux`](#selinux) |
| 用户 ID | [`runAsUser`](#runasuser) |
| 配置允许的补充组 | [`supplementalGroups`](#supplementalgroups) |
| 分配拥有 Pod 数据卷的 FSGroup | [`fsGroup`](#fsgroup) |
| 必须使用一个只读的 root 文件系统 | `readOnlyRootFilesystem` |



_Pod 安全策略_ 由设置和策略组成,它们能够控制 Pod 访问的安全特征。这些设置分为如下三类:

- *基于布尔值控制*:这种类型的字段默认为最严格限制的值。
- *基于被允许的值集合控制*:这种类型的字段会与这组值进行对比,以确认值被允许。
- *基于策略控制*:设置项通过一种策略提供的机制来生成该值,这种机制能够确保指定的值落在被允许的这组值中。



### RunAsUser



- *MustRunAs* - 必须配置一个 `range`。使用该范围内的第一个值作为默认值。验证是否不在配置的该范围内。
- *MustRunAsNonRoot* - 要求提交的 Pod 具有非零 `runAsUser` 值,或在镜像中定义了 `USER` 环境变量。不提供默认值。
- *RunAsAny* - 没有提供默认值。允许指定任何 `runAsUser`



### SELinux

- *MustRunAs* - 如果没有使用预分配的值,必须配置 `seLinuxOptions`。默认使用 `seLinuxOptions`。验证 `seLinuxOptions`
- *RunAsAny* - 没有提供默认值。允许任意指定的 `seLinuxOptions` ID。



### SupplementalGroups

- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证所有范围的值。
- *RunAsAny* - 没有提供默认值。允许任意指定的 `supplementalGroups` ID。



### FSGroup

- *MustRunAs* - 至少需要指定一个范围。默认使用第一个范围的最小值。验证在第一个范围内的第一个 ID。
- *RunAsAny* - 没有提供默认值。允许任意指定的 `fsGroup` ID。



### 控制卷

通过设置 PSP 卷字段,能够控制具体卷类型的使用。当创建一个卷的时候,与该字段相关的已定义卷可以允许设置如下值:

1. azureFile
1. azureDisk
1. flocker
1. flexVolume
1. hostPath
1. emptyDir
1. gcePersistentDisk
1. awsElasticBlockStore
1. gitRepo
1. secret
1. nfs
1. iscsi
1. glusterfs
1. persistentVolumeClaim
1. rbd
1. cinder
1. cephFS
1. downwardAPI
1. fc
1. configMap
1. vsphereVolume
1. quobyte
1. photonPersistentDisk
1. projected
1. portworxVolume
1. scaleIO
1. storageos
1. \* (allow all volumes)



对新的 PSP,推荐允许的卷的最小集合包括:configMap、downwardAPI、emptyDir、persistentVolumeClaim、secret 和 projected。



### 主机网络
- *HostPorts*, 默认为 `empty``HostPortRange` 列表通过 `min`(包含) and `max`(包含) 来定义,指定了被允许的主机端口。

### 允许的主机路径
- *AllowedHostPaths* 是一个被允许的主机路径前缀的白名单。空值表示所有的主机路径都可以使用。



## 许可

包含 `PodSecurityPolicy`_许可控制_,允许控制集群资源的创建和修改,基于这些资源在集群范围内被许可的能力。

许可使用如下的方式为 Pod 创建最终的安全上下文:
1. 检索所有可用的 PSP。
1. 生成在请求中没有指定的安全上下文设置的字段值。
1. 基于可用的策略,验证最终的设置。

如果某个策略能够匹配上,该 Pod 就被接受。如果请求与 PSP 不匹配,则 Pod 被拒绝。

Pod 必须基于 PSP 验证每个字段。



## 创建 Pod 安全策略

下面是一个 Pod 安全策略的例子,所有字段的设置都被允许:

{% include code.html language="yaml" file="psp.yaml" ghlink="/docs/concepts/policy/psp.yaml" %}



下载示例文件可以创建该策略,然后执行如下命令:

```shell
$ kubectl create -f ./psp.yaml
podsecuritypolicy "permissive" created
```



## 获取 Pod 安全策略列表

获取已存在策略列表,使用 `kubectl get`

```shell
$ kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
permissive false [] RunAsAny RunAsAny RunAsAny RunAsAny false [*]
privileged true [] RunAsAny RunAsAny RunAsAny RunAsAny false [*]
restricted false [] RunAsAny MustRunAsNonRoot RunAsAny RunAsAny false [emptyDir secret downwardAPI configMap persistentVolumeClaim projected]
```



## 修改 Pod 安全策略

通过交互方式修改策略,使用 `kubectl edit`

```shell
$ kubectl edit psp permissive
```



该命令将打开一个默认文本编辑器,在这里能够修改策略。



## 删除 Pod 安全策略

一旦不再需要一个策略,很容易通过 `kubectl` 删除它:

```shell
$ kubectl delete psp permissive
podsecuritypolicy "permissive" deleted
```



## 启用 Pod 安全策略

为了能够在集群中使用 Pod 安全策略,必须确保满足如下条件:



1. 已经启用 API 类型 `extensions/v1beta1/podsecuritypolicy`(仅对 1.6 之前的版本)
1. 已经启用许可控制器 `PodSecurityPolicy`
1. 已经定义了自己的策略



## 使用 RBAC

在 Kubernetes 1.5 或更新版本,可以使用 PodSecurityPolicy 来控制,对基于用户角色和组的已授权容器的访问。访问不同的 PodSecurityPolicy 对象,可以基于认证来控制。基于 Deployment、ReplicaSet 等创建的 Pod,限制访问 PodSecurityPolicy 对象,[Controller Manager](/docs/admin/kube-controller-manager/) 必须基于安全 API 端口运行,并且不能够具有超级用户权限。

PodSecurityPolicy 认证使用所有可用的策略,包括创建 Pod 的用户,Pod 上指定的服务账户(Service Acount)。当 Pod 基于 Deployment、ReplicaSet 创建时,它是创建 Pod 的 Controller Manager,所以如果基于非安全 API 端口运行,允许所有的 PodSecurityPolicy 对象,并且不能够有效地实现细分权限。用户访问给定的 PSP 策略有效,仅当是直接部署 Pod 的情况。更多详情,查看 [PodSecurityPolicy RBAC 示例](https://git.k8s.io/kubernetes/examples/podsecuritypolicy/rbac/README.md),当直接部署 Pod 时,应用 PodSecurityPolicy 控制基于角色和组的已授权容器的访问 。
18 changes: 18 additions & 0 deletions cn/docs/concepts/policy/psp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: permissive
spec:
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
hostPorts:
- min: 8000
max: 8080
volumes:
- '*'
Loading

0 comments on commit 793dd13

Please sign in to comment.