From 532900f81909dd380a604dd40047bde120fd996d Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Fri, 18 Aug 2017 17:30:16 +0800 Subject: [PATCH 01/32] Update index.md Fix the format. The format in orginal web page is confusion. --- docs/admin/authorization/index.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/admin/authorization/index.md b/docs/admin/authorization/index.md index 61ad340eb4..cc2dfed4a6 100644 --- a/docs/admin/authorization/index.md +++ b/docs/admin/authorization/index.md @@ -136,11 +136,12 @@ to determine what access an authorizer is granting. You must include a flag in your policy to indicate which authorization module your policies include: The following flags can be used: - - `--authorization-mode=ABAC` Attribute-Based Access Control (ABAC) mode allows you to configure policies using local files. - - `--authorization-mode=RBAC` Role-based access control (RBAC) mode allows you to create and store policies using the Kubernetes API. - - `--authorization-mode=Webhook` WebHook is an HTTP callback mode that allows you to manage authorization using a remote REST. - - `--authorization-mode=AlwaysDeny` This flag blocks all requests. Use this flag only for testing. - - `--authorization-mode=AlwaysAllow` This flag allows all requests. Use this flag only if you do not require authorization for your API requests. + + * `--authorization-mode=ABAC` Attribute-Based Access Control (ABAC) mode allows you to configure policies using local files. + * `--authorization-mode=RBAC` Role-based access control (RBAC) mode allows you to create and store policies using the Kubernetes API. + * `--authorization-mode=Webhook` WebHook is an HTTP callback mode that allows you to manage authorization using a remote REST. + * `--authorization-mode=AlwaysDeny` This flag blocks all requests. Use this flag only for testing. + * `--authorization-mode=AlwaysAllow` This flag allows all requests. Use this flag only if you do not require authorization for your API requests. You can choose more than one authorization module. If one of the modes is `AlwaysAllow`, then it overrides the other modes and all API requests are allowed. From ea05cd4a56b23b9d5272879daa0ebb5f700a56d2 Mon Sep 17 00:00:00 2001 From: Li Jingjing Date: Sat, 19 Aug 2017 15:13:23 +0800 Subject: [PATCH 02/32] kube-apiserver-pr --- cn/docs/admin/kube-apiserver.md | 233 ++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 cn/docs/admin/kube-apiserver.md diff --git a/cn/docs/admin/kube-apiserver.md b/cn/docs/admin/kube-apiserver.md new file mode 100644 index 0000000000..7200eb73a2 --- /dev/null +++ b/cn/docs/admin/kube-apiserver.md @@ -0,0 +1,233 @@ +--- +title: kube-apiserver +notitle: true +--- +## kube-apiserver + + + +### 概要 + + +Kubernetes API server 为 api 对象验证并配置数据,包括 pods、 services、 replicationcontrollers和其它 api 对象。API Server 提供 REST 操作和到集群共享状态的前端,所有其他组件通过它进行交互。 + +``` +kube-apiserver +``` + +### 选项 +``` + + --admission-control stringSlice 控制资源进入集群的准入控制插件的顺序列表。逗号分隔的NamespaceLifecycle列表。(默认值[AlwaysAdmit]) + + --admission-control-config-file string 包含准入控制配置的文件。 + + --advertise-address ip 向集群成员通知apiserver消息的IP地址。这个地址必须能够被集群中其他成员访问。如果IP地址为空,将会使用--bind-address,如果未指定--bind-address,将会使用主机的默认接口地址。 + + --allow-privileged 如果为true, 将允许特权容器. + + --anonymous-auth 启用到API server的安全端口的匿名请求。未被其他认证方法拒绝的请求被当做匿名请求。匿名请求的用户名为system:anonymous,用户组名为system:unauthenticated。(默认值true) + + --apiserver-count int 集群中运行的apiserver数量,必须为正数。(默认值1) + + --audit-log-maxage int 基于文件名中的时间戳,旧审计日志文件的最长保留天数。 + + --audit-log-maxbackup int 旧审计日志文件的最大保留个数. + + --audit-log-maxsize int 审计日志被轮转前的最大兆字节数。 + + --audit-log-path string 如果设置该值,所有到apiserver的请求都将会被记录到这个文件。'-'表示记录到标准输出。 + + --audit-policy-file string 定义审计策略配置的文件的路径。需要打开'AdvancedAuditing'特性开关。AdvancedAuditing需要一个配置来启用审计功能。 + + --audit-webhook-config-file string 一个具有kubeconfig格式文件的路径,该文件定义了审计的webhook配置。需要打开'AdvancedAuditing'特性开关。 + + --audit-webhook-mode string 发送审计事件的策略。 Blocking模式表示正在发送事件时应该阻塞服务器的响应。 Batch模式使webhook异步缓存和发送事件。 Known模式为batch,blocking。 (默认值"batch") + + --authentication-token-webhook-cache-ttl duration 从webhook令牌认证者获取的响应的缓存时长。(默认值2m0s) + + --authentication-token-webhook-config-file string 包含webhook配置的文件,用于令牌认证,具有kubeconfig格式。API server将查询远程服务来决定对bearer令牌的认证。 + + --authorization-mode string 在安全端口上进行权限验证的插件的顺序列表。以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值"AlwaysAllow") + + --authorization-policy-file string 包含权限验证策略的csv文件,和--authorization-mode=ABAC一起使用,作用在安全端口上。 + + --authorization-webhook-cache-authorized-ttl duration 从webhook授权者获得的'authorized'响应的缓存时长。(默认值5m0s) + + --authorization-webhook-cache-unauthorized-ttl duration 从webhook授权者获得的'unauthorized'响应的缓存时长。(默认值30s) + + --authorization-webhook-config-file string 包含webhook配置的kubeconfig格式文件,和--authorization-mode=Webhook一起使用。API server将查询远程服务来决定对API server安全端口的访问。 + + --azure-container-registry-config string 包含Azure容器注册表配置信息的文件的路径。 + + --basic-auth-file string 如果设置该值,这个文件将会被用于准许通过http基本认证到API server安全端口的请求。 + + --bind-address ip 监听--seure-port的IP地址。被关联的接口必须能够被集群其它节点和CLI/web客户端访问。如果为空,则将使用所有接口(0.0.0.0)。(默认值0.0.0.0) + + --cert-dir string 存放TLS证书的目录。如果提供了--tls-cert-file和--tls-private-key-file选项,该标志将被忽略。(默认值 "/var/run/kubernetes") + + --client-ca-file string 如果设置此标志,对于任何请求,如果存包含client-ca-file中的authorities签名的客户端证书,将会使用客户端证书中的CommonName对应的身份进行认证。 + + --cloud-config string 云服务提供商配置文件路径。空字符串表示无配置文件. + + --cloud-provider string 云服务提供商,空字符串表示无提供商。 + + --contention-profiling 如果已经启用profiling,则启用锁竞争profiling。 + + --cors-allowed-origins stringSlice CORS的域列表,以逗号分隔。合法的域可以是一个匹配子域名的正则表达式。如果这个列表为空则不会启用CORS. + + --delete-collection-workers int 用于DeleteCollection调用的工作者数量。这被用于加速namespace的清理。(默认值1) + + --deserialization-cache-size int 在内存中缓存的反序列化json对象的数量。 + + --enable-aggregator-routing 打开到endpoints IP的aggregator路由请求,替换cluster IP。 + + --enable-garbage-collector 启用通用垃圾回收器. 必须与kube-controller-manager对应的标志保持同步。 (默认值true) + + --enable-logs-handler 如果为true,则为apiserver日志功能安装一个/logs处理器。(默认值true) + + --enable-swagger-ui 在apiserver的/swagger-ui路径启用swagger ui。 + + --etcd-cafile string 用于保护etcd通信的SSL CA文件。 + + --etcd-certfile string 用于保护etcd通信的的SSL证书文件。 + + --etcd-keyfile string 用于保护etcd通信的SSL密钥文件. + + --etcd-prefix string 附加到所有etcd中资源路径的前缀。 (默认值"/registry") + + --etcd-quorum-read 如果为true, 启用quorum读。 + + --etcd-servers stringSlice 连接的etcd服务器列表,形式为(scheme://ip:port),使用逗号分隔。 + + --etcd-servers-overrides stringSlice 针对单个资源的etcd服务器覆盖配置, 以逗号分隔。 单个配置覆盖格式为: group/resource#servers, 其中servers形式为http://ip:port, 以分号分隔。 + + --event-ttl duration 事件驻留时间。(默认值1h0m0s) + + --experimental-bootstrap-token-auth 启用此选项以允许'kube-system'命名空间中的'bootstrap.kubernetes.io/token'类型密钥可以被用于TLS的启动认证。 + + --experimental-encryption-provider-config string 包含加密提供程序的配置的文件,该加密提供程序被用于在etcd中保存密钥。 + + --experimental-keystone-ca-file string 如果设置该值,将会使用experimental-keystone-ca-file中的一个authority对Keystone服务的证书进行验证,否则将会使用主机的根CA进行验证。 + + --experimental-keystone-url string 如果设置了该值,将启用keystone认证插件。 + + --external-hostname string 为此master生成外部URL时使用的主机名(例如Swagger API文档)。 + + --feature-gates mapStringBool 一个描述alpha/experimental特性开关的键值对列表。 选项包括: +Accelerators=true|false (ALPHA - default=false) +AdvancedAuditing=true|false (ALPHA - default=false) +AffinityInAnnotations=true|false (ALPHA - default=false) +AllAlpha=true|false (ALPHA - default=false) +AllowExtTrafficLocalEndpoints=true|false (default=true) +AppArmor=true|false (BETA - default=true) +DynamicKubeletConfig=true|false (ALPHA - default=false) +DynamicVolumeProvisioning=true|false (ALPHA - default=true) +ExperimentalCriticalPodAnnotation=true|false (ALPHA - default=false) +ExperimentalHostUserNamespaceDefaulting=true|false (BETA - default=false) +LocalStorageCapacityIsolation=true|false (ALPHA - default=false) +PersistentLocalVolumes=true|false (ALPHA - default=false) +RotateKubeletClientCertificate=true|false (ALPHA - default=false) +RotateKubeletServerCertificate=true|false (ALPHA - default=false) +StreamingProxyRedirects=true|false (BETA - default=true) +TaintBasedEvictions=true|false (ALPHA - default=false) + + --google-json-key string 用于认证的Google Cloud Platform服务账号的JSON密钥。 + + --insecure-allow-any-token username/group1,group2 如果设置该值, 你的服务将处于非安全状态。任何令牌都将会被允许,并将从令牌中把用户信息解析成为username/group1,group2。 + + --insecure-bind-address ip 用于监听--insecure-port的IP地址 (设置成0.0.0.0表示监听所有接口)。(默认值127.0.0.1) + + --insecure-port int 用于监听不安全和为认证访问的端口。这个配置假设你已经设置了防火墙规则,使得这个端口不能从集群外访问。对集群的公共地址的443端口的访问将被代理到这个端口。默认设置中使用nginx实现。(默认值8080) + + --kubelet-certificate-authority string 证书authority的文件路径。 + + --kubelet-client-certificate string 用于TLS的客户端证书文件路径。 + + --kubelet-client-key string 用于TLS的客户端证书密钥文件路径. + + --kubelet-https 为kubelet启用https。 (默认值true) + + --kubelet-preferred-address-types stringSlice 用于kubelet连接的首选NodeAddressTypes列表。 (默认值[Hostname,InternalDNS,InternalIP,ExternalDNS,ExternalIP]) + + --kubelet-read-only-port uint 已废弃: kubelet端口. (默认值10255) + + --kubelet-timeout duration kubelet操作超时时间。(默认值 + 5s) + + --kubernetes-service-node-port int 如果不为0,Kubernetes master服务(用于创建/管理apiserver)将会使用NodePort类型,并将这个值作为端口号。如果为0,Kubernetes master服务将会使用ClusterIP类型。 + + --master-service-namespace string 已废弃: 注入到pod中的kubernetes master服务的命名空间。(默认值"default") + + --max-connection-bytes-per-sec int 如果不为0,每个用户连接将会被限速为该值(bytes/sec)。当前只应用于长时间运行的请求。 + + --max-mutating-requests-inflight int 在给定时间内进行中可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值200) + + --max-requests-inflight int 在给定时间内进行中不可变请求的最大数量。当超过该值时,服务将拒绝所有请求。0值表示没有限制。(默认值400) + + --min-request-timeout int 一个可选字段,表示一个handler在一个请求超时前,必须保持它处于打开状态的最小秒数。当前只对监听请求handler有效,它基于这个值选择一个随机数作为连接超时值,以达到分散负载的目的(默认值1800)。 + + --oidc-ca-file string 如果设置该值,将会使用oidc-ca-file中的任意一个authority对OpenID服务的证书进行验证,否则将会使用主机的根CA对其进行验证。 + + --oidc-client-id string 使用OpenID连接的客户端的ID,如果设置了oidc-issuer-url,则必须设置这个值。 + + --oidc-groups-claim string 如果提供该值,这个自定义OpenID连接名将指定给特定的用户组。该声明值需要是一个字符串或字符串数组。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 + + --oidc-issuer-url string OpenID颁发者URL,只接受HTTPS方案。如果设置该值,它将被用于验证OIDC JSON Web Token(JWT)。 + + --oidc-username-claim string 用作用户名的OpenID声明值。注意,不保证除默认 ('sub')外的其他声明值的唯一性和不变性。此标志为实验性的,请查阅验证相关文档进一步了解详细信息。 + + --profiling 在web接口host:port/debug/pprof/上启用profiling。(默认值true) + + --proxy-client-cert-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。它期望这个证书包含一个来自于CA中的--requestheader-client-ca-file标记的签名。该CA在kube-system命名空间的'extension-apiserver-authentication' configmap中发布。从Kube-aggregator收到调用的组件应该使用该CA进行他们部分的双向TLS验证。 + + --proxy-client-key-file string 当必须调用外部程序时,用于证明aggregator或者kube-apiserver的身份的客户端证书密钥。包括代理到用户api-server的请求和调用webhook准入控制插件的请求。 + + --repair-malformed-updates 如果为true,服务将会尽力修复更新请求以通过验证,例如:将更新请求UID的当前值设置为空。在我们修复了所有发送错误格式请求的客户端后,可以关闭这个标志。 + + --requestheader-allowed-names stringSlice 使用--requestheader-username-headers指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过--requestheader-client-ca-file中authorities验证的客户端证书都是被允许的。 + + --requestheader-client-ca-file string 在信任请求头中以--requestheader-username-headers指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑。 + + --requestheader-extra-headers-prefix stringSlice 用于检查的请求头的前缀列表。建议使用X-Remote-Extra-。 + + --requestheader-group-headers stringSlice 用于检查群组的请求头列表。建议使用X-Remote-Group. + + --requestheader-username-headers stringSlice 用于检查用户名的请求头列表。建议使用X-Remote-User。 + + --runtime-config mapStringString 传递给apiserver用于描述运行时配置的键值对集合。 apis/键可以被用来打开/关闭特定的api版本。apis//键被用来打开/关闭特定的资源. api/all和api/legacy键分别用于控制所有的和遗留的api版本. + + --secure-port int 用于监听具有认证授权功能的HTTPS协议的端口。如果为0,则不会监听HTTPS协议。 (默认值6443) + + --service-account-key-file stringArray 包含PEM加密的x509 RSA或ECDSA私钥或公钥的文件,用于验证ServiceAccount令牌。如果设置该值,--tls-private-key-file将会被使用。指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用。 + + --service-cluster-ip-range ipNet CIDR表示的IP范围,服务的cluster ip将从中分配。 一定不要和分配给nodes和pods的IP范围产生重叠。 + + --ssh-keyfile string 如果不为空,在使用安全的SSH代理访问节点时,将这个文件作为用户密钥文件。 + + --storage-backend string 持久化存储后端。 选项为: 'etcd3' (默认), 'etcd2'. + + --storage-media-type string 在存储中保存对象的媒体类型。某些资源或者存储后端可能仅支持特定的媒体类型,并且忽略该配置项。(默认值 "application/vnd.kubernetes.protobuf") + + --storage-versions string 按组划分资源存储的版本。 以"group1/version1,group2/version2,..."的格式指定。当对象从一组移动到另一组时, 你可以指定"group1=group2/v1beta1,group3/v1beta1,..."的格式。你只需要传入你希望从结果中改变的组的列表。默认为从KUBE_API_VERSIONS环境变量集成而来,所有注册组的首选版本列表。 (默认值"admission.k8s.io/v1alpha1,admissionregistration.k8s.io/v1alpha1,apps/v1beta1,authentication.k8s.io/v1,authorization.k8s.io/v1,autoscaling/v1,batch/v1,certificates.k8s.io/v1beta1,componentconfig/v1alpha1,extensions/v1beta1,federation/v1beta1,imagepolicy.k8s.io/v1alpha1,networking.k8s.io/v1,policy/v1beta1,rbac.authorization.k8s.io/v1beta1,settings.k8s.io/v1alpha1,storage.k8s.io/v1,v1") + + --target-ram-mb int apiserver内存限制,单位为MB(用于配置缓存大小等)。 + + --tls-ca-file string 如果设置该值,这个证书authority将会被用于从Admission Controllers过来的安全访问。它必须是一个PEM加密的合法CA捆绑包。此外, 该证书authority可以被添加到以--tls-cert-file提供的证书文件中. + + --tls-cert-file string 包含用于HTTPS的默认x509证书的文件。(如果有CA证书,则附加于server证书之后)。如果启用了HTTPS服务,并且没有提供--tls-cert-file和--tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于/var/run/kubernetes目录。 + + --tls-private-key-file string 包含匹配--tls-cert-file的x509证书私钥的文件。 + + --tls-sni-cert-key namedCertKey 一对x509证书和私钥的文件路径, 可以使用符合正式域名的域形式作为后缀。 如果没有提供域形式后缀, 则将提取证书名。 非通配符版本优先于通配符版本, 显示的域形式优先于证书中提取的名字。 对于多个密钥/证书对, 请多次使用--tls-sni-cert-key。例如: "example.crt,example.key" or "foo.crt,foo.key:*.foo.com,foo.com". (默认值[]) + + --token-auth-file string 如果设置该值,这个文件将被用于通过令牌认证来保护API服务的安全端口。 + + --version version[=true] 打印版本信息并退出。 + + --watch-cache 启用apiserver的监视缓存。(默认值true) + + --watch-cache-sizes stringSlice 每种资源(pods, nodes等)的监视缓存大小列表,以逗号分隔。每个缓存配置的形式为:resource#size,size是一个数字。在watch-cache启用时生效。 +``` + +###### Auto generated by spf13/cobra on 11-Jul-2017 From cec1723e1e312f07991e3e285e0cbd3c4ffbf7e9 Mon Sep 17 00:00:00 2001 From: Li Jingjing Date: Sat, 19 Aug 2017 15:17:14 +0800 Subject: [PATCH 03/32] k8s-hihg-availability-index --- cn/docs/admin/high-availability/index.md | 215 +++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 cn/docs/admin/high-availability/index.md diff --git a/cn/docs/admin/high-availability/index.md b/cn/docs/admin/high-availability/index.md new file mode 100644 index 0000000000..f8d851e236 --- /dev/null +++ b/cn/docs/admin/high-availability/index.md @@ -0,0 +1,215 @@ +--- +title: 构建高可用集群 +--- + + +## 简介 + + +本文描述了如何构建一个高可用(high-availability, HA)的Kubernetes集群。这是一个非常高级的主题。 + +对于仅希望使用Kubernetes进行试验的用户,推荐使用更简单的配置工具进行搭建,例如: +[Minikube](/docs/getting-started-guides/minikube/),或者尝试使用[Google Container Engine](https://cloud.google.com/container-engine/) 来运行Kubernetes。 + +此外,当前在我们的端到端(e2e)测试环境中,没有对Kubernetes高可用的支持进行连续测试。我们将会增加这个连续测试项,但当前对单节点master的安装测试得更加严格。 + +* TOC +{:toc} + +## 概览 + + +搭建一个正真可靠,高度可用的分布式系统需要若干步骤。这类似于穿上内衣,裤子,皮带,背带,另一套内衣和另一套裤子。我们会详细介绍每一个步骤,但先在这里给出一个总结来帮助指导用户。 + + +相关步骤如下: + + * [创建可靠的组成节点,共同形成我们的高可用主节点实现。](#可靠的节点) + * [使用etcd集群,搭建一个冗余的,可靠的存储层。](#建立一个冗余的,可靠的存储层) + * [启动具有备份和负载均衡能力的Kubernetes API 服务](#复制的API服务) + * [搭建运行master选举的Kubernetes scheduler和controller-manager守护程序](#进行master选举的组件) + +系统完成时看起来应该像这样: + +![High availability Kubernetes diagram](/images/docs/ha.svg) + + +## 初始配置 + + +本文假设你正在搭建一个3节点的主节点集群,每个节点上都运行者某种Linux系统。 + +指南中的示例使用Debian发行版,但它们应该可以被轻松移植到其他发行版上。 + +同样的,不管在公有云还是私有云亦或是裸机上,这个配置都应该可以运行。 + + +从一个现成的单主节点集群开始是实现一个高可用Kubernetes集群的最简单的方法。这篇指导 [https://get.k8s.io](https://get.k8s.io) 描述了在多种平台上方便的安装一个单主节点集群的方法。 + +## 可靠的节点 + + +我们在每个主节点上都将运行数个实现Kubernetes API的进程。使他们可靠的第一步是保证在发生故障时,每一个进程都可以自动重启。为了实现这个目标,我们需要安装一个进程监视器。我们选择了在每个工作者节点上都会运行的`kubelet`进程。这会带来便利性,因为我们使用了容器来分发我们的二进制文件,所以我们能够为每一个守护程序建立资源限制并省查它们的资源消耗。当然,我们也需要一些手段来监控kubelete本身(在此监测监控者本身是一个有趣的话题)。对于Debian系统我们选择了monit,但也有许多可替代的工具。例如在基于systemd的系统上(如RHEL, CentOS),你可以运行 'systemctl enable kubelet'。 + + +如果你是从标准的Kubernetes安装扩展而来,那么`kubelet`二进制文件应该已经存在于你的系统中。你可以运行`which kubelet`来判断是否确实安装了这个二进制文件。如果没有安装的话,你应该手动安装 [kubelet binary](https://storage.googleapis.com/kubernetes-release/release/v0.19.3/bin/linux/amd64/kubelet), +[kubelet init file](http://releases.k8s.io/{{page.githubbranch}}/cluster/saltbase/salt/kubelet/initd) 和 [default-kubelet](/docs/admin/high-availability/default-kubelet)脚本。 + +如果使用monit,你还需要安装monit守护程序(`apt-get install monit`)以及[monit-kubelet](/docs/admin/high-availability/monit-kubelet) 和 +[monit-docker](/docs/admin/high-availability/monit-docker) 配置。 + +在使用systemd的系统上,你可以执行 `systemctl enable kubelet` 和 `systemctl enable docker`。 + + +## 建立一个冗余的,可靠的存储层 + + +高可用方案的中心基础是一个冗余的,可靠的存储层。高可用的头条规则是保护数据。不管发生了什么,不管什么着了火,只要还有数据,你就可以重建。如果丢掉了数据,你就完了。 + + +集群化的etcd已经把你存储的数据复制到了你集群中的所有主节点实例上。这意味着如果要想丢失数据,三个节点的物理(或虚拟)硬盘需要全部同时故障。这种情况发生的概率是比较低的,所以对于许多人来说,运行一个复制的etcd集群可能已经足够的可靠了。你可以将集群数量从3个增大到5个来增加集群的可靠性。如果那样还不够,你可以添加[更多的可靠性到你的存储层](#更加可靠的存储)。 + + +### 集群化etcd + + +集群化etcd的完整细节超出了本文范围,你可以在[etcd clustering page](https://github.com/coreos/etcd/blob/master/Documentation/op-guide/clustering.md)找到许多详细内容。这个例子仅走查一个简单的集群建立过程,使用etcd内置的发现功能来构建我们的集群。 + + +首先,调用etcd发现服务来创建一个新令牌: + +```shell +curl https://discovery.etcd.io/new?size=3 +``` + + +在每个节点上,拷贝 [etcd.yaml](/docs/admin/high-availability/etcd.yaml) 文件到`/etc/kubernetes/manifests/etcd.yaml`。 + + +每个节点上的kubelet会动态的监控这个文件夹的内容,并且会按照`etcd.yaml`里对pod的定义创建一个`etcd`服务的实例。 + + +请注意,你应该使用上文中获取的令牌URL替换全部三个节点上`etcd.yaml`中的`${DISCOVERY_TOKEN}`项。同时还应该将每个节点上的 `${NODE_NAME}`替换为一个不同的名字(例如:`node-1`),并将 `${NODE_IP}`替换为正确的IP地址。 + + +#### 验证你的集群 + + +如果已经将这个文件拷贝到所有三个节点,你应该已经搭建起了一个集群化的etcd。你可以在主节点上进行验证: +```shell +kubectl exec < pod_name > etcdctl member list +``` + +和 + +```shell +kubectl exec < pod_name > etcdctl cluster-health +``` + + +你也可以在一个节点上运行 `etcdctl set foo bar`,在另一个节点上运行`etcdctl get foo`来验证集群是否工作正常。 + + +### 更加可靠的存储 + + +当然,如果你对增加数据的可靠性感兴趣,这里还有一些更深入的选项可以使etcd把它的数据存放在比常规硬盘更可靠的地方(裤带和背带,ftw!)。 + + +如果你使用云服务,那么你的提供商通常会为你提供这个特性,例如Google Cloud Platform上的 [Persistent Disk](https://cloud.google.com/compute/docs/disks/persistent-disks) 。它们是可以挂载到你的虚拟机中的块设备持久化存储。其他的云服务提供商提供了类似的解决方案。 + + +如果运行于物理机之上,你仍然可以使用iSCSI或者NFS接口通过网络来连接冗余存储。 +此外,你还可以运行一个集群文件系统,比如Gluster或者Ceph。最后,你还可以在你的每个物理机器上运行RAID矩阵。 + + +不管你选择如何实现,如果已经选择了使用其中的一个选项,那么你应该保证你的存储被挂载到了每一台机器上。如果你的存储在集群中的三个主节点之间共享,那么你应该在存储上为每一个节点创建一个不同的文件夹。对于所有的这些指导,我们都假设这个存储被挂载到你机器上的`/var/etcd/data`路径。 + + +## 复制的API服务 + + +在正确搭建复制的etcd之后,我们还需要使用kubelet安装apiserver。 + + + + +首先,你需要创建初始的日志文件,这样Docker才会挂载一个文件而不是一个文件夹: +```shell +touch /var/log/kube-apiserver.log +``` + +接下来,你需要在每个节点上创建一个`/srv/kubernetes/`文件夹。这个文件夹包含: + + * basic_auth.csv - 基本认证的用户名和密码 + * ca.crt - CA证书 + * known_tokens.csv - 实体(例如kubelet)用来和apiserver通信的令牌 + * kubecfg.crt - 客户端证书,公钥 + * kubecfg.key - 客户端证书,私钥 + * server.cert - 服务端证书,公钥 + * server.key - 服务端证书,私钥 + + +创建这个文件夹最简单的方法可以是从一个工作正常的集群的主节点拷贝,或者你也可以手动生成它们。 + + +### 启动API服务 + + +一旦这些文件已经存在了,拷贝 [kube-apiserver.yaml](/docs/admin/high-availability/kube-apiserver.yaml) 到每个主节点的 `/etc/kubernetes/manifests/`文件夹。 + + +kubelet会监控这个文件夹,并且会按照文件里对pod的定义创建一个`kube-apiserver`容器。 + + +### 负载均衡 + + +现在,你应该有3个全部正常工作的apiserver了。如果搭建了网络负载均衡器,你应该能够通过那个负载均衡器访问你的集群,并且看到负载在apiserver实例间分发。设置负载均衡器依赖于你的平台的实际情况,例如对于Google Cloud Platform的指导可以在[这里](https://cloud.google.com/compute/docs/load-balancing/)找到。 + + +请注意,如果使用了身份认证,你可能需要重新生成你的证书,除每个节点的IP地址外额外包含负载均衡器的IP地址。 + + +对于部署在集群中的pods, `kubernetes`服务/dns名称应该自动的为主节点提供了负载均衡的endpoint。 + + +对于使用API的外部用户(如命令行运行的`kubectl`,持续集成管道或其他客户端)你会希望将他们配置成为访问外部负载均衡器的地址。 + + +## 进行Master选举的组件 + + +到目前为止,我们已经搭建了状态存储,也搭建好了API服务,但我们还没有运行任何真正改变集群状态的服务,比如controller manager和scheduler。为了可靠的实现这个目标,我们希望在同一时间只有一个参与者在修改集群状态。但是我们希望复制这些参与者的实例以防某个机器宕机。要做到这一点,我们打算在API中使用一个lease-lock来执行master选举。我们会对每一个scheduler和controller-manager使用`--leader-elect`标志,从而在API中使用一个租约来保证同一时间只有一个scheduler和controller-manager的实例正在运行。 + + +scheduler和controller-manager可以配置为只和位于它们相同节点(即127.0.0.1)上的API服务通信,也可以配置为使用API服务的负载均衡器的IP地址。不管它们如何配置,当使用`--leader-elect` 时scheduler和controller-manager都将完成上文提到的leader选举过程。 + + +为了防止访问API服务失败,选举出的leader不能通过更新租约来选举一个新的leader。当scheduler和controller-manager通过127.0.0.1访问API服务,而相同节点上的API服务不可用时,这一点相当重要。 + + +### 安装配置文件 + + +首先,在每个节点上创建空白日志文件,这样Docker就会挂载这些文件而不是创建一个新文件夹: + +```shell +touch /var/log/kube-scheduler.log +touch /var/log/kube-controller-manager.log +``` + + +接下来,在每个节点上配置scheduler和controller manager pods的描述文件。拷贝 [kube-scheduler.yaml](/docs/admin/high-availability/kube-scheduler.yaml) 和 [kube-controller-manager.yaml](/docs/admin/high-availability/kube-controller-manager.yaml) 到`/etc/kubernetes/manifests/` 文件夹。 + + +## 结尾 + + +此时,你已经完成了master组件的配置(耶!),但你还需要添加工作者节点(噗!)。 + + +如果你有一个现成的集群,你只需要在每个节点上简单的重新配置你的kubeletes连接到负载均衡的endpoint并重启它们。 + + +如果你搭建的是一个全新的集群,你将需要在每个工作节点上安装kubelet和kube-proxy,并设置 `--apiserver`指向复制的endpoint。 \ No newline at end of file From 070143a1c9b593ca2a6fbfcf835f86579dd0e6ba Mon Sep 17 00:00:00 2001 From: Li Jingjing Date: Sat, 19 Aug 2017 15:33:01 +0800 Subject: [PATCH 04/32] k8s-tutorials-services-source-ip --- cn/docs/tutorials/services/source-ip.md | 330 ++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 cn/docs/tutorials/services/source-ip.md diff --git a/cn/docs/tutorials/services/source-ip.md b/cn/docs/tutorials/services/source-ip.md new file mode 100644 index 0000000000..02bb213816 --- /dev/null +++ b/cn/docs/tutorials/services/source-ip.md @@ -0,0 +1,330 @@ +--- + +title: 使用 Source IP +--- + +{% capture overview %} + + +Kubernetes 集群中运行的应用通过抽象的 Service 查找彼此,相互通信和连接外部世界。本文揭示了发送到不同类型 Services 的数据包源 IP 的内幕,你可以根据需求改变这个行为。 + +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + + +## 术语表 + + +本文使用了下列术语: + +* [NAT](https://en.wikipedia.org/wiki/Network_address_translation): 网络地址转换 +* [Source NAT](https://en.wikipedia.org/wiki/Network_address_translation#SNAT): 替换数据包的源 IP, 通常为节点的 IP +* [Destination NAT](https://en.wikipedia.org/wiki/Network_address_translation#DNAT): 替换数据包的目的 IP, 通常为 Pod 的 IP +* [VIP](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies): 一个虚拟 IP, 例如分配给每个 Kubernetes Service 的 IP +* [Kube-proxy](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies): 一个网络守护程序,在每个节点上协调 Service VIP 管理 + + +## 准备工作 + + +你必须拥有一个正常工作的 Kubernetes 1.5 集群,用来运行本文中的示例。该示例使用一个简单的 nginx webserver 回送它接收到的请求的 HTTP 头中的源 IP 地址。你可以像下面这样创建它: + +```console +$ kubectl run source-ip-app --image=gcr.io/google_containers/echoserver:1.4 +deployment "source-ip-app" created +``` + +{% endcapture %} + +{% capture objectives %} + + +* 通过多种类型的 Services 暴露一个简单应用 +* 理解每种 Service 类型如何处理源 IP NAT +* 理解保留源 IP 的折中 + +{% endcapture %} + + +{% capture lessoncontent %} + + +## Type=ClusterIP 类型 Services 的 Source IP + + +如果你的 kube-proxy 运行在 [iptables 模式](/docs/user-guide/services/#proxy-mode-iptables)下,从集群内部发送到 ClusterIP 的包永远不会进行源地址 NAT,这从 Kubernetes 1.2 开始是默认选项。Kube-proxy 通过一个 `proxyMode` endpoint 暴露它的模式。 + +```console +$ kubectl get nodes +NAME STATUS AGE VERSION +kubernetes-minion-group-6jst Ready 2h v1.6.0+fff5156 +kubernetes-minion-group-cx31 Ready 2h v1.6.0+fff5156 +kubernetes-minion-group-jj1t Ready 2h v1.6.0+fff5156 + +kubernetes-minion-group-6jst $ curl localhost:10249/proxyMode +iptables +``` + + +你可以通过在 source IP 应用上创建一个服务来测试源 IP 保留。 + +```console +$ kubectl expose deployment source-ip-app --name=clusterip --port=80 --target-port=8080 +service "clusterip" exposed + +$ kubectl get svc clusterip +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +clusterip 10.0.170.92 80/TCP 51s +``` + + +从相同集群中的一个 pod 访问这个 `ClusterIP`: + +```console +$ kubectl run busybox -it --image=busybox --restart=Never --rm +Waiting for pod default/busybox to be running, status is Pending, pod ready: false +If you don't see a command prompt, try pressing enter. + +# ip addr +1: lo: mtu 65536 qdisc noqueue + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 + inet 127.0.0.1/8 scope host lo + valid_lft forever preferred_lft forever + inet6 ::1/128 scope host + valid_lft forever preferred_lft forever +3: eth0: mtu 1460 qdisc noqueue + link/ether 0a:58:0a:f4:03:08 brd ff:ff:ff:ff:ff:ff + inet 10.244.3.8/24 scope global eth0 + valid_lft forever preferred_lft forever + inet6 fe80::188a:84ff:feb0:26a5/64 scope link + valid_lft forever preferred_lft forever + +# wget -qO - 10.0.170.92 +CLIENT VALUES: +client_address=10.244.3.8 +command=GET +... +``` + +如果客户端 pod 和 服务端 pod 在相同的节点上,client_address 就是客户端 pod 的 IP 地址。但是,如果它们在不同的节点上, client_address 将会是客户端 pod 所在节点的 flannel IP 地址。 + + +## Type=NodePort 类型 Services 的 Source IP + + +对于 Kubernetes 1.5,发送给类型为 [Type=NodePort](/docs/user-guide/services/#type-nodeport) Services 的数据包默认进行源地址 NAT。你可以创建一个 `NodePort` Service 来进行测试: + +```console +$ kubectl expose deployment source-ip-app --name=nodeport --port=80 --target-port=8080 --type=NodePort +service "nodeport" exposed + +$ NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services nodeport) +$ NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="ExternalIP")].address }') +``` + +如果你的集群运行在一个云服务上,你可能需要为上面报告的 `nodes:nodeport` 开启一条防火墙规则。 +现在,你可以通过上面分配的节点端口从外部访问这个 Service。 + +```console +$ for node in $NODES; do curl -s $node:$NODEPORT | grep -i client_address; done +client_address=10.180.1.1 +client_address=10.240.0.5 +client_address=10.240.0.3 +``` + +请注意,这些并不是正确的客户端 IP,它们是集群的内部 IP。这是所发生的事情: + +* 客户端发送数据包到 `node2:nodePort` +* `node2` 使用它自己的 IP 地址替换数据包的源 IP 地址(SNAT) +* `node2` 使用 pod IP 地址替换数据包的目的 IP 地址 +* 数据包被路由到 node 1,然后交给 endpoint +* Pod 的回复被路由回 node2 +* Pod 的回复被发送回给客户端 + + +形象的: + +``` + client + \ ^ + \ \ + v \ + node 1 <--- node 2 + | ^ SNAT + | | ---> + v | + endpoint +``` + + +为了防止这种情况发生,Kubernetes 提供了一个特性来保留客户端的源 IP 地址[(点击此处查看可用特性)](/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip)。设置 `service.spec.externalTrafficPolicy` 的值为 `Local`,请求就只会被代理到本地 endpoints 而不会被转发到其它节点。这样就保留了最初的源 IP 地址。如果没有本地 endpoints,发送到这个节点的数据包将会被丢弃。这样在应用到数据包的任何包处理规则下,你都能依赖这个正确的 source-ip 使数据包通过并到达 endpoint。 + + +设置 `service.spec.externalTrafficPolicy` 字段如下: + +```console +$ kubectl patch svc nodeport -p '{"spec":{"externalTrafficPolicy":"Local"}}' +service "nodeport" patched +``` + + +现在,重新运行测试: + +```console +$ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done +client_address=104.132.1.79 +``` + + +请注意,你只从 endpoint pod 运行的那个节点得到了一个回复,这个回复有*正确的*客户端 IP。 + + +这是发生的事情: + +* 客户端发送数据包到 `node2:nodePort`,它没有任何 endpoints +* 数据包被丢弃 +* 客户端发送数据包到 `node1:nodePort`,它*有*endpoints +* node1 使用正确的源 IP 地址将数据包路由到 endpoint + + +形象的: + +``` + client + ^ / \ + / / \ + / v X + node 1 node 2 + ^ | + | | + | v + endpoint +``` + + + +## Type=LoadBalancer 类型 Services 的 Source IP + + +对于 Kubernetes 1.5,发送给类型为 [Type=LoadBalancer](/docs/user-guide/services/#type-nodeport) Services 的数据包默认进行源地址 NAT,这是由于所有处于 `Ready` 状态的 Kubernetes 节点对于负载均衡的流量都是符合条件的。所以如果数据包到达一个没有 endpoint 的节点,系统将把这个包代理到*有* endpoint 的节点,并替换数据包的源 IP 为节点的 IP(如前面章节所述)。 + + +你可以通过在一个 loadbalancer 上暴露这个 source-ip-app 来进行测试。 + +```console +$ kubectl expose deployment source-ip-app --name=loadbalancer --port=80 --target-port=8080 --type=LoadBalancer +service "loadbalancer" exposed + +$ kubectl get svc loadbalancer +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +loadbalancer 10.0.65.118 104.198.149.140 80/TCP 5m + +$ curl 104.198.149.140 +CLIENT VALUES: +client_address=10.240.0.5 +... +``` + + +然而,如果你的集群运行在 GKE/GCE 上,设置 `service.spec.externalTrafficPolicy` 字段值为 `Local` 可以强制使*没有* endpoints 的节点把他们自己从负载均衡流量的可选节点名单中删除。这是通过故意使它们健康检查失败达到的。 + + +形象的: + +``` + client + | + lb VIP + / ^ + v / +health check ---> node 1 node 2 <--- health check + 200 <--- ^ | ---> 500 + | V + endpoint +``` + + +你可以设置 annotation 来进行测试: + +```console +$ kubectl patch svc loadbalancer -p '{"spec":{"externalTrafficPolicy":"Local"}}' +``` + + +你应该能够立即看到 Kubernetes 分配的 `service.spec.healthCheckNodePort` 字段: + +```console +$ kubectl get svc loadbalancer -o yaml | grep -i healthCheckNodePort + healthCheckNodePort: 32122 +``` + + +`service.spec.healthCheckNodePort` 字段指向每个节点在 `/healthz` 路径上提供的用于健康检查的端口。你可以这样测试: + +``` +$ kubectl get pod -o wide -l run=source-ip-app +NAME READY STATUS RESTARTS AGE IP NODE +source-ip-app-826191075-qehz4 1/1 Running 0 20h 10.180.1.136 kubernetes-minion-group-6jst + +kubernetes-minion-group-6jst $ curl localhost:32122/healthz +1 Service Endpoints found + +kubernetes-minion-group-jj1t $ curl localhost:32122/healthz +No Service Endpoints Found +``` + + +主节点运行的 service 控制器负责分配 cloud loadbalancer。在这样做的同时,它也会分配指向每个节点的 HTTP 健康检查的 port/path。等待大约 10 秒钟之后,没有 endpoints 的两个节点的健康检查会失败,然后 curl 负载均衡器的 ip: + +```console +$ curl 104.198.149.140 +CLIENT VALUES: +client_address=104.132.1.79 +... +``` + + +__跨平台支持__ + + +由于 Kubernetes 1.5 在类型为 Type=LoadBalancer 的 Services 中支持源 IP 保存的特性仅在 cloudproviders 的子集中实现(GCP and Azure)。你的集群运行的 cloudprovider 可能以某些不同的方式满足 loadbalancer 的要求: + + +1. 使用一个代理终止客户端连接并打开一个到你的 nodes/endpoints 的新连接。在这种情况下,源 IP 地址将永远是云负载均衡器的地址而不是客户端的。 + +2. 使用一个包转发器,因此从客户端发送到负载均衡器 VIP 的请求在拥有客户端源 IP 地址的节点终止,而不被中间代理。 + + +第一类负载均衡器必须使用一种它和后端之间约定的协议来和真实的客户端 IP 通信,例如 HTTP [X-FORWARDED-FOR](https://en.wikipedia.org/wiki/X-Forwarded-For) 头,或者 [proxy 协议](http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt)。 +第二类负载均衡器可以通过简单的在保存于 Service 的 `service.spec.healthCheckNodePort` 字段上创建一个 HTTP 健康检查点来使用上面描述的特性。 + +{% endcapture %} + +{% capture cleanup %} + + +删除服务: + +```console +$ kubectl delete svc -l run=source-ip-app +``` + + +删除 Deployment、ReplicaSet 和 Pod: + +```console +$ kubectl delete deployment source-ip-app +``` + +{% endcapture %} + +{% capture whatsnext %} + +* 学习更多关于 [通过 services 连接应用](/docs/concepts/services-networking/connect-applications-service/) +* 学习更多关于 [负载均衡](/docs/user-guide/load-balancer) +{% endcapture %} + +{% include templates/tutorial.md %} From 8a46359353e3989a327082cc482bf4bd7df0a042 Mon Sep 17 00:00:00 2001 From: huzhifeng Date: Wed, 23 Aug 2017 08:49:39 +0800 Subject: [PATCH 05/32] Fix document style Signed-off-by: huzhifeng --- .../independent/create-cluster-kubeadm.md | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/setup/independent/create-cluster-kubeadm.md b/docs/setup/independent/create-cluster-kubeadm.md index 5e7a3d0189..34aa3bedb3 100644 --- a/docs/setup/independent/create-cluster-kubeadm.md +++ b/docs/setup/independent/create-cluster-kubeadm.md @@ -560,22 +560,30 @@ Another workaround is to overwrite the default `kubeconfig` for the "admin" user 1. If you are using CentOS and encounter difficulty while setting up the master node, verify that your Docker cgroup driver matches the kubelet config: -``` +```bash docker info |grep -i cgroup cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ``` - If the Docker cgroup driver and the kubelet config don't match, change the kubelet config to match the Docker cgroup driver: +If the Docker cgroup driver and the kubelet config don't match, change the kubelet config to match the Docker cgroup driver. -``` -update KUBELET_CGROUP_ARGS=--cgroup-driver=systemd to KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs +Update + +```bash +KUBELET_CGROUP_ARGS=--cgroup-driver=systemd ``` - Then restart kubelet: +To +```bash +KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs ``` + +Then restart kubelet: + +```bash systemctl daemon-reload -service kubelet restart +systemctl restart kubelet ``` The `kubectl describe pod` or `kubectl logs` commands can help you diagnose errors. For example: From a492cee70d3f53ba7960e59e8a6b1eb4ef7ddb70 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 25 Aug 2017 14:43:29 +0800 Subject: [PATCH 06/32] Update bootstrap-tokens.md modify "discription" to "description" --- docs/admin/bootstrap-tokens.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/admin/bootstrap-tokens.md b/docs/admin/bootstrap-tokens.md index a2004e6c9e..d1f13a5585 100644 --- a/docs/admin/bootstrap-tokens.md +++ b/docs/admin/bootstrap-tokens.md @@ -82,7 +82,7 @@ data: The type of the secret must be `bootstrap.kubernetes.io/token` and the name must be `bootstrap-token-`. It must also exist in the `kube-system` -namespace. `description` is a human readable discription that should not be +namespace. `description` is a human readable description that should not be used for machine readable information. The Token ID and Secret are included in the data dictionary. From 07931517e3079c47c8e55bf76fb584ff818f4b7b Mon Sep 17 00:00:00 2001 From: Rob Young Date: Fri, 25 Aug 2017 12:33:14 +0100 Subject: [PATCH 07/32] Update json gem and use bundler - json 1.8.3 was failing to install on Mac. Upgrading has fixed this. - Call jekyll through bundler so that Gemfile versions --- Gemfile.lock | 4 ++-- Makefile | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1ae07067d8..09d52b8d72 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -155,7 +155,7 @@ GEM gemoji (~> 2.0) html-pipeline (~> 2.2) jekyll (>= 3.0) - json (1.8.3) + json (1.8.6) kramdown (1.11.1) liquid (3.0.6) listen (3.0.6) @@ -200,4 +200,4 @@ DEPENDENCIES jekyll-include-cache (~> 0.1) BUNDLED WITH - 1.13.6 + 1.15.2 diff --git a/Makefile b/Makefile index a957010a0d..999feab316 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,13 @@ help: ## Show this help. all: build ## Build site with production settings and put deliverables in _site. build: ## Build site with production settings and put deliverables in _site. - jekyll build + bundle exec jekyll build build-preview: ## Build site with drafts and future posts enabled. - jekyll build --drafts --future + bundle exec jekyll build --drafts --future serve: ## Boot the development server. - jekyll serve + bundle exec jekyll serve stage: ## Run the Jekyll staging container. docker run -ti --rm -v "${PWD}":/k8sdocs -p 4000:4000 gcr.io/google-samples/k8sdocs:1.1 From 5b79d36e59a3506e35e220dd378ba4c965e8665d Mon Sep 17 00:00:00 2001 From: Anton Drukh Date: Fri, 25 Aug 2017 21:46:50 +0300 Subject: [PATCH 08/32] docs: fixing a typo --- docs/tasks/administer-cluster/cpu-default-namespace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/administer-cluster/cpu-default-namespace.md b/docs/tasks/administer-cluster/cpu-default-namespace.md index eab8e81b6e..d446b436b5 100644 --- a/docs/tasks/administer-cluster/cpu-default-namespace.md +++ b/docs/tasks/administer-cluster/cpu-default-namespace.md @@ -123,7 +123,7 @@ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/cpu-defaults-pod- ``` The output shows that the Container's CPU request is set to the value specified in the -Container's configuration file. The Container's CPU limit is set to 1 cpu, wh70cb02113b7c7cc1604d1951ef82e1c82850eef2ich is the +Container's configuration file. The Container's CPU limit is set to 1 cpu, which is the default CPU limit for the namespace. ``` From 78c2801d1b8fbc31ed22a2f583dd0f8e4f971a44 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Wed, 9 Aug 2017 13:16:03 -0700 Subject: [PATCH 09/32] docs/admin: encourage out-of-tree auth-N/Z integrations Remove the custom modules description in the authorization and authentication docs. While we could add more later, we probably don't want to advertise them to end users. Also note that the authentication webhook and authenticating proxy can be used to integrate with unsupported auth protocols. --- docs/admin/authentication.md | 12 ++++-------- docs/admin/authorization/index.md | 21 --------------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/docs/admin/authentication.md b/docs/admin/authentication.md index 324330cf39..220f418c43 100644 --- a/docs/admin/authentication.md +++ b/docs/admin/authentication.md @@ -60,6 +60,10 @@ The API server does not guarantee the order authenticators run in. The `system:authenticated` group is included in the list of groups for all authenticated users. +Integrations with other authentication protocols (LDAP, SAML, Kerberos, alternate x509 schemes, etc) +can be accomplished using an [authenticating proxy](#authenticating-proxy) or the +[authentication webhook](#webhook-token-authentication). + ### X509 Client Certs Client certificate authentication is enabled by passing the `--client-ca-file=SOMEFILE` @@ -685,14 +689,6 @@ rules: resourceNames: ["view", "development"] ``` -## Plugin Development - -We plan for the Kubernetes API server to issue tokens after the user has been -(re)authenticated by a *bedrock* authentication provider external to Kubernetes. -We also plan to make it easy to develop modules that interface between -Kubernetes and a bedrock authentication provider (e.g. github.com, google.com, -enterprise directory, kerberos, etc.) - ## APPENDIX ### Creating Certificates diff --git a/docs/admin/authorization/index.md b/docs/admin/authorization/index.md index 61ad340eb4..c1d456f626 100644 --- a/docs/admin/authorization/index.md +++ b/docs/admin/authorization/index.md @@ -65,27 +65,6 @@ of the `bind` verb on `roles` and `clusterroles` resources in the `rbac.authoriz ..* As of 1.6 RBAC mode is in beta. ..* To enable RBAC, start the apiserver with `--authorization-mode=RBAC`. * **Webhook** - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen. To learn more about using the Webhook mode, see [Webhook Mode](/docs/admin/authorization/webhook/). - * **Custom Modules** - You can create custom modules for using with Kubernetes. To learn more, see **Custom Modules** below. - -### Custom Modules -Other implementations can be developed fairly easily. The APIserver calls the Authorizer interface: - -```go -type Authorizer interface { - Authorize(a Attributes) error -} -``` - -to determine whether or not to allow each API action. - -An authorization plugin is a module that implements this interface. -Authorization plugin code goes in `pkg/auth/authorizer/$MODULENAME`. - -An authorization module can be completely implemented in go, or can call out -to a remote authorization service. Authorization modules can implement -their own caching to reduce the cost of repeated authorization calls with the -same or similar arguments. Developers should then consider the interaction -between caching and revocation of permissions. #### Checking API Access From 4416d79eb9228395784ee0e5c6ddffe52fdfd0da Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Sat, 26 Aug 2017 15:33:34 +0800 Subject: [PATCH 10/32] fix the command output fix the command output --- ...un-single-instance-stateful-application.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/tasks/run-application/run-single-instance-stateful-application.md b/docs/tasks/run-application/run-single-instance-stateful-application.md index 17bb7c594f..ca0bb66775 100644 --- a/docs/tasks/run-application/run-single-instance-stateful-application.md +++ b/docs/tasks/run-application/run-single-instance-stateful-application.md @@ -95,10 +95,31 @@ for a secure solution. Namespace: default CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700 Labels: app=mysql + Annotations: deployment.kubernetes.io/revision=1 Selector: app=mysql - Replicas: 1 updated | 1 total | 0 available | 1 unavailable + Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable StrategyType: Recreate MinReadySeconds: 0 + Pod Template: + Labels: app=mysql + Containers: + mysql: + Image: mysql:5.6 + Port: 3306/TCP + Environment: + MYSQL_ROOT_PASSWORD: password + Mounts: + /var/lib/mysql from mysql-persistent-storage (rw) + Volumes: + mysql-persistent-storage: + Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) + ClaimName: mysql-pv-claim + ReadOnly: false + Conditions: + Type Status Reason + ---- ------ ------ + Available False MinimumReplicasUnavailable + Progressing True ReplicaSetUpdated OldReplicaSets: NewReplicaSet: mysql-63082529 (1/1 replicas created) Events: From a6abd035eca8615560f2c793a9b80167cea0f87f Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 27 Aug 2017 09:38:40 +0800 Subject: [PATCH 11/32] Update fedora_manual_config.md Fix signal. --- docs/getting-started-guides/fedora/fedora_manual_config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/fedora/fedora_manual_config.md b/docs/getting-started-guides/fedora/fedora_manual_config.md index dd6a301fd9..6f32409623 100644 --- a/docs/getting-started-guides/fedora/fedora_manual_config.md +++ b/docs/getting-started-guides/fedora/fedora_manual_config.md @@ -85,7 +85,7 @@ KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" KUBE_API_ARGS="" ``` -* Edit /etc/etcd/etcd.conf to let etcd listen on all available IPs instead of 127.0.0.1; If you have not done this, you might see an error such as "connection refused". +* Edit /etc/etcd/etcd.conf to let etcd listen on all available IPs instead of 127.0.0.1. If you have not done this, you might see an error such as "connection refused". ```shell ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" From 7e7170cecbf2bdb6b8172dc556c5c9db3fa9f7c3 Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 27 Aug 2017 18:25:45 +0800 Subject: [PATCH 12/32] Update namespaces.md Missing signal. --- docs/concepts/overview/working-with-objects/namespaces.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/overview/working-with-objects/namespaces.md b/docs/concepts/overview/working-with-objects/namespaces.md index 0f66878964..aa06eff515 100644 --- a/docs/concepts/overview/working-with-objects/namespaces.md +++ b/docs/concepts/overview/working-with-objects/namespaces.md @@ -30,7 +30,7 @@ resources within the same namespace. ## Working with Namespaces Creation and deletion of namespaces is described in the [Admin Guide documentation -for namespaces](/docs/admin/namespaces) +for namespaces](/docs/admin/namespaces). ### Viewing namespaces @@ -74,7 +74,7 @@ $ kubectl config view | grep namespace: When you create a [Service](/docs/user-guide/services), it creates a corresponding [DNS entry](/docs/admin/dns). This entry is of the form `..svc.cluster.local`, which means -that if a container just uses `` it will resolve to the service which +that if a container just uses ``, it will resolve to the service which is local to a namespace. This is useful for using the same configuration across multiple namespaces such as Development, Staging and Production. If you want to reach across namespaces, you need to use the fully qualified domain name (FQDN). From 9071a63b85bdee5053f75710bfadb29d2330fb6e Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 27 Aug 2017 18:27:48 +0800 Subject: [PATCH 13/32] Update configure-aggregation-layer.md Missing a signal. --- docs/tasks/access-kubernetes-api/configure-aggregation-layer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md b/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md index ab069fa30a..0265ad1371 100644 --- a/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md +++ b/docs/tasks/access-kubernetes-api/configure-aggregation-layer.md @@ -34,7 +34,7 @@ Enable the aggregation layer via the following kube-apiserver flags. They may ha --proxy-client-cert-file= --proxy-client-key-file= -If you are not running kube-proxy on a host running the API server then you must make sure that the system is enabled with the following apiserver flag: +If you are not running kube-proxy on a host running the API server, then you must make sure that the system is enabled with the following apiserver flag: --enable-aggregator-routing=true From 9f901b1cf83b42aeec1c4118b7c7c2395eb56077 Mon Sep 17 00:00:00 2001 From: Stewart-YU Date: Sun, 27 Aug 2017 18:36:40 +0800 Subject: [PATCH 14/32] Update daemonset.md Missing a signal. --- docs/concepts/workloads/controllers/daemonset.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/workloads/controllers/daemonset.md b/docs/concepts/workloads/controllers/daemonset.md index 694a0d1637..26bc660eef 100644 --- a/docs/concepts/workloads/controllers/daemonset.md +++ b/docs/concepts/workloads/controllers/daemonset.md @@ -64,7 +64,7 @@ a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) or other new re The `spec.selector` is an object consisting of two fields: -* `matchLabels` - works the same as the `.spec.selector` of a [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/) +* `matchLabels` - works the same as the `.spec.selector` of a [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/). * `matchExpressions` - allows to build more sophisticated selectors by specifying key, list of values and an operator that relates the key and values. @@ -83,7 +83,7 @@ a node for testing. If you specify a `.spec.template.spec.nodeSelector`, then the DaemonSet controller will create pods on nodes which match that [node -selector](/docs/concepts/configuration/assign-pod-node/). Likewise if you specify a `.spec.template.spec.affinity` +selector](/docs/concepts/configuration/assign-pod-node/). Likewise if you specify a `.spec.template.spec.affinity`, then DaemonSet controller will create pods on nodes which match that [node affinity](/docs/concepts/configuration/assign-pod-node/). If you do not specify either, then the DaemonSet controller will create pods on all nodes. From beb35916629364524246f4ea59eb43638dc4cfc2 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Sun, 27 Aug 2017 10:10:20 -0700 Subject: [PATCH 15/32] Update pod names to match what's in the spec. --- docs/tasks/administer-cluster/memory-default-namespace.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tasks/administer-cluster/memory-default-namespace.md b/docs/tasks/administer-cluster/memory-default-namespace.md index 951f015380..d2d7bf0d5a 100644 --- a/docs/tasks/administer-cluster/memory-default-namespace.md +++ b/docs/tasks/administer-cluster/memory-default-namespace.md @@ -103,7 +103,7 @@ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-defaults-p View detailed information about the Pod: ```shell -kubectl get pod mem-limit-no-request --output=yaml --namespace=default-mem-example +kubectl get pod default-mem-demo-2 --output=yaml --namespace=default-mem-example ``` The output shows that the Container's memory request is set to match its memory limit. @@ -133,7 +133,7 @@ kubectl create -f https://k8s.io/docs/tasks/administer-cluster/memory-defaults-p View the Pod's specification: ```shell -kubectl get pod default-mem-request-no-limit --output=yaml --namespace=default-mem-example +kubectl get pod default-mem-demo-3 --output=yaml --namespace=default-mem-example ``` The output shows that the Container's memory request is set to the value specified in the From 681fd11bacc899b91ce54f7f657328361660e790 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Sun, 27 Aug 2017 15:44:59 -0700 Subject: [PATCH 16/32] Remove broken link. --- docs/setup/pick-right-solution.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/setup/pick-right-solution.md b/docs/setup/pick-right-solution.md index 23861da7b0..dd3174746b 100644 --- a/docs/setup/pick-right-solution.md +++ b/docs/setup/pick-right-solution.md @@ -43,8 +43,6 @@ a Kubernetes cluster from scratch. * [AppsCode.com](https://appscode.com/products/cloud-deployment/) provides managed Kubernetes clusters for various public clouds, including AWS and Google Cloud Platform. -* [KCluster.io](https://kcluster.io) provides highly available and scalable managed Kubernetes clusters for AWS. - * [KUBE2GO.io](https://kube2go.io) get started with highly available Kubernetes clusters on multiple public clouds along with useful tools for development, debugging, monitoring. * [Madcore.Ai](https://madcore.ai) is devops-focused CLI tool for deploying Kubernetes infrastructure in AWS. Master, auto-scaling group nodes with spot-instances, ingress-ssl-lego, Heapster, and Grafana. @@ -144,7 +142,6 @@ any | any | multi-support | any CNI | [docs](/docs/set GKE | | | GCE | [docs](https://cloud.google.com/container-engine) | Commercial Stackpoint.io | | multi-support | multi-support | [docs](https://stackpoint.io/) | Commercial AppsCode.com | Saltstack | Debian | multi-support | [docs](https://appscode.com/products/cloud-deployment/) | Commercial -KCluster.io | | multi-support | multi-support | [docs](https://kcluster.io) | Commercial KUBE2GO.io | | multi-support | multi-support | [docs](https://kube2go.io) | Commercial Madcore.Ai | Jenkins DSL | Ubuntu | flannel | [docs](https://madcore.ai) | Community ([@madcore-ai](https://github.com/madcore-ai)) Platform9 | | multi-support | multi-support | [docs](https://platform9.com/managed-kubernetes/) | Commercial From 8019d73c97af2ee2201b9380d70dcf6edb2330d9 Mon Sep 17 00:00:00 2001 From: Rohit Agarwal Date: Sun, 27 Aug 2017 16:01:52 -0700 Subject: [PATCH 17/32] Clean up the index page. 'Picking the Right Solution' already points to all these tools along with all other options. --- docs/home/index.md | 8 -------- docs/setup/pick-right-solution.md | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/home/index.md b/docs/home/index.md index 7399c031e8..187d5cc672 100644 --- a/docs/home/index.md +++ b/docs/home/index.md @@ -15,14 +15,6 @@ The [Kubernetes Basics interactive tutorial](/docs/tutorials/kubernetes-basics/) [Picking the Right Solution](/docs/getting-started-guides/) can help you get a Kubernetes cluster up and running, either for local development, or on your cloud provider of choice. -Other/newer ways to set up a Kubernetes cluster include: - -* [Minikube](/docs/getting-started-guides/minikube/): Install a single-node Kubernetes cluster on your local machine for development and testing. -* [Installing Kubernetes on AWS with kops](/docs/getting-started-guides/kops/): Bring up a complete Kubernetes cluster on Amazon Web Services, using a tool called `kops`. -* [Installing Kubernetes on Linux with kubeadm](/docs/getting-started-guides/kubeadm/) (Beta): Install a secure Kubernetes cluster on any pre-existing machines running Linux, using the built-in `kubeadm` tool. -* [Installing Kubernetes On-premises/Cloud Providers with Kubespray](/docs/getting-started-guides/kubespray/): Deploy a Kubernetes cluster on-premises baremetal or hosted on cloud providers, with Ansible and `kubespray` tools. -* [Installing Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/): Deploy a Kubernetes cluster on-premises, baremetal, cloud providers, or localhost with Charms and `conjure-up`. - ## Concepts, Tasks, and Tutorials The Kubernetes documentation contains a number of resources to help you understand and work with Kubernetes. diff --git a/docs/setup/pick-right-solution.md b/docs/setup/pick-right-solution.md index 23861da7b0..6af713c982 100644 --- a/docs/setup/pick-right-solution.md +++ b/docs/setup/pick-right-solution.md @@ -99,6 +99,7 @@ These solutions are combinations of cloud providers and operating systems not co * [CoreOS on AWS or GCE](/docs/getting-started-guides/coreos) * [Kubernetes on Ubuntu](/docs/getting-started-guides/ubuntu/) +* [Kubespray](/docs/getting-started-guides/kubespray/) ## On-Premises VMs From 613dcc65851d30bac6f819e0093ca9ccba14ed7f Mon Sep 17 00:00:00 2001 From: Sivasamy Kaliappan Date: Mon, 28 Aug 2017 14:32:40 +0530 Subject: [PATCH 18/32] Fixed incorrect links for YAML files The current links for YAML files throws 404. Updated the links from tutorials to tasks --- .../run-application/run-replicated-stateful-application.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tasks/run-application/run-replicated-stateful-application.md b/docs/tasks/run-application/run-replicated-stateful-application.md index 2be54886d5..9613bb2437 100644 --- a/docs/tasks/run-application/run-replicated-stateful-application.md +++ b/docs/tasks/run-application/run-replicated-stateful-application.md @@ -62,7 +62,7 @@ Create the ConfigMap from the following YAML configuration file: kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-configmap.yaml ``` -{% include code.html language="yaml" file="mysql-configmap.yaml" ghlink="/docs/tutorials/run-application/mysql-configmap.yaml" %} +{% include code.html language="yaml" file="mysql-configmap.yaml" ghlink="/docs/tasks/run-application/mysql-configmap.yaml" %} This ConfigMap provides `my.cnf` overrides that let you independently control configuration on the MySQL master and slaves. @@ -82,7 +82,7 @@ Create the Services from the following YAML configuration file: kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-services.yaml ``` -{% include code.html language="yaml" file="mysql-services.yaml" ghlink="/docs/tutorials/run-application/mysql-services.yaml" %} +{% include code.html language="yaml" file="mysql-services.yaml" ghlink="/docs/tasks/run-application/mysql-services.yaml" %} The Headless Service provides a home for the DNS entries that the StatefulSet controller creates for each Pod that's part of the set. @@ -108,7 +108,7 @@ Finally, create the StatefulSet from the following YAML configuration file: kubectl create -f https://k8s.io/docs/tasks/run-application/mysql-statefulset.yaml ``` -{% include code.html language="yaml" file="mysql-statefulset.yaml" ghlink="/docs/tutorials/run-application/mysql-statefulset.yaml" %} +{% include code.html language="yaml" file="mysql-statefulset.yaml" ghlink="/docs/tasks/run-application/mysql-statefulset.yaml" %} You can watch the startup progress by running: From 71a21288845effe02835043f4f2162fb99131a2d Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Mon, 28 Aug 2017 17:22:18 +0800 Subject: [PATCH 19/32] fix the command output fix the command output --- .../debug-application-introspection.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/tasks/debug-application-cluster/debug-application-introspection.md b/docs/tasks/debug-application-cluster/debug-application-introspection.md index bacbd66163..ac936adf74 100644 --- a/docs/tasks/debug-application-cluster/debug-application-introspection.md +++ b/docs/tasks/debug-application-cluster/debug-application-introspection.md @@ -62,6 +62,7 @@ Namespace: default Node: kubernetes-node-wul5/10.240.0.9 Start Time: Thu, 24 Mar 2016 01:39:49 +0000 Labels: app=nginx,pod-template-hash=1006230814 +Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind" :"ReplicaSet","namespace":"default","name":"nginx-deployment-1956810328","uid":"14e607e7-8ba1-11e7-b5cb-fa16 ... Status: Running IP: 10.244.0.6 Controllers: ReplicaSet/nginx-deployment-1006230814 @@ -84,14 +85,22 @@ Containers: Started: Thu, 24 Mar 2016 01:39:51 +0000 Ready: True Restart Count: 0 - Environment Variables: + Environment: + Mounts: + /var/run/secrets/kubernetes.io/serviceaccount from default-token-5kdvl (ro) Conditions: - Type Status - Ready True + Type Status + Initialized True + Ready True + PodScheduled True Volumes: default-token-4bcbi: Type: Secret (a volume populated by a Secret) SecretName: default-token-4bcbi + Optional: false +QoS Class: Guaranteed +Node-Selectors: +Tolerations: Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- From 60afe111005e3c301ec20e1583161dc58b0a82c6 Mon Sep 17 00:00:00 2001 From: "Tim(Xiaoyu) Zhang" Date: Tue, 29 Aug 2017 15:08:41 +0800 Subject: [PATCH 20/32] fix typo:ConfigMap ConfigMap is a kind of volume. So We should use its formal name. --- docs/concepts/storage/volumes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/storage/volumes.md b/docs/concepts/storage/volumes.md index 28cb140e48..4b644c4b8b 100644 --- a/docs/concepts/storage/volumes.md +++ b/docs/concepts/storage/volumes.md @@ -544,7 +544,7 @@ Each projected volume source is listed in the spec under `sources`. The parameters are nearly the same with two exceptions: * For secrets, the `secretName` field has been changed to `name` to be consistent -with config maps naming. +with ConfigMap naming. * The `defaultMode` can only be specified at the projected level and not for each volume source. However, as illustrated above, you can explicitly set the `mode` for each individual projection. From e50af70c1fe6b1127f553fabc15bc1a977345f3b Mon Sep 17 00:00:00 2001 From: William Stewart Date: Tue, 29 Aug 2017 12:42:55 +0200 Subject: [PATCH 21/32] Make caret for version drop-down more visible --- _sass/_base.sass | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/_sass/_base.sass b/_sass/_base.sass index 5e96e07c47..e45c5c9600 100644 --- a/_sass/_base.sass +++ b/_sass/_base.sass @@ -258,6 +258,9 @@ ul.global-nav left: 0 background: #fff + .ui-icon + filter: brightness(0) invert(1) + ul display: none position: fixed @@ -286,6 +289,10 @@ ul.global-nav .open-nav ul.global-nav li a, color: $dark-grey +.flip-nav ul.global-nav li a .ui-icon + filter: brightness(0) + + .flip-nav ul.global-nav li ul li a, background: #fff color: $dark-grey From 959cd767f5e066c76230ba7646e54525a8699862 Mon Sep 17 00:00:00 2001 From: mattjmcnaughton Date: Tue, 29 Aug 2017 09:10:08 -0400 Subject: [PATCH 22/32] Example links use kubernetes/examples Fix #5203 Previously, many of the Kubernetes links used `https://github.com/kubernetes/kubernetes/examples`. This directory was deprecated through https://github.com/kubernetes/kubernetes/commit/cb712e41d435dbb42519bded680fef4043dd23b3, in favor of the new `examples` repo hosted at `https://github.com/kubernetes/examples`. This commit updates all links accordingly. --- .../manage-deployment.md | 2 +- docs/concepts/configuration/overview.md | 6 ++-- .../connect-applications-service.md | 4 +-- .../services-networking/dns-pod-service.md | 2 +- docs/concepts/storage/persistent-volumes.md | 4 +-- docs/concepts/storage/volumes.md | 30 +++++++++---------- .../controllers/jobs-run-to-completion.md | 2 +- docs/concepts/workloads/controllers/petset.md | 4 +-- .../workloads/controllers/statefulset.md | 2 +- docs/getting-started-guides/aws.md | 4 +-- .../coreos/bare_metal_offline.md | 2 +- docs/getting-started-guides/dcos.md | 4 +-- docs/getting-started-guides/gce.md | 2 +- docs/getting-started-guides/mesos-docker.md | 2 +- docs/getting-started-guides/mesos/index.md | 2 +- docs/getting-started-guides/openstack-heat.md | 2 +- docs/getting-started-guides/rkt/index.md | 2 +- docs/getting-started-guides/ubuntu/manual.md | 2 +- docs/getting-started-guides/vsphere.md | 2 +- .../access-cluster.md | 4 +-- .../administer-cluster/access-cluster-api.md | 4 +-- .../index.md | 2 +- .../basic-stateful-set.md | 2 +- .../stateful-application/zookeeper.md | 2 +- docs/user-guide/walkthrough/index.md | 2 +- docs/user-guide/walkthrough/k8s201.md | 2 +- 26 files changed, 49 insertions(+), 49 deletions(-) diff --git a/docs/concepts/cluster-administration/manage-deployment.md b/docs/concepts/cluster-administration/manage-deployment.md index 2f97b153d9..4a94607125 100644 --- a/docs/concepts/cluster-administration/manage-deployment.md +++ b/docs/concepts/cluster-administration/manage-deployment.md @@ -137,7 +137,7 @@ If you're interested in learning more about `kubectl`, go ahead and read [kubect The examples we've used so far apply at most a single label to any resource. There are many scenarios where multiple labels should be used to distinguish sets from one another. -For instance, different applications would use different values for the `app` label, but a multi-tier application, such as the [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/), would additionally need to distinguish each tier. The frontend could carry the following labels: +For instance, different applications would use different values for the `app` label, but a multi-tier application, such as the [guestbook example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/), would additionally need to distinguish each tier. The frontend could carry the following labels: ```yaml labels: diff --git a/docs/concepts/configuration/overview.md b/docs/concepts/configuration/overview.md index febbc6726f..3690f36ea6 100644 --- a/docs/concepts/configuration/overview.md +++ b/docs/concepts/configuration/overview.md @@ -19,11 +19,11 @@ This is a living document. If you think of something that is not on this list bu - Write your configuration files using YAML rather than JSON. Though these formats can be used interchangeably in almost all scenarios, YAML tends to be more user-friendly. -- Group related objects into a single file whenever it makes sense. One file is often easier to manage than several. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax. +- Group related objects into a single file whenever it makes sense. One file is often easier to manage than several. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax. Note also that many `kubectl` commands can be called on a directory, so you can also call `kubectl create` on a directory of config files. See below for more details. -- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to reduce error. For example, omit the selector and labels in a `ReplicationController` if you want them to be the same as the labels in its `podTemplate`, since those fields are populated from the `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/frontend-deployment.yaml) of this. +- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to reduce error. For example, omit the selector and labels in a `ReplicationController` if you want them to be the same as the labels in its `podTemplate`, since those fields are populated from the `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/frontend-deployment.yaml) of this. - Put an object description in an annotation to allow better introspection. @@ -58,7 +58,7 @@ This is a living document. If you think of something that is not on this list bu ## Using Labels -- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or deployment. For example, instead of attaching a label to a set of pods to explicitly represent some service (For example, `service: myservice`), or explicitly representing the replication controller managing the pods (for example, `controller: mycontroller`), attach labels that identify semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This will let you select the object groups appropriate to the context— for example, a service for all "tier: frontend" pods, or all "test" phase components of app "myapp". See the [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) app for an example of this approach. +- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or deployment. For example, instead of attaching a label to a set of pods to explicitly represent some service (For example, `service: myservice`), or explicitly representing the replication controller managing the pods (for example, `controller: mycontroller`), attach labels that identify semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This will let you select the object groups appropriate to the context— for example, a service for all "tier: frontend" pods, or all "test" phase components of app "myapp". See the [guestbook](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) app for an example of this approach. A service can be made to span multiple deployments, such as is done across [rolling updates](/docs/tasks/run-application/rolling-update-replication-controller/), by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully. diff --git a/docs/concepts/services-networking/connect-applications-service.md b/docs/concepts/services-networking/connect-applications-service.md index 3572e9e9f2..3209c50afb 100644 --- a/docs/concepts/services-networking/connect-applications-service.md +++ b/docs/concepts/services-networking/connect-applications-service.md @@ -169,7 +169,7 @@ Till now we have only accessed the nginx server from within the cluster. Before * An nginx server configured to use the certificates * A [secret](/docs/user-guide/secrets) that makes the certificates accessible to pods -You can acquire all these from the [nginx https example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/https-nginx/), in short: +You can acquire all these from the [nginx https example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/https-nginx/), in short: ```shell $ make keys secret KEY=/tmp/nginx.key CERT=/tmp/nginx.crt SECRET=/tmp/secret.json @@ -188,7 +188,7 @@ Now modify your nginx replicas to start an https server using the certificate in Noteworthy points about the nginx-secure-app manifest: - It contains both Deployment and Service specification in the same file. -- The [nginx server](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/https-nginx/default.conf) serves http traffic on port 80 and https traffic on 443, and nginx Service exposes both ports. +- The [nginx server](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/https-nginx/default.conf) serves http traffic on port 80 and https traffic on 443, and nginx Service exposes both ports. - Each container has access to the keys through a volume mounted at /etc/nginx/ssl. This is setup *before* the nginx server is started. ```shell diff --git a/docs/concepts/services-networking/dns-pod-service.md b/docs/concepts/services-networking/dns-pod-service.md index 7f024f523a..bf3779981a 100644 --- a/docs/concepts/services-networking/dns-pod-service.md +++ b/docs/concepts/services-networking/dns-pod-service.md @@ -345,7 +345,7 @@ kube-dns 10.180.3.17:53,10.180.3.17:53 1h If you do not see the endpoints, see endpoints section in the [debugging services documentation](/docs/tasks/debug-application-cluster/debug-service/). -For additional Kubernetes DNS examples, see the [cluster-dns examples](https://git.k8s.io/kubernetes/examples/cluster-dns) in the Kubernetes GitHub repository. +For additional Kubernetes DNS examples, see the [cluster-dns examples](https://github.com/kubernetes/examples/tree/master/staging/cluster-dns) in the Kubernetes GitHub repository. ## Kubernetes Federation (Multiple Zone support) diff --git a/docs/concepts/storage/persistent-volumes.md b/docs/concepts/storage/persistent-volumes.md index fae77cfdfe..f20004aff7 100644 --- a/docs/concepts/storage/persistent-volumes.md +++ b/docs/concepts/storage/persistent-volumes.md @@ -536,7 +536,7 @@ parameters: ``` $ kubectl create secret generic heketi-secret --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' --namespace=default ``` - Example of a secret can be found in [glusterfs-provisioning-secret.yaml](https://git.k8s.io/kubernetes/examples/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml). + Example of a secret can be found in [glusterfs-provisioning-secret.yaml](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml). * `clusterid`: `630372ccdc720a92c681fb928f27b53f` is the ID of the cluster which will be used by Heketi when provisioning the volume. It can also be a list of clusterids, for ex: "8452344e2becec931ece4e33c4674e4e,42982310de6c63381718ccfa6d8cf397". This is an optional parameter. * `gidMin`, `gidMax` : The minimum and maximum value of GID range for the storage class. A unique value (GID) in this range ( gidMin-gidMax ) will be used for dynamically provisioned volumes. These are optional values. If not specified, the volume will be provisioned with a value between 2000-2147483647 which are defaults for gidMin and gidMax respectively. @@ -631,7 +631,7 @@ parameters: vSphere Infrastructure(VI) administrator can specify storage requirements for applications in terms of storage capabilities while creating a storage class inside Kubernetes. Please note that while creating a StorageClass, administrator should specify storage capability names used in the table above as these names might differ from the ones used by VSAN. For example - Number of disk stripes per object is referred to as stripeWidth in VSAN documentation however vSphere Cloud Provider uses a friendly name diskStripes. -You can see [vSphere example](https://git.k8s.io/kubernetes/examples/volumes/vsphere) for more details. +You can see [vSphere example](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere) for more details. #### Ceph RBD diff --git a/docs/concepts/storage/volumes.md b/docs/concepts/storage/volumes.md index 28cb140e48..868b5ad613 100644 --- a/docs/concepts/storage/volumes.md +++ b/docs/concepts/storage/volumes.md @@ -300,7 +300,7 @@ writers simultaneously. **Important:** You must have your own NFS server running with the share exported before you can use it. {: .caution} -See the [NFS example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/nfs) for more details. +See the [NFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/nfs) for more details. ### iscsi @@ -319,7 +319,7 @@ and then serve it in parallel from as many pods as you need. Unfortunately, iSCSI volumes can only be mounted by a single consumer in read-write mode - no simultaneous writers allowed. -See the [iSCSI example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/iscsi) for more details. +See the [iSCSI example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/iscsi) for more details. ### fc (fibre channel) @@ -331,7 +331,7 @@ targetWWNs expect that those WWNs are from multi-path connections. **Important:** You must configure FC SAN Zoning to allocate and mask those LUNs (volumes) to the target WWNs beforehand so that Kubernetes hosts can access them. {: .caution} -See the [FC example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/fibre_channel) for more details. +See the [FC example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/fibre_channel) for more details. ### flocker @@ -347,7 +347,7 @@ can be "handed off" between pods as required. **Important:** You must have your own Flocker installation running before you can use it. {: .caution} -See the [Flocker example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/flocker) for more details. +See the [Flocker example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/flocker) for more details. ### glusterfs @@ -362,7 +362,7 @@ simultaneously. **Important:** You must have your own GlusterFS installation running before you can use it. {: .caution} -See the [GlusterFS example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/glusterfs) for more details. +See the [GlusterFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/glusterfs) for more details. ### rbd @@ -382,7 +382,7 @@ and then serve it in parallel from as many pods as you need. Unfortunately, RBD volumes can only be mounted by a single consumer in read-write mode - no simultaneous writers allowed. -See the [RBD example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/rbd) for more details. +See the [RBD example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/rbd) for more details. ### cephfs @@ -396,7 +396,7 @@ writers simultaneously. **Important:** You must have your own Ceph server running with the share exported before you can use it. {: .caution} -See the [CephFS example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/cephfs/) for more details. +See the [CephFS example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/cephfs/) for more details. ### gitRepo @@ -555,20 +555,20 @@ A `FlexVolume` enables users to mount vendor volumes into a pod. It expects vend drivers are installed in the volume plugin path on each kubelet node. This is an alpha feature and may change in future. -More details are in [here](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/flexvolume/README.md). +More details are in [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/flexvolume/README.md). ### AzureFileVolume A `AzureFileVolume` is used to mount a Microsoft Azure File Volume (SMB 2.1 and 3.0) into a Pod. -More details can be found [here](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/azure_file/README.md). +More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_file/README.md). ### AzureDiskVolume A `AzureDiskVolume` is used to mount a Microsoft Azure [Data Disk](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-about-disks-vhds/) into a Pod. -More details can be found [here](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/azure_disk/README.md). +More details can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/azure_disk/README.md). ### vsphereVolume @@ -626,7 +626,7 @@ spec: volumePath: "[DatastoreName] volumes/myDisk" fsType: ext4 ``` -More examples can be found [here](https://git.k8s.io/kubernetes/examples/volumes/vsphere). +More examples can be found [here](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere). ### Quobyte @@ -636,7 +636,7 @@ A `Quobyte` volume allows an existing [Quobyte](http://www.quobyte.com) volume t **Important:** You must have your own Quobyte setup running with the volumes created before you can use it. {: .caution} -See the [Quobyte example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/quobyte) for more details. +See the [Quobyte example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/quobyte) for more details. ### PortworxVolume A `PortworxVolume` is an elastic block storage layer that runs hyperconverged with Kubernetes. Portworx fingerprints storage in a @@ -669,7 +669,7 @@ spec: **Important:** Make sure you have an existing PortworxVolume with name `pxvol` before using it in the pod. {: .caution} -More details and examples can be found [here](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/portworx/README.md). +More details and examples can be found [here](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/portworx/README.md). ### ScaleIO ScaleIO is a software-based storage platform that can use existing hardware to create clusters of scalable @@ -705,7 +705,7 @@ spec: fsType: xfs ``` -For further detail, please the see the [ScaleIO examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/scaleio). +For further detail, please the see the [ScaleIO examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/scaleio). ### StorageOS A `storageos` volume allows an existing [StorageOS](https://www.storageos.com) volume to be mounted into your pod. @@ -747,7 +747,7 @@ spec: fsType: ext4 ``` -For more information including Dynamic Provisioning and Persistent Volume Claims, please see the [StorageOS examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/volumes/storageos). +For more information including Dynamic Provisioning and Persistent Volume Claims, please see the [StorageOS examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/volumes/storageos). ### local diff --git a/docs/concepts/workloads/controllers/jobs-run-to-completion.md b/docs/concepts/workloads/controllers/jobs-run-to-completion.md index 23f604abab..1c5ceed3df 100644 --- a/docs/concepts/workloads/controllers/jobs-run-to-completion.md +++ b/docs/concepts/workloads/controllers/jobs-run-to-completion.md @@ -366,7 +366,7 @@ of custom controller for those pods. This allows the most flexibility, but may complicated to get started with and offers less integration with Kubernetes. One example of this pattern would be a Job which starts a Pod which runs a script that in turn -starts a Spark master controller (see [spark example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/spark/README.md)), runs a spark +starts a Spark master controller (see [spark example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/spark/README.md)), runs a spark driver, and then cleans up. An advantage of this approach is that the overall process gets the completion guarantee of a Job diff --git a/docs/concepts/workloads/controllers/petset.md b/docs/concepts/workloads/controllers/petset.md index 87c301259a..42c90cfd96 100644 --- a/docs/concepts/workloads/controllers/petset.md +++ b/docs/concepts/workloads/controllers/petset.md @@ -39,7 +39,7 @@ This doc assumes familiarity with the following Kubernetes concepts: * [Cluster DNS](/docs/concepts/services-networking/dns-pod-service/) * [Headless Services](/docs/user-guide/services/#headless-services) * [Persistent Volumes](/docs/concepts/storage/volumes/) -* [Persistent Volume Provisioning](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/README.md) +* [Persistent Volume Provisioning](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/README.md) You need a working Kubernetes cluster at version >= 1.3, with a healthy DNS [cluster addon](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/README.md) at version >= 15. You cannot use PetSet on a hosted Kubernetes provider that has disabled `alpha` resources. @@ -95,7 +95,7 @@ Before you start deploying applications as PetSets, there are a few limitations * PetSet is an *alpha* resource, not available in any Kubernetes release prior to 1.3. * As with all alpha/beta resources, it can be disabled through the `--runtime-config` option passed to the apiserver, and in fact most likely will be disabled on hosted offerings of Kubernetes. * The only updatable field on a PetSet is `replicas`. -* The storage for a given pet must either be provisioned by a [persistent volume provisioner](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. Note that persistent volume provisioning is also currently in alpha. +* The storage for a given pet must either be provisioned by a [persistent volume provisioner](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. Note that persistent volume provisioning is also currently in alpha. * Deleting and/or scaling a PetSet down will *not* delete the volumes associated with the PetSet. This is done to ensure safety first, your data is more valuable than an auto purge of all related PetSet resources. **Deleting the Persistent Volume Claims will result in a deletion of the associated volumes**. * All PetSets currently require a "governing service", or a Service responsible for the network identity of the pets. The user is responsible for this Service. * Updating an existing PetSet is currently a manual process, meaning you either need to deploy a new PetSet with the new image version, or orphan Pets one by one, update their image, and join them back to the cluster. diff --git a/docs/concepts/workloads/controllers/statefulset.md b/docs/concepts/workloads/controllers/statefulset.md index d52a8c1e1f..52168247c7 100644 --- a/docs/concepts/workloads/controllers/statefulset.md +++ b/docs/concepts/workloads/controllers/statefulset.md @@ -42,7 +42,7 @@ provides a set of stateless replicas. Controllers such as * StatefulSet is a beta resource, not available in any Kubernetes release prior to 1.5. * As with all alpha/beta resources, you can disable StatefulSet through the `--runtime-config` option passed to the apiserver. -* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. +* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. * Deleting and/or scaling a StatefulSet down will *not* delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources. * StatefulSets currently require a [Headless Service](/docs/concepts/services-networking/service/#headless-services) to be responsible for the network identity of the Pods. You are responsible for creating this Service. diff --git a/docs/getting-started-guides/aws.md b/docs/getting-started-guides/aws.md index 033345b7b5..f723837295 100644 --- a/docs/getting-started-guides/aws.md +++ b/docs/getting-started-guides/aws.md @@ -142,9 +142,9 @@ For more information, please read [kubeconfig files](/docs/concepts/cluster-admi See [a simple nginx example](/docs/user-guide/simple-nginx) to try out your new cluster. -The "Guestbook" application is another popular example to get started with Kubernetes: [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) +The "Guestbook" application is another popular example to get started with Kubernetes: [guestbook example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) -For more complete applications, please look in the [examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) +For more complete applications, please look in the [examples directory](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) ## Scaling the cluster diff --git a/docs/getting-started-guides/coreos/bare_metal_offline.md b/docs/getting-started-guides/coreos/bare_metal_offline.md index c60839bf59..a471d2db8d 100644 --- a/docs/getting-started-guides/coreos/bare_metal_offline.md +++ b/docs/getting-started-guides/coreos/bare_metal_offline.md @@ -653,7 +653,7 @@ Now that the CoreOS with Kubernetes installed is up and running lets spin up som See [a simple nginx example](/docs/user-guide/simple-nginx) to try out your new cluster. -For more complete applications, please look in the [examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/). +For more complete applications, please look in the [examples directory](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/). ## Helping commands for debugging diff --git a/docs/getting-started-guides/dcos.md b/docs/getting-started-guides/dcos.md index 8955334e6d..07aa56c002 100644 --- a/docs/getting-started-guides/dcos.md +++ b/docs/getting-started-guides/dcos.md @@ -33,7 +33,7 @@ Explore the following resources for more information about Kubernetes, Kubernete - [DCOS Documentation](https://docs.mesosphere.com/) - [Managing DCOS Services](https://docs.mesosphere.com/services/kubernetes/) -- [Kubernetes Examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) +- [Kubernetes Examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) - [Kubernetes on Mesos Documentation](https://github.com/kubernetes-incubator/kube-mesos-framework/blob/master/README.md) - [Kubernetes on Mesos Release Notes](https://github.com/mesosphere/kubernetes-mesos/releases) - [Kubernetes on DCOS Package Source](https://github.com/mesosphere/kubernetes-mesos) @@ -110,7 +110,7 @@ $ dcos kubectl get pods --namespace=kube-system Names and ages may vary. -Now that Kubernetes is installed on DCOS, you may wish to explore the [Kubernetes Examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/README.md) or the [Kubernetes User Guide](/docs/user-guide/). +Now that Kubernetes is installed on DCOS, you may wish to explore the [Kubernetes Examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/README.md) or the [Kubernetes User Guide](/docs/user-guide/). ## Uninstall diff --git a/docs/getting-started-guides/gce.md b/docs/getting-started-guides/gce.md index a152d0af53..31d95c45f8 100644 --- a/docs/getting-started-guides/gce.md +++ b/docs/getting-started-guides/gce.md @@ -135,7 +135,7 @@ Some of the pods may take a few seconds to start up (during this time they'll sh Then, see [a simple nginx example](/docs/user-guide/simple-nginx) to try out your new cluster. -For more complete applications, please look in the [examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/). The [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) is a good "getting started" walkthrough. +For more complete applications, please look in the [examples directory](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/). The [guestbook example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) is a good "getting started" walkthrough. ### Tearing down the cluster diff --git a/docs/getting-started-guides/mesos-docker.md b/docs/getting-started-guides/mesos-docker.md index a6540bebdb..05a26dac05 100644 --- a/docs/getting-started-guides/mesos-docker.md +++ b/docs/getting-started-guides/mesos-docker.md @@ -216,7 +216,7 @@ sudo route -n add -net 172.17.0.0 $(docker-machine ip kube-dev) To learn more about Pods, Volumes, Labels, Services, and Replication Controllers, start with the [Kubernetes Tutorials](/docs/tutorials/). - To skip to a more advanced example, see the [Guestbook Example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) + To skip to a more advanced example, see the [Guestbook Example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) 1. Destroy cluster diff --git a/docs/getting-started-guides/mesos/index.md b/docs/getting-started-guides/mesos/index.md index d09b280779..26cc6c248a 100644 --- a/docs/getting-started-guides/mesos/index.md +++ b/docs/getting-started-guides/mesos/index.md @@ -333,7 +333,7 @@ Future work will add instructions to this guide to enable support for Kubernetes [6]: http://mesos.apache.org/ [7]: https://github.com/kubernetes-incubator/kube-mesos-framework/blob/master/docs/issues.md [8]: https://github.com/mesosphere/kubernetes-mesos/issues -[9]: https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples +[9]: https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/ [10]: http://open.mesosphere.com/getting-started/cloud/google/mesosphere/#vpn-setup [11]: https://git.k8s.io/kubernetes/cluster/addons/dns/README.md#kube-dns [12]: https://git.k8s.io/kubernetes/cluster/addons/dns/kubedns-controller.yaml.in diff --git a/docs/getting-started-guides/openstack-heat.md b/docs/getting-started-guides/openstack-heat.md index c405b7eddd..70f20a89f9 100644 --- a/docs/getting-started-guides/openstack-heat.md +++ b/docs/getting-started-guides/openstack-heat.md @@ -167,7 +167,7 @@ Once the nginx pod is running, use the port-forward command to set up a proxy fr You should now see nginx on [http://localhost:8888](). -For more complex examples please see the [examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/). +For more complex examples please see the [examples directory](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/). ## Administering your cluster with Openstack diff --git a/docs/getting-started-guides/rkt/index.md b/docs/getting-started-guides/rkt/index.md index d95e073f77..bf048ebaf2 100644 --- a/docs/getting-started-guides/rkt/index.md +++ b/docs/getting-started-guides/rkt/index.md @@ -151,7 +151,7 @@ The `kube-up` script is not yet supported on AWS. Instead, we recommend followin ### Deploy apps to the cluster -After creating the cluster, you can start deploying applications. For an introductory example, [deploy a simple nginx web server](/docs/user-guide/simple-nginx). Note that this example did not have to be modified for use with a "rktnetes" cluster. More examples can be found in the [Kubernetes examples directory](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/). +After creating the cluster, you can start deploying applications. For an introductory example, [deploy a simple nginx web server](/docs/user-guide/simple-nginx). Note that this example did not have to be modified for use with a "rktnetes" cluster. More examples can be found in the [Kubernetes examples directory](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/). ## Modular isolation with interchangeable stage1 images diff --git a/docs/getting-started-guides/ubuntu/manual.md b/docs/getting-started-guides/ubuntu/manual.md index e45fc69a33..7957e10bef 100644 --- a/docs/getting-started-guides/ubuntu/manual.md +++ b/docs/getting-started-guides/ubuntu/manual.md @@ -170,7 +170,7 @@ NAME STATUS AGE VERSION 10.10.103.250 Ready 3d v1.6.0+fff5156 ``` -Also you can run Kubernetes [guest-example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) to build a redis backend cluster. +Also you can run Kubernetes [guest-example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) to build a redis backend cluster. ### Deploy addons diff --git a/docs/getting-started-guides/vsphere.md b/docs/getting-started-guides/vsphere.md index a0048b228c..ebad9e3204 100644 --- a/docs/getting-started-guides/vsphere.md +++ b/docs/getting-started-guides/vsphere.md @@ -33,7 +33,7 @@ vSphere Cloud Provider allows using vSphere managed storage within Kubernetes. I Documentation for how to use vSphere managed storage can be found in the [persistent volumes user guide](/docs/concepts/storage/persistent-volumes/#vsphere) and the [volumes user guide](/docs/concepts/storage/volumes/#vspherevolume). -Examples can be found [here](https://git.k8s.io/kubernetes/examples/volumes/vsphere). +Examples can be found [here](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere). #### Enable vSphere Cloud Provider diff --git a/docs/tasks/access-application-cluster/access-cluster.md b/docs/tasks/access-application-cluster/access-cluster.md index a623ad36bf..9d218e816f 100644 --- a/docs/tasks/access-application-cluster/access-cluster.md +++ b/docs/tasks/access-application-cluster/access-cluster.md @@ -23,7 +23,7 @@ Check the location and credentials that kubectl knows about with this command: $ kubectl config view ``` -Many of the [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) provide an introduction to using +Many of the [examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) provide an introduction to using kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index). ### Directly accessing the REST API @@ -172,7 +172,7 @@ From within a pod the recommended ways to connect to API are: process within a container. This proxies the Kubernetes API to the localhost interface of the pod, so that other processes in any container of the pod can access it. See this [example of using kubectl proxy - in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/). + in a pod](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/kubectl-container/). - use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions. They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go) diff --git a/docs/tasks/administer-cluster/access-cluster-api.md b/docs/tasks/administer-cluster/access-cluster-api.md index 995e8ad69d..f1fd4ea5c1 100644 --- a/docs/tasks/administer-cluster/access-cluster-api.md +++ b/docs/tasks/administer-cluster/access-cluster-api.md @@ -31,7 +31,7 @@ Check the location and credentials that kubectl knows about with this command: $ kubectl config view ``` -Many of the [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) provide an introduction to using +Many of the [examples](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/) provide an introduction to using kubectl. Complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index). ### Directly accessing the REST API @@ -194,7 +194,7 @@ From within a pod the recommended ways to connect to API are: process within a container. This proxies the Kubernetes API to the localhost interface of the pod, so that other processes in any container of the pod can access it. See this [example of using kubectl proxy - in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/). + in a pod](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/kubectl-container/). - use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions. They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go) diff --git a/docs/tasks/job/fine-parallel-processing-work-queue/index.md b/docs/tasks/job/fine-parallel-processing-work-queue/index.md index 1b4ff01698..887f5e6dd2 100644 --- a/docs/tasks/job/fine-parallel-processing-work-queue/index.md +++ b/docs/tasks/job/fine-parallel-processing-work-queue/index.md @@ -31,7 +31,7 @@ Here is an overview of the steps in this example: ## Starting Redis For this example, for simplicity, we will start a single instance of Redis. -See the [Redis Example](https://git.k8s.io/kubernetes/examples/guestbook) for an example +See the [Redis Example](https://github.com/kubernetes/examples/tree/master/guestbook) for an example of deploying Redis scalably and redundantly. Start a temporary Pod running Redis and a service so we can find it. diff --git a/docs/tutorials/stateful-application/basic-stateful-set.md b/docs/tutorials/stateful-application/basic-stateful-set.md index 30c13a4f8e..32420ddf8b 100644 --- a/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/docs/tutorials/stateful-application/basic-stateful-set.md @@ -23,7 +23,7 @@ following Kubernetes concepts. * [Cluster DNS](/docs/concepts/services-networking/dns-pod-service/) * [Headless Services](/docs/concepts/services-networking/service/#headless-services) * [PersistentVolumes](/docs/concepts/storage/volumes/) -* [PersistentVolume Provisioning](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/) +* [PersistentVolume Provisioning](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/) * [StatefulSets](/docs/concepts/abstractions/controllers/statefulsets/) * [kubectl CLI](/docs/user-guide/kubectl) diff --git a/docs/tutorials/stateful-application/zookeeper.md b/docs/tutorials/stateful-application/zookeeper.md index 1ef52a7a23..09159d471d 100644 --- a/docs/tutorials/stateful-application/zookeeper.md +++ b/docs/tutorials/stateful-application/zookeeper.md @@ -26,7 +26,7 @@ Kubernetes concepts. * [Cluster DNS](/docs/concepts/services-networking/dns-pod-service/) * [Headless Services](/docs/concepts/services-networking/service/#headless-services) * [PersistentVolumes](/docs/concepts/storage/volumes/) -* [PersistentVolume Provisioning](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/) +* [PersistentVolume Provisioning](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/staging/persistent-volume-provisioning/) * [ConfigMaps](/docs/tasks/configure-pod-container/configmap/) * [StatefulSets](/docs/concepts/abstractions/controllers/statefulsets/) * [PodDisruptionBudgets](/docs/admin/disruptions/#specifying-a-poddisruptionbudget) diff --git a/docs/user-guide/walkthrough/index.md b/docs/user-guide/walkthrough/index.md index cfd8d1e2e6..ae5a938ec9 100644 --- a/docs/user-guide/walkthrough/index.md +++ b/docs/user-guide/walkthrough/index.md @@ -162,4 +162,4 @@ Finally, we have also introduced an environment variable to the `git-monitor` co ## What's Next? Continue on to [Kubernetes 201](/docs/user-guide/walkthrough/k8s201) or -for a complete application see the [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) +for a complete application see the [guestbook example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/) diff --git a/docs/user-guide/walkthrough/k8s201.md b/docs/user-guide/walkthrough/k8s201.md index 594cf05c3c..f5f42d7120 100644 --- a/docs/user-guide/walkthrough/k8s201.md +++ b/docs/user-guide/walkthrough/k8s201.md @@ -225,4 +225,4 @@ For more information about health checking, see [Container Probes](/docs/user-gu ## What's Next? -For a complete application see the [guestbook example](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/). +For a complete application see the [guestbook example](https://github.com/kubernetes/examples/tree/{{page.githubbranch}}/guestbook/). From 5fcf7f6e8c9cf1cfbd71737be39b95c64fa6caca Mon Sep 17 00:00:00 2001 From: Dragons Date: Wed, 30 Aug 2017 10:53:15 +0800 Subject: [PATCH 23/32] index-pr-2017-08-15 --- cn/index.html | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 cn/index.html diff --git a/cn/index.html b/cn/index.html new file mode 100644 index 0000000000..63e059c497 --- /dev/null +++ b/cn/index.html @@ -0,0 +1,186 @@ +--- +layout: basic +cid: home +--- + + +
+
+
+ +

生产级别的容器编排系统

+
自动化的容器部署、扩展和管理
+
+ + 尝试我们的互动教程 +
+ + + + + + + +
+ + +
+
+
+
+ +

Kubernetes 是用于自动部署,扩展和管理容器化应用程序的开源系统。

+

它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现,Kubernetes 构建在 Google 15 年生产环境经验基础之上,并结合来自社区的最佳创意和实践。

+
+
+
+
+
+ +

星际尺度

+

根据同样的原则设计,允许 Google 每周运行数十亿个容器,Kubernetes 可以在不增加您的 ops 团队的情况下进行弹性扩展。

+
+
+
+
+
+ +

永不过时

+

无论您应用运行在本地还是运行于全球任何地域,Kubernetes 的灵活性都可以随着您的需求复杂度不断增加,还可以持续、轻松地对外提供服务。

+
+
+
+
+
+ +

随处运行

+

Kubernetes 是开源的,可以让您自由地部署在企业内部,私有云、混合云或公有云基础架构,使您轻松将应用迁移至任何位置。

+
+
+
+ +
+
+ +

Kubernetes: 最后… 它是真正的云平台

+

Box 的联合创始人和服务架构师 Sam Ghods 发表了热情洋溢的演讲,随着使用 Kubernetes,我们首次有一个通用接口,可以建立真正的部署工具。

+ +
+ +
+ +
+
+ +

Kubernetes 特性

+ +
+
+ +

自动包装

+

根据资源需求和其他约束自动放置容器,同时不会牺牲可用性,混合关键和最大努力的工作负载,以提高资源利用率并节省更多资源。

+
+
+ +

自我修复

+

重新启动失败的容器,在节点不可用时,替换和重新编排节点上的容器,终止不对用户定义的健康检查做出响应的容器,并且不会在客户端准备投放之前将其通告给客户端。

+
+
+ +
+
+ +

横向缩放

+

使用简单的命令或 UI,或者根据 CPU 的使用情况自动调整应用程序副本数。

+
+
+ +

服务发现和负载均衡

+

不需要修改您的应用程序来使用不熟悉的服务发现机制,Kubernetes 为容器提供了自己的 IP 地址和一组容器的单个 DNS 名称,并可以在它们之间进行负载均衡。

+
+
+ +
+
+ +

自动部署和回滚

+

Kubernetes 逐渐部署对应用程序或其配置的更改,同时监视应用程序运行状况,以确保它不会同时终止所有实例。 如果出现问题,Kubernetes会为您恢复更改,利用日益增长的部署解决方案的生态系统。

+
+
+

密钥配置 管理

+

部署和更新密钥和应用程序配置,不会重新编译您的镜像,不会在堆栈配置中暴露密钥(secrets)。

+
+
+ +
+
+

存储编排

+

自动安装您所选择的存储系统,无论是本地存储,如公有云提供商 GCPAWS, 还是网络存储系统 NFS, iSCSI, + Gluster, Ceph, Cinder, 或 Flocker。

+
+
+

批处理

+

除了服务之外,Kubernetes还可以管理您的批处理和 CI 工作负载,如果需要,替换出现故障的容器。

+
+
+ +
+
+ +
+
+ +

实例探究

+
+
+

使用Kubernetes来重塑世界上最大的教育公司

+ 阅读更多 +
+
+

Kubernetes at Box: 微服务的最大优势

+ 阅读更多 +
+
+

在 eBay 内部转移到 OpenStack 上的 Kubernetes 和容器

+ 阅读更多 +
+
+

将本地的集群迁移至 Kubernetes

+ 观看视频 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
探究所有的案例
+
+
+ + + + +
+ + +
From ab4f5c3e380106c36299ec6255d1891f0fd2fec7 Mon Sep 17 00:00:00 2001 From: chentao1596 Date: Wed, 30 Aug 2017 11:09:38 +0800 Subject: [PATCH 24/32] Translate into chinese about GPU --- cn/docs/tasks/manage-gpus/scheduling-gpus.md | 178 +++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 cn/docs/tasks/manage-gpus/scheduling-gpus.md diff --git a/cn/docs/tasks/manage-gpus/scheduling-gpus.md b/cn/docs/tasks/manage-gpus/scheduling-gpus.md new file mode 100644 index 0000000000..208d01caf1 --- /dev/null +++ b/cn/docs/tasks/manage-gpus/scheduling-gpus.md @@ -0,0 +1,178 @@ +--- +approvers: +- vishh +title: 调度 GPU +--- + +{% capture overview %} + + +Kubernetes 提供对分布在节点上的 NVIDIA GPU 进行管理的**实验**支持。本页描述用户如何使用 GPU 以及当前使用的一些限制 + +{% endcapture %} + +{% capture prerequisites %} + + +1. Kubernetes 节点必须预先安装好 NVIDIA 驱动,否则,Kubelet 将检测不到可用的GPU信息;如果节点的 Capacity 属性中没有出现 NIVIDA GPU 的数量,有可能是驱动没有安装或者安装失败,请尝试重新安装 + +2. 在整个 Kubernetes 系统中,feature-gates 里面特定的 **alpha** 特性参数 `Accelerators` 必须设置为 true:`--feature-gates="Accelerators=true"` + +3. Kuberntes 节点必须使用 `docker` 引擎作为容器的运行引擎 + + +上述预备工作完成后,节点会自动发现它上面的 NVIDIA GPU,并将其作为可调度资源暴露 + +{% endcapture %} + +{% capture steps %} + +## API + + +容器可以通过名称为 `alpha.kubernetes.io/nvidia-gpu` 的标识来申请需要使用的 NVIDIA GPU 的数量 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: gpu-pod +spec: + containers: + - + name: gpu-container-1 + image: gcr.io/google_containers/pause:2.0 + resources: + limits: + alpha.kubernetes.io/nvidia-gpu: 2 # requesting 2 GPUs + - + name: gpu-container-2 + image: gcr.io/google_containers/pause:2.0 + resources: + limits: + alpha.kubernetes.io/nvidia-gpu: 3 # requesting 3 GPUs +``` + + +- GPU 只能在容器资源的 `limits` 中配置 + +- 容器和 Pod 都不支持共享 GPU + +- 每个容器可以申请使用一个或者多个 GPU + +- GPU 必须以整数为单位被申请使用 + +- 所有节点的 GPU 硬件要求相同 + + +如果在不同的节点上面安装了不同版本的 GPU,可以通过设置节点标签以及使用节点选择器的方式将 pod 调度到期望运行的节点上。工作流程如下: + + +在节点上,识别出 GPU 硬件类型,然后将其作为节点标签进行暴露 + +```shell +NVIDIA_GPU_NAME=$(nvidia-smi --query-gpu=gpu_name --format=csv,noheader --id=0) +source /etc/default/kubelet +KUBELET_OPTS="$KUBELET_OPTS --node-labels='alpha.kubernetes.io/nvidia-gpu-name=$NVIDIA_GPU_NAME'" +echo "KUBELET_OPTS=$KUBELET_OPTS" > /etc/default/kubelet +``` + + +在 pod 上,通过节点[亲和性](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)规则为它指定可以使用的 GPU 类型 + +```yaml +kind: pod +apiVersion: v1 +metadata: + annotations: + scheduler.alpha.kubernetes.io/affinity: > + { + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "alpha.kubernetes.io/nvidia-gpu-name", + "operator": "In", + "values": ["Tesla K80", "Tesla P100"] + } + ] + } + ] + } + } + } +spec: + containers: + - + name: gpu-container-1 + resources: + limits: + alpha.kubernetes.io/nvidia-gpu: 2 +``` + + +上述设定可以确保 pod 会被调度到包含名称为 `alpha.kubernetes.io/nvidia-gpu-name` 的标签并且标签的值为 `Tesla K80` 或者 `Tesla P100` 的节点上 + + +### 警告 + + +当未来的 Kubernetes 版本能够更好的支持GPU以及一般的硬件加速器时,这里的 API 描述**将会随之做出变更** + + +## 访问 CUDA 库 + + +到目前为止,还需要预先在节点上安装 CUDA 库 + + +为了避免后面使用库出现问题,可以将库放到 ``/var/lib/`` 下的某个文件夹下,或者直接改变库目录的权限(以后的版本会自动完成这一过程) + + +Pods能够通过 `hostPath` 卷来访问库 + +```yaml +kind: Pod +apiVersion: v1 +metadata: + name: gpu-pod +spec: + containers: + - name: gpu-container-1 + image: gcr.io/google_containers/pause:2.0 + resources: + limits: + alpha.kubernetes.io/nvidia-gpu: 1 + volumeMounts: + - mountPath: /usr/local/nvidia/bin + name: bin + - mountPath: /usr/lib/nvidia + name: lib + volumes: + - hostPath: + path: /usr/lib/nvidia-375/bin + name: bin + - hostPath: + path: /usr/lib/nvidia-375 + name: lib +``` + + +## 未来 + + +- Kubernetes 对硬件加速器的支持还处在早期阶段 + +- GPU 和其它的加速器很快会成为系统的本地计算资源 + +- 将引入更好的 API 以可扩展的方式提供和使用加速器 + +- Kubernets 将会自动确保应用在使用 GPU 时得到最佳性能 + +- 类似访问 CUDA 库这种关键的可用性问题将得到解决 + +{% endcapture %} + +{% include templates/task.md %} From 7b3ca0814f0cdf30318e26bcaea51d8566a1bb48 Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Wed, 30 Aug 2017 16:02:47 +0800 Subject: [PATCH 25/32] fix the command output fix the command output --- .../service-access-application-cluster.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tasks/access-application-cluster/service-access-application-cluster.md b/docs/tasks/access-application-cluster/service-access-application-cluster.md index ebbd195b5e..46bb4c9833 100644 --- a/docs/tasks/access-application-cluster/service-access-application-cluster.md +++ b/docs/tasks/access-application-cluster/service-access-application-cluster.md @@ -66,14 +66,14 @@ provides load balancing for an application that has two running instances. Name: example-service Namespace: default Labels: run=load-balancer-example + Annotations: Selector: run=load-balancer-example Type: NodePort IP: 10.32.0.16 Port: 8080/TCP - NodePort: 31496/TCP Endpoints: 10.200.1.4:8080,10.200.2.5:8080 Session Affinity: None - No events. + Events: Make a note of the NodePort value for the service. For example, in the preceding output, the NodePort value is 31496. From 2c85669fb9d61129668cb512d65c88e8da5abbde Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Wed, 30 Aug 2017 16:53:19 +0800 Subject: [PATCH 26/32] fix typo fix typo --- .../debug-application-cluster/logging-stackdriver.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tasks/debug-application-cluster/logging-stackdriver.md b/docs/tasks/debug-application-cluster/logging-stackdriver.md index fb29b010cf..ccaba3ea08 100644 --- a/docs/tasks/debug-application-cluster/logging-stackdriver.md +++ b/docs/tasks/debug-application-cluster/logging-stackdriver.md @@ -53,7 +53,7 @@ Stackdriver Logging agents to the running cluster. that don't have fluentd pod allocated already. You can ensure that your node is labelled properly by running `kubectl describe` as follows: - ```shell + ``` kubectl describe node $NODE_NAME ``` @@ -69,7 +69,7 @@ Stackdriver Logging agents to the running cluster. Ensure that the output contains the label `beta.kubernetes.io/fluentd-ds-ready=true`. If it is not present, you can add it using the `kubectl label` command as follows: - ```shell + ``` kubectl label node $NODE_NAME beta.kubernetes.io/fluentd-ds-ready=true ``` @@ -79,7 +79,7 @@ Stackdriver Logging agents to the running cluster. 1. Deploy a `ConfigMap` with the logging agent configuration by running the following command: - ```shell + ``` kubectl create -f https://k8s.io/docs/tasks/debug-application-cluster/fluentd-gcp-configmap.yaml ``` @@ -88,7 +88,7 @@ Stackdriver Logging agents to the running cluster. 1. Deploy the logging agent `DaemonSet` by running the following command: - ```shell + ``` kubectl create -f https://k8s.io/docs/tasks/debug-application-cluster/fluentd-gcp-ds.yaml ``` From 9164d30955fc644d399af75ea7b05215fa74cb90 Mon Sep 17 00:00:00 2001 From: Jimmy Song Date: Wed, 30 Aug 2017 20:45:01 +0800 Subject: [PATCH 27/32] rootsongjc-pr-20170815 --- cn/docs/admin/daemon.yaml | 18 + .../kubelet-authentication-authorization.md | 87 ++ cn/docs/admin/kubelet-tls-bootstrapping.md | 216 ++++ cn/docs/concepts/configuration/commands.yaml | 12 + cn/docs/concepts/configuration/overview.md | 93 ++ .../configuration/pod-with-node-affinity.yaml | 26 + .../configuration/pod-with-pod-affinity.yaml | 29 + cn/docs/concepts/configuration/pod.yaml | 13 + .../concepts/services-networking/curlpod.yaml | 25 + .../services-networking/hostaliases-pod.yaml | 21 + .../concepts/services-networking/ingress.md | 298 ++++++ .../concepts/services-networking/ingress.yaml | 9 + .../services-networking/nginx-secure-app.yaml | 43 + .../services-networking/nginx-svc.yaml | 12 + .../services-networking/run-my-nginx.yaml | 17 + .../workloads/controllers/cronjob.yaml | 18 + .../workloads/controllers/daemonset.yaml | 36 + .../workloads/controllers/deployment.md | 935 ++++++++++++++++++ .../workloads/controllers/frontend.yaml | 45 + .../workloads/controllers/hpa-rs.yaml | 11 + .../concepts/workloads/controllers/job.yaml | 15 + .../workloads/controllers/my-repset.yaml | 17 + .../controllers/nginx-deployment.yaml | 16 + .../workloads/controllers/petset.yaml | 51 + .../workloads/controllers/replication.yaml | 19 + .../workloads/controllers/statefulset.md | 231 +++++ .../access-cluster.md | 318 ++++++ .../access-application-cluster/frontend.yaml | 34 + .../hello-service.yaml | 12 + .../access-application-cluster/hello.yaml | 19 + ...port-forward-access-application-cluster.md | 94 ++ .../redis-master.yaml | 33 + .../service-access-application-cluster.md | 147 +++ .../two-container-pod.yaml | 27 + .../cpu-constraints-pod-2.yaml | 13 + .../cpu-constraints-pod-3.yaml | 13 + .../cpu-constraints-pod-4.yaml | 8 + .../cpu-constraints-pod.yaml | 13 + .../administer-cluster/cpu-constraints.yaml | 11 + .../cpu-defaults-pod-2.yaml | 11 + .../cpu-defaults-pod-3.yaml | 11 + .../administer-cluster/cpu-defaults-pod.yaml | 8 + .../administer-cluster/cpu-defaults.yaml | 11 + .../dns-horizontal-autoscaler.yaml | 30 + .../tasks/administer-cluster/ip-masq-agent.md | 112 +++ .../memory-constraints-pod-2.yaml | 13 + .../memory-constraints-pod-3.yaml | 13 + .../memory-constraints-pod-4.yaml | 9 + .../memory-constraints-pod.yaml | 13 + .../memory-constraints.yaml | 11 + .../memory-defaults-pod-2.yaml | 11 + .../memory-defaults-pod-3.yaml | 11 + .../memory-defaults-pod.yaml | 8 + .../administer-cluster/memory-defaults.yaml | 11 + .../administer-cluster/my-scheduler.yaml | 43 + cn/docs/tasks/administer-cluster/pod1.yaml | 10 + cn/docs/tasks/administer-cluster/pod2.yaml | 11 + cn/docs/tasks/administer-cluster/pod3.yaml | 11 + .../quota-mem-cpu-pod-2.yaml | 16 + .../administer-cluster/quota-mem-cpu-pod.yaml | 16 + .../administer-cluster/quota-mem-cpu.yaml | 10 + .../quota-objects-pvc-2.yaml | 11 + .../administer-cluster/quota-objects-pvc.yaml | 11 + .../administer-cluster/quota-objects.yaml | 9 + .../quota-pod-deployment.yaml | 14 + .../tasks/administer-cluster/quota-pod.yaml | 7 + .../tasks/administer-cluster/quota-pvc-2.yaml | 11 + .../configure-pod-container/configmap.md | 256 +++++ .../configure-liveness-readiness-probes.md | 301 ++++++ .../configure-service-account.md | 231 +++++ .../cpu-request-limit-2.yaml | 16 + .../cpu-request-limit.yaml | 16 + .../exec-liveness.yaml | 26 + .../http-liveness.yaml | 25 + .../init-containers.yaml | 30 + .../lifecycle-events.yaml | 33 + .../mem-limit-range.yaml | 11 + .../memory-request-limit-2.yaml | 20 + .../memory-request-limit-3.yaml | 20 + .../memory-request-limit.yaml | 20 + .../configure-pod-container/oir-pod-2.yaml | 11 + .../configure-pod-container/oir-pod.yaml | 11 + .../configure-pod-container/pod-redis.yaml | 14 + .../tasks/configure-pod-container/pod.yaml | 13 + .../private-reg-pod.yaml | 11 + .../projected-volume.yaml | 23 + .../configure-pod-container/qos-pod-2.yaml | 13 + .../configure-pod-container/qos-pod-3.yaml | 8 + .../configure-pod-container/qos-pod-4.yaml | 15 + .../configure-pod-container/qos-pod.yaml | 15 + .../rq-compute-resources.yaml | 11 + .../security-context-2.yaml | 12 + .../security-context-3.yaml | 11 + .../security-context-4.yaml | 11 + .../security-context.yaml | 17 + .../task-pv-claim.yaml | 11 + .../configure-pod-container/task-pv-pod.yaml | 22 + .../task-pv-volume.yaml | 14 + .../tcp-liveness-readiness.yaml | 22 + .../deployment-patch-demo.yaml | 14 + .../run-application/deployment-scale.yaml | 16 + .../run-application/deployment-update.yaml | 16 + cn/docs/tasks/run-application/deployment.yaml | 18 + cn/docs/tasks/run-application/gce-volume.yaml | 12 + .../horizontal-pod-autoscale.md | 153 +++ .../run-application/mysql-configmap.yaml | 16 + .../run-application/mysql-deployment.yaml | 52 + .../tasks/run-application/mysql-services.yaml | 30 + .../run-application/mysql-statefulset.yaml | 164 +++ .../tasks/tls/managing-tls-in-a-cluster.md | 205 ++++ 110 files changed, 5484 insertions(+) create mode 100644 cn/docs/admin/daemon.yaml create mode 100644 cn/docs/admin/kubelet-authentication-authorization.md create mode 100644 cn/docs/admin/kubelet-tls-bootstrapping.md create mode 100644 cn/docs/concepts/configuration/commands.yaml create mode 100644 cn/docs/concepts/configuration/overview.md create mode 100644 cn/docs/concepts/configuration/pod-with-node-affinity.yaml create mode 100644 cn/docs/concepts/configuration/pod-with-pod-affinity.yaml create mode 100644 cn/docs/concepts/configuration/pod.yaml create mode 100644 cn/docs/concepts/services-networking/curlpod.yaml create mode 100644 cn/docs/concepts/services-networking/hostaliases-pod.yaml create mode 100644 cn/docs/concepts/services-networking/ingress.md create mode 100644 cn/docs/concepts/services-networking/ingress.yaml create mode 100644 cn/docs/concepts/services-networking/nginx-secure-app.yaml create mode 100644 cn/docs/concepts/services-networking/nginx-svc.yaml create mode 100644 cn/docs/concepts/services-networking/run-my-nginx.yaml create mode 100644 cn/docs/concepts/workloads/controllers/cronjob.yaml create mode 100644 cn/docs/concepts/workloads/controllers/daemonset.yaml create mode 100644 cn/docs/concepts/workloads/controllers/deployment.md create mode 100644 cn/docs/concepts/workloads/controllers/frontend.yaml create mode 100644 cn/docs/concepts/workloads/controllers/hpa-rs.yaml create mode 100644 cn/docs/concepts/workloads/controllers/job.yaml create mode 100644 cn/docs/concepts/workloads/controllers/my-repset.yaml create mode 100644 cn/docs/concepts/workloads/controllers/nginx-deployment.yaml create mode 100644 cn/docs/concepts/workloads/controllers/petset.yaml create mode 100644 cn/docs/concepts/workloads/controllers/replication.yaml create mode 100644 cn/docs/concepts/workloads/controllers/statefulset.md create mode 100644 cn/docs/tasks/access-application-cluster/access-cluster.md create mode 100644 cn/docs/tasks/access-application-cluster/frontend.yaml create mode 100644 cn/docs/tasks/access-application-cluster/hello-service.yaml create mode 100644 cn/docs/tasks/access-application-cluster/hello.yaml create mode 100644 cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md create mode 100644 cn/docs/tasks/access-application-cluster/redis-master.yaml create mode 100644 cn/docs/tasks/access-application-cluster/service-access-application-cluster.md create mode 100644 cn/docs/tasks/access-application-cluster/two-container-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-constraints-pod-4.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-constraints-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-constraints.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-defaults-pod-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-defaults-pod-3.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-defaults-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/cpu-defaults.yaml create mode 100644 cn/docs/tasks/administer-cluster/dns-horizontal-autoscaler.yaml create mode 100644 cn/docs/tasks/administer-cluster/ip-masq-agent.md create mode 100644 cn/docs/tasks/administer-cluster/memory-constraints-pod-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-constraints-pod-3.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-constraints-pod-4.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-constraints-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-constraints.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-defaults-pod-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-defaults-pod-3.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-defaults-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/memory-defaults.yaml create mode 100644 cn/docs/tasks/administer-cluster/my-scheduler.yaml create mode 100644 cn/docs/tasks/administer-cluster/pod1.yaml create mode 100644 cn/docs/tasks/administer-cluster/pod2.yaml create mode 100644 cn/docs/tasks/administer-cluster/pod3.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-mem-cpu-pod-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-mem-cpu-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-mem-cpu.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-objects-pvc-2.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-objects-pvc.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-objects.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-pod-deployment.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-pod.yaml create mode 100644 cn/docs/tasks/administer-cluster/quota-pvc-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/configmap.md create mode 100644 cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md create mode 100644 cn/docs/tasks/configure-pod-container/configure-service-account.md create mode 100644 cn/docs/tasks/configure-pod-container/cpu-request-limit-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/cpu-request-limit.yaml create mode 100644 cn/docs/tasks/configure-pod-container/exec-liveness.yaml create mode 100644 cn/docs/tasks/configure-pod-container/http-liveness.yaml create mode 100644 cn/docs/tasks/configure-pod-container/init-containers.yaml create mode 100644 cn/docs/tasks/configure-pod-container/lifecycle-events.yaml create mode 100644 cn/docs/tasks/configure-pod-container/mem-limit-range.yaml create mode 100644 cn/docs/tasks/configure-pod-container/memory-request-limit-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/memory-request-limit-3.yaml create mode 100644 cn/docs/tasks/configure-pod-container/memory-request-limit.yaml create mode 100644 cn/docs/tasks/configure-pod-container/oir-pod-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/oir-pod.yaml create mode 100644 cn/docs/tasks/configure-pod-container/pod-redis.yaml create mode 100644 cn/docs/tasks/configure-pod-container/pod.yaml create mode 100644 cn/docs/tasks/configure-pod-container/private-reg-pod.yaml create mode 100644 cn/docs/tasks/configure-pod-container/projected-volume.yaml create mode 100644 cn/docs/tasks/configure-pod-container/qos-pod-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/qos-pod-3.yaml create mode 100644 cn/docs/tasks/configure-pod-container/qos-pod-4.yaml create mode 100644 cn/docs/tasks/configure-pod-container/qos-pod.yaml create mode 100644 cn/docs/tasks/configure-pod-container/rq-compute-resources.yaml create mode 100644 cn/docs/tasks/configure-pod-container/security-context-2.yaml create mode 100644 cn/docs/tasks/configure-pod-container/security-context-3.yaml create mode 100644 cn/docs/tasks/configure-pod-container/security-context-4.yaml create mode 100644 cn/docs/tasks/configure-pod-container/security-context.yaml create mode 100644 cn/docs/tasks/configure-pod-container/task-pv-claim.yaml create mode 100644 cn/docs/tasks/configure-pod-container/task-pv-pod.yaml create mode 100644 cn/docs/tasks/configure-pod-container/task-pv-volume.yaml create mode 100644 cn/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml create mode 100644 cn/docs/tasks/run-application/deployment-patch-demo.yaml create mode 100644 cn/docs/tasks/run-application/deployment-scale.yaml create mode 100644 cn/docs/tasks/run-application/deployment-update.yaml create mode 100644 cn/docs/tasks/run-application/deployment.yaml create mode 100644 cn/docs/tasks/run-application/gce-volume.yaml create mode 100644 cn/docs/tasks/run-application/horizontal-pod-autoscale.md create mode 100644 cn/docs/tasks/run-application/mysql-configmap.yaml create mode 100644 cn/docs/tasks/run-application/mysql-deployment.yaml create mode 100644 cn/docs/tasks/run-application/mysql-services.yaml create mode 100644 cn/docs/tasks/run-application/mysql-statefulset.yaml create mode 100644 cn/docs/tasks/tls/managing-tls-in-a-cluster.md diff --git a/cn/docs/admin/daemon.yaml b/cn/docs/admin/daemon.yaml new file mode 100644 index 0000000000..c5cd14a592 --- /dev/null +++ b/cn/docs/admin/daemon.yaml @@ -0,0 +1,18 @@ +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: prometheus-node-exporter +spec: + template: + metadata: + name: prometheus-node-exporter + labels: + daemon: prom-node-exp + spec: + containers: + - name: c + image: prom/prometheus + ports: + - containerPort: 9090 + hostPort: 9090 + name: serverport diff --git a/cn/docs/admin/kubelet-authentication-authorization.md b/cn/docs/admin/kubelet-authentication-authorization.md new file mode 100644 index 0000000000..6d26b1c670 --- /dev/null +++ b/cn/docs/admin/kubelet-authentication-authorization.md @@ -0,0 +1,87 @@ +--- +approvers: +- liggitt +title: Kubelet authentication/authorization +--- + +* TOC +{:toc} + +## Overview + +A kubelet's HTTPS endpoint exposes APIs which give access to data of varying sensitivity, +and allow you to perform operations with varying levels of power on the node and within containers. + +This document describes how to authenticate and authorize access to the kubelet's HTTPS endpoint. + +## Kubelet authentication + +By default, requests to the kubelet's HTTPS endpoint that are not rejected by other configured +authentication methods are treated as anonymous requests, and given a username of `system:anonymous` +and a group of `system:unauthenticated`. + +To disable anonymous access and send `401 Unauthorized` responses to unauthenticated requests: + +* start the kubelet with the `--anonymous-auth=false` flag + +To enable X509 client certificate authentication to the kubelet's HTTPS endpoint: + +* start the kubelet with the `--client-ca-file` flag, providing a CA bundle to verify client certificates with +* start the apiserver with `--kubelet-client-certificate` and `--kubelet-client-key` flags +* see the [apiserver authentication documentation](/docs/admin/authentication/#x509-client-certs) for more details + +To enable API bearer tokens (including service account tokens) to be used to authenticate to the kubelet's HTTPS endpoint: + +* ensure the `authentication.k8s.io/v1beta1` API group is enabled in the API server +* start the kubelet with the `--authentication-token-webhook`, `--kubeconfig`, and `--require-kubeconfig` flags +* the kubelet calls the `TokenReview` API on the configured API server to determine user information from bearer tokens + +## Kubelet authorization + +Any request that is successfully authenticated (including an anonymous request) is then authorized. The default authorization mode is `AlwaysAllow`, which allows all requests. + +There are many possible reasons to subdivide access to the kubelet API: + +* anonymous auth is enabled, but anonymous users' ability to call the kubelet API should be limited +* bearer token auth is enabled, but arbitrary API users' (like service accounts) ability to call the kubelet API should be limited +* client certificate auth is enabled, but only some of the client certificates signed by the configured CA should be allowed to use the kubelet API + +To subdivide access to the kubelet API, delegate authorization to the API server: + +* ensure the `authorization.k8s.io/v1beta1` API group is enabled in the API server +* start the kubelet with the `--authorization-mode=Webhook`, `--kubeconfig`, and `--require-kubeconfig` flags +* the kubelet calls the `SubjectAccessReview` API on the configured API server to determine whether each request is authorized + +The kubelet authorizes API requests using the same [request attributes](/docs/admin/authorization/#request-attributes) approach as the apiserver. + +The verb is determined from the incoming request's HTTP verb: + +HTTP verb | request verb +----------|--------------- +POST | create +GET, HEAD | get +PUT | update +PATCH | patch +DELETE | delete + +The resource and subresource is determined from the incoming request's path: + +Kubelet API | resource | subresource +-------------|----------|------------ +/stats/\* | nodes | stats +/metrics/\* | nodes | metrics +/logs/\* | nodes | log +/spec/\* | nodes | spec +*all others* | nodes | proxy + +The namespace and API group attributes are always an empty string, and +the resource name is always the name of the kubelet's `Node` API object. + +When running in this mode, ensure the user identified by the `--kubelet-client-certificate` and `--kubelet-client-key` +flags passed to the apiserver is authorized for the following attributes: + +* verb=\*, resource=nodes, subresource=proxy +* verb=\*, resource=nodes, subresource=stats +* verb=\*, resource=nodes, subresource=log +* verb=\*, resource=nodes, subresource=spec +* verb=\*, resource=nodes, subresource=metrics diff --git a/cn/docs/admin/kubelet-tls-bootstrapping.md b/cn/docs/admin/kubelet-tls-bootstrapping.md new file mode 100644 index 0000000000..81d91d4a94 --- /dev/null +++ b/cn/docs/admin/kubelet-tls-bootstrapping.md @@ -0,0 +1,216 @@ +--- +approvers: +- ericchiang +- mikedanese +- jcbsmpsn +title: TLS bootstrapping +--- + +* TOC +{:toc} + +## Overview + +This document describes how to set up TLS client certificate bootstrapping for kubelets. +Kubernetes 1.4 introduced an API for requesting certificates from a cluster-level Certificate Authority (CA). The original intent of this API is to enable provisioning of TLS client certificates for kubelets. The proposal can be found [here](https://github.com/kubernetes/kubernetes/pull/20439) +and progress on the feature is being tracked as [feature #43](https://github.com/kubernetes/features/issues/43). + +## kube-apiserver configuration + +The API server should be configured with an [authenticator](/docs/admin/authentication/) that can authenticate tokens as a user in the `system:bootstrappers` group. + +This group will later be used in the controller-manager configuration to scope approvals in the default approval +controller. As this feature matures, you should ensure tokens are bound to a Role-Based Access Control (RBAC) policy which limits requests +(using the bootstrap token) strictly to client requests related to certificate provisioning. With RBAC in place, scoping the tokens to a group allows for great flexibility (e.g. you could disable a particular bootstrap group's access when you are done provisioning the nodes). + +While any authentication strategy can be used for the kubelet's initial bootstrap credentials, the following two authenticators are recommended for ease of provisioning. + +1. [Bootstrap Tokens](/docs/admin/bootstrap-tokens/) - __alpha__ +2. [Token authentication file](###token-authentication-file) + +Using bootstrap tokens is currently __alpha__ and will simplify the management of bootstrap token management especially in a HA scenario. + +### Token authentication file +Tokens are arbitrary but should represent at least 128 bits of entropy derived from a secure random number +generator (such as /dev/urandom on most modern systems). There are multiple ways you can generate a token. For example: + +`head -c 16 /dev/urandom | od -An -t x | tr -d ' '` + +will generate tokens that look like `02b50b05283e98dd0fd71db496ef01e8` + +The token file should look like the following example, where the first three values can be anything and the quoted group +name should be as depicted: + +``` +02b50b05283e98dd0fd71db496ef01e8,kubelet-bootstrap,10001,"system:bootstrappers" +``` + +Add the `--token-auth-file=FILENAME` flag to the kube-apiserver command (in your systemd unit file perhaps) to enable the token file. +See docs [here](/docs/admin/authentication/#static-token-file) for further details. + +### Client certificate CA bundle + +Add the `--client-ca-file=FILENAME` flag to the kube-apiserver command to enable client certificate authentication, +referencing a certificate authority bundle containing the signing certificate (e.g. `--client-ca-file=/var/lib/kubernetes/ca.pem`). + +## kube-controller-manager configuration +The API for requesting certificates adds a certificate-issuing control loop to the Kubernetes Controller Manager. This takes the form of a +[cfssl](https://blog.cloudflare.com/introducing-cfssl/) local signer using assets on disk. Currently, all certificates issued have one year validity and a default set of key usages. + +### Signing assets +You must provide a Certificate Authority in order to provide the cryptographic materials necessary to issue certificates. +This CA should be trusted by kube-apiserver for authentication with the `--client-ca-file=FILENAME` flag. The management +of the CA is beyond the scope of this document but it is recommended that you generate a dedicated CA for Kubernetes. +Both certificate and key are assumed to be PEM-encoded. + +The kube-controller-manager flags are: + +``` +--cluster-signing-cert-file="/etc/path/to/kubernetes/ca/ca.crt" --cluster-signing-key-file="/etc/path/to/kubernetes/ca/ca.key" +``` + +### Approval controller + +In 1.7 the experimental "group auto approver" controller is dropped in favor of the new `csrapproving` controller +that ships as part of [kube-controller-manager](/docs/admin/kube-controller-manager/) and is enabled by default. +The controller uses the [`SubjectAccessReview` API](/docs/admin/authorization/#checking-api-access) to determine +if a given user is authorized to request a CSR, then approves based on the authorization outcome. To prevent +conflicts with other approvers, the builtin approver doesn't explicitly deny CSRs, only ignoring unauthorized requests. + +The controller categorizes CSRs into three subresources: + +1. `nodeclient` - a request by a user for a client certificate with `O=system:nodes` and `CN=system:node:(node name)`. +2. `selfnodeclient` - a node renewing a client certificate with the same `O` and `CN`. +3. `selfnodeserver` - a node renewing a serving certificate. (ALPHA, requires feature gate) + +The checks to determine if a CSR is a `selfnodeserver` request is currently tied to the kubelet's credential rotation +implementation, an __alpha__ feature. As such, the definition of `selfnodeserver` will likely change in a future and +requires the `RotateKubeletServerCertificate` feature gate on the controller manager. The feature progress can be +tracked at [kubernetes/features#267](https://github.com/kubernetes/features/issues/267). + +``` +--feature-gates=RotateKubeletServerCertificate=true +``` + +The following RBAC `ClusterRoles` represent the `nodeclient`, `selfnodeclient`, and `selfnodeserver` capabilities. Similar roles +may be automatically created in future releases. + +```yml +# A ClusterRole which instructs the CSR approver to approve a user requesting +# node client credentials. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: approve-node-client-csr +rules: +- apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/nodeclient"] + verbs: ["create"] +--- +# A ClusterRole which instructs the CSR approver to approve a node renewing its +# own client credentials. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: approve-node-client-renewal-csr +rules: +- apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/selfnodeclient"] + verbs: ["create"] +--- +# A ClusterRole which instructs the CSR approver to approve a node requesting a +# serving cert matching its client cert. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: approve-node-server-renewal-csr +rules: +- apiGroups: ["certificates.k8s.io"] + resources: ["certificatesigningrequests/selfnodeserver"] + verbs: ["create"] +``` + +These powers can be granted to credentials, such as bootstrapping tokens. For example, to replicate the behavior +provided by the removed auto-approval flag, of approving all CSRs by a single group: + +``` +# REMOVED: This flag no longer works as of 1.7. +--insecure-experimental-approve-all-kubelet-csrs-for-group="system:bootstrappers" +``` + +An admin would create a `ClusterRoleBinding` targeting that group. + +```yml +# Approve all CSRs for the group "system:bootstrappers" +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: auto-approve-csrs-for-group +subjects: +- kind: Group + name: system:bootstrappers + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: approve-node-client-csr + apiGroup: rbac.authorization.k8s.io +``` + +To let a node renew its own credentials, an admin can construct a `ClusterRoleBinding` targeting +that node's credentials: + +```yml +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + name: node1-client-cert-renewal +subjects: +- kind: User + name: system:node:node-1 # Let "node-1" renew its client certificate. + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: approve-node-client-renewal-csr + apiGroup: rbac.authorization.k8s.io +``` + +Deleting the binding will prevent the node from renewing its client credentials, effectively +removing it from the cluster once its certificate expires. + +## kubelet configuration +To request a client certificate from kube-apiserver, the kubelet first needs a path to a kubeconfig file that contains the +bootstrap authentication token. You can use `kubectl config set-cluster`, `set-credentials`, and `set-context` to build this kubeconfig. Provide the name `kubelet-bootstrap` to `kubectl config set-credentials` and include `--token=` as follows: + +``` +kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=bootstrap.kubeconfig +``` + +When starting the kubelet, if the file specified by `--kubeconfig` does not exist, the bootstrap kubeconfig is used to request a client certificate from the API server. On approval of the certificate request and receipt back by the kubelet, a kubeconfig file referencing the generated key and obtained certificate is written to the path specified by `--kubeconfig`. The certificate and key file will be placed in the directory specified by `--cert-dir`. + +**Note:** The following flags are required to enable this bootstrapping when starting the kubelet: + +``` +--require-kubeconfig +--bootstrap-kubeconfig="/path/to/bootstrap/kubeconfig" +``` + +Additionally, in 1.7 the kubelet implements __alpha__ features for enabling rotation of both its client and/or serving certs. +These can be enabled through the respective `RotateKubeletClientCertificate` and `RotateKubeletServerCertificate` feature +flags on the kubelet, but may change in backward incompatible ways in future releases. + +``` +--feature-gates=RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true +``` + +`RotateKubeletClientCertificate` causes the kubelet to rotate its client certificates by creating new CSRs as its existing +credentials expire. `RotateKubeletServerCertificate` causes the kubelet to both request a serving certificate after +bootstrapping its client credentials and rotate the certificate. The serving cert currently does not request DNS or IP +SANs. + +## kubectl approval +The signing controller does not immediately sign all certificate requests. Instead, it waits until they have been flagged with an +"Approved" status by an appropriately-privileged user. This is intended to eventually be an automated process handled by an external +approval controller, but for the alpha version of the API it can be done manually by a cluster administrator using kubectl. +An administrator can list CSRs with `kubectl get csr` and describe one in detail with `kubectl describe csr `. Before the 1.6 release there were +[no direct approve/deny commands](https://github.com/kubernetes/kubernetes/issues/30163) so an approver had to update +the Status field directly ([rough how-to](https://github.com/gtank/csrctl)). Later versions of Kubernetes offer `kubectl certificate approve ` and `kubectl certificate deny ` commands. diff --git a/cn/docs/concepts/configuration/commands.yaml b/cn/docs/concepts/configuration/commands.yaml new file mode 100644 index 0000000000..8d58007db4 --- /dev/null +++ b/cn/docs/concepts/configuration/commands.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: command-demo + labels: + purpose: demonstrate-command +spec: + containers: + - name: command-demo-container + image: debian + command: ["printenv"] + args: ["HOSTNAME", "KUBERNETES_PORT"] diff --git a/cn/docs/concepts/configuration/overview.md b/cn/docs/concepts/configuration/overview.md new file mode 100644 index 0000000000..febbc6726f --- /dev/null +++ b/cn/docs/concepts/configuration/overview.md @@ -0,0 +1,93 @@ +--- +approvers: +- mikedanese +title: Configuration Best Practices +--- + +{% capture overview %} +This document highlights and consolidates configuration best practices that are introduced throughout the user-guide, getting-started documentation, and examples. + +This is a living document. If you think of something that is not on this list but might be useful to others, please don't hesitate to file an issue or submit a PR. +{% endcapture %} + +{% capture body %} +## General Config Tips + +- When defining configurations, specify the latest stable API version (currently v1). + +- Configuration files should be stored in version control before being pushed to the cluster. This allows quick roll-back of a configuration if needed. It also aids with cluster re-creation and restoration if necessary. + +- Write your configuration files using YAML rather than JSON. Though these formats can be used interchangeably in almost all scenarios, YAML tends to be more user-friendly. + +- Group related objects into a single file whenever it makes sense. One file is often easier to manage than several. See the [guestbook-all-in-one.yaml](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/all-in-one/guestbook-all-in-one.yaml) file as an example of this syntax. + + Note also that many `kubectl` commands can be called on a directory, so you can also call `kubectl create` on a directory of config files. See below for more details. + +- Don't specify default values unnecessarily, in order to simplify and minimize configs, and to reduce error. For example, omit the selector and labels in a `ReplicationController` if you want them to be the same as the labels in its `podTemplate`, since those fields are populated from the `podTemplate` labels by default. See the [guestbook app's](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) .yaml files for some [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/frontend-deployment.yaml) of this. + +- Put an object description in an annotation to allow better introspection. + + +## "Naked" Pods vs Replication Controllers and Jobs + +- If there is a viable alternative to naked pods (in other words: pods not bound to a [replication controller](/docs/user-guide/replication-controller)), go with the alternative. Naked pods will not be rescheduled in the event of node failure. + + Replication controllers are almost always preferable to creating pods, except for some explicit [`restartPolicy: Never`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) scenarios. A [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) object (currently in Beta) may also be appropriate. + + +## Services + +- It's typically best to create a [service](/docs/concepts/services-networking/service/) before corresponding [replication controllers](/docs/concepts/workloads/controllers/replicationcontroller/). This lets the scheduler spread the pods that comprise the service. + + You can also use this process to ensure that at least one replica works before creating lots of them: + + 1. Create a replication controller without specifying replicas (this will set replicas=1); + 2. Create a service; + 3. Then scale up the replication controller. + +- Don't use `hostPort` unless it is absolutely necessary (for example: for a node daemon). It specifies the port number to expose on the host. When you bind a Pod to a `hostPort`, there are a limited number of places to schedule a pod due to port conflicts— you can only schedule as many such Pods as there are nodes in your Kubernetes cluster. + + If you only need access to the port for debugging purposes, you can use the [kubectl proxy and apiserver proxy](/docs/tasks/access-kubernetes-api/http-proxy-access-api/) or [kubectl port-forward](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/). + You can use a [Service](/docs/concepts/services-networking/service/) object for external service access. + + If you explicitly need to expose a pod's port on the host machine, consider using a [NodePort](/docs/user-guide/services/#type-nodeport) service before resorting to `hostPort`. + +- Avoid using `hostNetwork`, for the same reasons as `hostPort`. + +- Use _headless services_ for easy service discovery when you don't need kube-proxy load balancing. See [headless services](/docs/user-guide/services/#headless-services). + +## Using Labels + +- Define and use [labels](/docs/user-guide/labels/) that identify __semantic attributes__ of your application or deployment. For example, instead of attaching a label to a set of pods to explicitly represent some service (For example, `service: myservice`), or explicitly representing the replication controller managing the pods (for example, `controller: mycontroller`), attach labels that identify semantic attributes, such as `{ app: myapp, tier: frontend, phase: test, deployment: v3 }`. This will let you select the object groups appropriate to the context— for example, a service for all "tier: frontend" pods, or all "test" phase components of app "myapp". See the [guestbook](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/guestbook/) app for an example of this approach. + + A service can be made to span multiple deployments, such as is done across [rolling updates](/docs/tasks/run-application/rolling-update-replication-controller/), by simply omitting release-specific labels from its selector, rather than updating a service's selector to match the replication controller's selector fully. + +- To facilitate rolling updates, include version info in replication controller names, for example as a suffix to the name. It is useful to set a 'version' label as well. The rolling update creates a new controller as opposed to modifying the existing controller. So, there will be issues with version-agnostic controller names. See the [documentation](/docs/tasks/run-application/rolling-update-replication-controller/) on the rolling-update command for more detail. + + Note that the [Deployment](/docs/concepts/workloads/controllers/deployment/) object obviates the need to manage replication controller 'version names'. A desired state of an object is described by a Deployment, and if changes to that spec are _applied_, the deployment controller changes the actual state to the desired state at a controlled rate. (Deployment objects are currently part of the [`extensions` API Group](/docs/concepts/overview/kubernetes-api/#api-groups).) + +- You can manipulate labels for debugging. Because Kubernetes replication controllers and services match to pods using labels, this allows you to remove a pod from being considered by a controller, or served traffic by a service, by removing the relevant selector labels. If you remove the labels of an existing pod, its controller will create a new pod to take its place. This is a useful way to debug a previously "live" pod in a quarantine environment. See the [`kubectl label`](/docs/concepts/overview/working-with-objects/labels/) command. + +## Container Images + +- The [default container image pull policy](/docs/concepts/containers/images/) is `IfNotPresent`, which causes the [Kubelet](/docs/admin/kubelet/) to not pull an image if it already exists. If you would like to always force a pull, you must specify a pull image policy of `Always` in your .yaml file (`imagePullPolicy: Always`) or specify a `:latest` tag on your image. + + That is, if you're specifying an image with other than the `:latest` tag, for example `myimage:v1`, and there is an image update to that same tag, the Kubelet won't pull the updated image. You can address this by ensuring that any updates to an image bump the image tag as well (for example, `myimage:v2`), and ensuring that your configs point to the correct version. + + **Note:** You should avoid using `:latest` tag when deploying containers in production, because this makes it hard to track which version of the image is running and hard to roll back. + +- To work only with a specific version of an image, you can specify an image with its digest (SHA256). This approach guarantees that the image will never update. For detailed information about working with image digests, see [the Docker documentation](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier). + +## Using kubectl + +- Use `kubectl create -f ` where possible. This looks for config objects in all `.yaml`, `.yml`, and `.json` files in `` and passes them to `create`. + +- Use `kubectl delete` rather than `stop`. `Delete` has a superset of the functionality of `stop`, and `stop` is deprecated. + +- Use kubectl bulk operations (via files and/or labels) for get and delete. See [label selectors](/docs/user-guide/labels/#label-selectors) and [using labels effectively](/docs/concepts/cluster-administration/manage-deployment/#using-labels-effectively). + +- Use `kubectl run` and `expose` to quickly create and expose single container Deployments. See the [quick start guide](/docs/user-guide/quick-start/) for an example. + +{% endcapture %} + +{% include templates/concept.md %} diff --git a/cn/docs/concepts/configuration/pod-with-node-affinity.yaml b/cn/docs/concepts/configuration/pod-with-node-affinity.yaml new file mode 100644 index 0000000000..7c38e19997 --- /dev/null +++ b/cn/docs/concepts/configuration/pod-with-node-affinity.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-node-affinity +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/e2e-az-name + operator: In + values: + - e2e-az1 + - e2e-az2 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + containers: + - name: with-node-affinity + image: gcr.io/google_containers/pause:2.0 \ No newline at end of file diff --git a/cn/docs/concepts/configuration/pod-with-pod-affinity.yaml b/cn/docs/concepts/configuration/pod-with-pod-affinity.yaml new file mode 100644 index 0000000000..3728537d5a --- /dev/null +++ b/cn/docs/concepts/configuration/pod-with-pod-affinity.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-pod-affinity +spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: failure-domain.beta.kubernetes.io/zone + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S2 + topologyKey: kubernetes.io/hostname + containers: + - name: with-pod-affinity + image: gcr.io/google_containers/pause:2.0 diff --git a/cn/docs/concepts/configuration/pod.yaml b/cn/docs/concepts/configuration/pod.yaml new file mode 100644 index 0000000000..134ddae2aa --- /dev/null +++ b/cn/docs/concepts/configuration/pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + nodeSelector: + disktype: ssd diff --git a/cn/docs/concepts/services-networking/curlpod.yaml b/cn/docs/concepts/services-networking/curlpod.yaml new file mode 100644 index 0000000000..0741a58e7f --- /dev/null +++ b/cn/docs/concepts/services-networking/curlpod.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: curl-deployment +spec: + replicas: 1 + template: + metadata: + labels: + app: curlpod + spec: + volumes: + - name: secret-volume + secret: + secretName: nginxsecret + containers: + - name: curlpod + command: + - sh + - -c + - while true; do sleep 1; done + image: radial/busyboxplus:curl + volumeMounts: + - mountPath: /etc/nginx/ssl + name: secret-volume diff --git a/cn/docs/concepts/services-networking/hostaliases-pod.yaml b/cn/docs/concepts/services-networking/hostaliases-pod.yaml new file mode 100644 index 0000000000..aa57b9a9e5 --- /dev/null +++ b/cn/docs/concepts/services-networking/hostaliases-pod.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Pod +metadata: + name: hostaliases-pod +spec: + hostAliases: + - ip: "127.0.0.1" + hostnames: + - "foo.local" + - "bar.local" + - ip: "10.1.2.3" + hostnames: + - "foo.remote" + - "bar.remote" + containers: + - name: cat-hosts + image: busybox + command: + - cat + args: + - "/etc/hosts" diff --git a/cn/docs/concepts/services-networking/ingress.md b/cn/docs/concepts/services-networking/ingress.md new file mode 100644 index 0000000000..f77b809e67 --- /dev/null +++ b/cn/docs/concepts/services-networking/ingress.md @@ -0,0 +1,298 @@ +--- +approvers: +- bprashanth +title: Ingress Resources +--- + +* TOC +{:toc} + +__Terminology__ + +Throughout this doc you will see a few terms that are sometimes used interchangeably elsewhere, that might cause confusion. This section attempts to clarify them. + +* Node: A single virtual or physical machine in a Kubernetes cluster. +* Cluster: A group of nodes firewalled from the internet, that are the primary compute resources managed by Kubernetes. +* Edge router: A router that enforces the firewall policy for your cluster. This could be a gateway managed by a cloud provider or a physical piece of hardware. +* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the [Kubernetes networking model](/docs/concepts/cluster-administration/networking/). Examples of a Cluster network include Overlays such as [flannel](https://github.com/coreos/flannel#flannel) or SDNs such as [OVS](/docs/admin/ovs-networking/). +* Service: A Kubernetes [Service](/docs/concepts/services-networking/service/) that identifies a set of pods using label selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network. + +## What is Ingress? + +Typically, services and pods have IPs only routable by the cluster network. All traffic that ends up at an edge router is either dropped or forwarded elsewhere. Conceptually, this might look like: + +``` + internet + | + ------------ + [ Services ] +``` + +An Ingress is a collection of rules that allow inbound connections to reach the cluster services. + +``` + internet + | + [ Ingress ] + --|-----|-- + [ Services ] +``` + +It can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, offer name based virtual hosting etc. Users request ingress by POSTing the Ingress resource to the API server. An [Ingress controller](#ingress-controllers) is responsible for fulfilling the Ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic in an HA manner. + +## Prerequisites + +Before you start using the Ingress resource, there are a few things you should understand. The Ingress is a beta resource, not available in any Kubernetes release prior to 1.1. You need an Ingress controller to satisfy an Ingress, simply creating the resource will have no effect. + +GCE/GKE deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://git.k8s.io/ingress/controllers/nginx#running-multiple-ingress-controllers) and [here](https://git.k8s.io/ingress/controllers/gce/BETA_LIMITATIONS.md#disabling-glbc). + +Make sure you review the [beta limitations](https://git.k8s.io/ingress/controllers/gce/BETA_LIMITATIONS.md) of this controller. In environments other than GCE/GKE, you need to [deploy a controller](https://git.k8s.io/ingress/controllers) as a pod. + +## The Ingress Resource + +A minimal Ingress might look like: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test-ingress + annotations: + ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - http: + paths: + - path: /testpath + backend: + serviceName: test + servicePort: 80 +``` + +*POSTing this to the API server will have no effect if you have not configured an [Ingress controller](#ingress-controllers).* + +__Lines 1-6__: As with all other Kubernetes config, an Ingress needs `apiVersion`, `kind`, and `metadata` fields. For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/) and [ingress configuration rewrite](https://github.com/kubernetes/ingress/blob/master/controllers/nginx/configuration.md#rewrite). + +__Lines 7-9__: Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Currently the Ingress resource only supports http rules. + +__Lines 10-11__: Each http rule contains the following information: A host (e.g.: foo.bar.com, defaults to * in this example), a list of paths (e.g.: /testpath) each of which has an associated backend (test:80). Both the host and path must match the content of an incoming request before the loadbalancer directs traffic to the backend. + +__Lines 12-14__: A backend is a service:port combination as described in the [services doc](/docs/concepts/services-networking/service/). Ingress traffic is typically sent directly to the endpoints matching a backend. + +__Global Parameters__: For the sake of simplicity the example Ingress has no global parameters, see the [API reference](https://releases.k8s.io/{{page.githubbranch}}/staging/src/k8s.io/api/extensions/v1beta1/types.go) for a full definition of the resource. One can specify a global default backend in the absence of which requests that don't match a path in the spec are sent to the default backend of the Ingress controller. + +## Ingress controllers + +In order for the Ingress resource to work, the cluster must have an Ingress controller running. This is unlike other types of controllers, which typically run as part of the `kube-controller-manager` binary, and which are typically started automatically as part of cluster creation. You need to choose the ingress controller implementation that is the best fit for your cluster, or implement one. Examples and instructions can be found [here](https://git.k8s.io/ingress/controllers). + +## Before you begin + +The following document describes a set of cross platform features exposed through the Ingress resource. Ideally, all Ingress controllers should fulfill this specification, but we're not there yet. The docs for the GCE and nginx controllers are [here](https://git.k8s.io/ingress/controllers/gce/README.md) and [here](https://git.k8s.io/ingress/controllers/nginx/README.md) respectively. **Make sure you review controller specific docs so you understand the caveats of each one**. + +## Types of Ingress + +### Single Service Ingress + +There are existing Kubernetes concepts that allow you to expose a single service (see [alternatives](#alternatives)), however you can do so through an Ingress as well, by specifying a *default backend* with no rules. + +{% include code.html language="yaml" file="ingress.yaml" ghlink="/docs/concepts/services-networking/ingress.yaml" %} + +If you create it using `kubectl create -f` you should see: + +```shell +$ kubectl get ing +NAME RULE BACKEND ADDRESS +test-ingress - testsvc:80 107.178.254.228 +``` + +Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy this Ingress. The `RULE` column shows that all traffic send to the IP is directed to the Kubernetes Service listed under `BACKEND`. + +### Simple fanout + +As described previously, pods within kubernetes have IPs only visible on the cluster network, so we need something at the edge accepting ingress traffic and proxying it to the right endpoints. This component is usually a highly available loadbalancer. An Ingress allows you to keep the number of loadbalancers down to a minimum, for example, a setup like: + +```shell +foo.bar.com -> 178.91.123.132 -> / foo s1:80 + / bar s2:80 +``` + +would require an Ingress such as: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test + annotations: + ingress.kubernetes.io/rewrite-target: / +spec: + rules: + - host: foo.bar.com + http: + paths: + - path: /foo + backend: + serviceName: s1 + servicePort: 80 + - path: /bar + backend: + serviceName: s2 + servicePort: 80 +``` + +When you create the Ingress with `kubectl create -f`: + +```shell +$ kubectl get ing +NAME RULE BACKEND ADDRESS +test - + foo.bar.com + /foo s1:80 + /bar s2:80 +``` +The Ingress controller will provision an implementation specific loadbalancer that satisfies the Ingress, as long as the services (s1, s2) exist. When it has done so, you will see the address of the loadbalancer under the last column of the Ingress. + +### Name based virtual hosting + +Name-based virtual hosts use multiple host names for the same IP address. + +``` +foo.bar.com --| |-> foo.bar.com s1:80 + | 178.91.123.132 | +bar.foo.com --| |-> bar.foo.com s2:80 +``` + +The following Ingress tells the backing loadbalancer to route requests based on the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4). + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test +spec: + rules: + - host: foo.bar.com + http: + paths: + - backend: + serviceName: s1 + servicePort: 80 + - host: bar.foo.com + http: + paths: + - backend: + serviceName: s2 + servicePort: 80 +``` + +__Default Backends__: An Ingress with no rules, like the one shown in the previous section, sends all traffic to a single default backend. You can use the same technique to tell a loadbalancer where to find your website's 404 page, by specifying a set of rules *and* a default backend. Traffic is routed to your default backend if none of the Hosts in your Ingress match the Host in the request header, and/or none of the paths match the URL of the request. + +### TLS + +You can secure an Ingress by specifying a [secret](/docs/user-guide/secrets) that contains a TLS private key and certificate. Currently the Ingress only supports a single TLS port, 443, and assumes TLS termination. If the TLS configuration section in an Ingress specifies different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret must contain keys named `tls.crt` and `tls.key` that contain the certificate and private key to use for TLS, e.g.: + +```yaml +apiVersion: v1 +data: + tls.crt: base64 encoded cert + tls.key: base64 encoded key +kind: Secret +metadata: + name: testsecret + namespace: default +type: Opaque +``` + +Referencing this secret in an Ingress will tell the Ingress controller to secure the channel from the client to the loadbalancer using TLS: + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: no-rules-map +spec: + tls: + - secretName: testsecret + backend: + serviceName: s1 + servicePort: 80 +``` + +Note that there is a gap between TLS features supported by various Ingress controllers. Please refer to documentation on [nginx](https://git.k8s.io/ingress/controllers/nginx/README.md#https), [GCE](https://git.k8s.io/ingress/controllers/gce/README.md#tls), or any other platform specific Ingress controller to understand how TLS works in your environment. + +### Loadbalancing + +An Ingress controller is bootstrapped with some loadbalancing policy settings that it applies to all Ingress, such as the loadbalancing algorithm, backend weight scheme etc. More advanced loadbalancing concepts (e.g.: persistent sessions, dynamic weights) are not yet exposed through the Ingress. You can still get these features through the [service loadbalancer](https://git.k8s.io/contrib/service-loadbalancer). With time, we plan to distill loadbalancing patterns that are applicable cross platform into the Ingress resource. + +It's also worth noting that even though health checks are not exposed directly through the Ingress, there exist parallel concepts in Kubernetes such as [readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/) which allow you to achieve the same end result. Please review the controller specific docs to see how they handle health checks ([nginx](https://git.k8s.io/ingress/controllers/nginx/README.md), [GCE](https://git.k8s.io/ingress/controllers/gce/README.md#health-checks)). + +## Updating an Ingress + +Say you'd like to add a new Host to an existing Ingress, you can update it by editing the resource: + +```shell +$ kubectl get ing +NAME RULE BACKEND ADDRESS +test - 178.91.123.132 + foo.bar.com + /foo s1:80 +$ kubectl edit ing test +``` + +This should pop up an editor with the existing yaml, modify it to include the new Host. + +```yaml +spec: + rules: + - host: foo.bar.com + http: + paths: + - backend: + serviceName: s1 + servicePort: 80 + path: /foo + - host: bar.baz.com + http: + paths: + - backend: + serviceName: s2 + servicePort: 80 + path: /foo +.. +``` + +saving it will update the resource in the API server, which should tell the Ingress controller to reconfigure the loadbalancer. + +```shell +$ kubectl get ing +NAME RULE BACKEND ADDRESS +test - 178.91.123.132 + foo.bar.com + /foo s1:80 + bar.baz.com + /foo s2:80 +``` + +You can achieve the same by invoking `kubectl replace -f` on a modified Ingress yaml file. + +## Failing across availability zones + +Techniques for spreading traffic across failure domains differs between cloud providers. Please check the documentation of the relevant Ingress controller for details. Please refer to the federation [doc](/docs/concepts/cluster-administration/federation/) for details on deploying Ingress in a federated cluster. + +## Future Work + +* Various modes of HTTPS/TLS support (e.g.: SNI, re-encryption) +* Requesting an IP or Hostname via claims +* Combining L4 and L7 Ingress +* More Ingress controllers + +Please track the [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827) for more details on the evolution of the resource, and the [Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the evolution of various Ingress controllers. + +## Alternatives + +You can expose a Service in multiple ways that don't directly involve the Ingress resource: + +* Use [Service.Type=LoadBalancer](/docs/user-guide/services/#type-loadbalancer) +* Use [Service.Type=NodePort](/docs/user-guide/services/#type-nodeport) +* Use a [Port Proxy](https://git.k8s.io/contrib/for-demos/proxy-to-service) +* Deploy the [Service loadbalancer](https://git.k8s.io/contrib/service-loadbalancer). This allows you to share a single IP among multiple Services and achieve more advanced loadbalancing through Service Annotations. diff --git a/cn/docs/concepts/services-networking/ingress.yaml b/cn/docs/concepts/services-networking/ingress.yaml new file mode 100644 index 0000000000..163c1d5b9d --- /dev/null +++ b/cn/docs/concepts/services-networking/ingress.yaml @@ -0,0 +1,9 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: test-ingress +spec: + backend: + serviceName: testsvc + servicePort: 80 + diff --git a/cn/docs/concepts/services-networking/nginx-secure-app.yaml b/cn/docs/concepts/services-networking/nginx-secure-app.yaml new file mode 100644 index 0000000000..9e4a16791e --- /dev/null +++ b/cn/docs/concepts/services-networking/nginx-secure-app.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-nginx + labels: + run: my-nginx +spec: + type: NodePort + ports: + - port: 8080 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + protocol: TCP + name: https + selector: + run: my-nginx +--- +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: my-nginx +spec: + replicas: 1 + template: + metadata: + labels: + run: my-nginx + spec: + volumes: + - name: secret-volume + secret: + secretName: nginxsecret + containers: + - name: nginxhttps + image: bprashanth/nginxhttps:1.0 + ports: + - containerPort: 443 + - containerPort: 80 + volumeMounts: + - mountPath: /etc/nginx/ssl + name: secret-volume diff --git a/cn/docs/concepts/services-networking/nginx-svc.yaml b/cn/docs/concepts/services-networking/nginx-svc.yaml new file mode 100644 index 0000000000..12fcd5d0bf --- /dev/null +++ b/cn/docs/concepts/services-networking/nginx-svc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: my-nginx + labels: + run: my-nginx +spec: + ports: + - port: 80 + protocol: TCP + selector: + run: my-nginx diff --git a/cn/docs/concepts/services-networking/run-my-nginx.yaml b/cn/docs/concepts/services-networking/run-my-nginx.yaml new file mode 100644 index 0000000000..b3d8e336cd --- /dev/null +++ b/cn/docs/concepts/services-networking/run-my-nginx.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: my-nginx +spec: + replicas: 2 + template: + metadata: + labels: + run: my-nginx + spec: + containers: + - name: my-nginx + image: nginx + ports: + - containerPort: 80 + diff --git a/cn/docs/concepts/workloads/controllers/cronjob.yaml b/cn/docs/concepts/workloads/controllers/cronjob.yaml new file mode 100644 index 0000000000..cdb1c469a1 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/cronjob.yaml @@ -0,0 +1,18 @@ +apiVersion: batch/v2alpha1 +kind: CronJob +metadata: + name: hello +spec: + schedule: "*/1 * * * *" + jobTemplate: + spec: + template: + spec: + containers: + - name: hello + image: busybox + args: + - /bin/sh + - -c + - date; echo Hello from the Kubernetes cluster + restartPolicy: OnFailure diff --git a/cn/docs/concepts/workloads/controllers/daemonset.yaml b/cn/docs/concepts/workloads/controllers/daemonset.yaml new file mode 100644 index 0000000000..e01d14d800 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/daemonset.yaml @@ -0,0 +1,36 @@ +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: fluentd-elasticsearch + namespace: kube-system + labels: + k8s-app: fluentd-logging +spec: + template: + metadata: + labels: + name: fluentd-elasticsearch + spec: + containers: + - name: fluentd-elasticsearch + image: gcr.io/google-containers/fluentd-elasticsearch:1.20 + resources: + limits: + memory: 200Mi + requests: + cpu: 100m + memory: 200Mi + volumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + terminationGracePeriodSeconds: 30 + volumes: + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers \ No newline at end of file diff --git a/cn/docs/concepts/workloads/controllers/deployment.md b/cn/docs/concepts/workloads/controllers/deployment.md new file mode 100644 index 0000000000..acc21c984e --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/deployment.md @@ -0,0 +1,935 @@ +--- +approvers: +- bgrant0607 +- janetkuo +title: Deployments +--- + +{% capture overview %} + +A _Deployment_ controller provides declarative updates for [Pods](/docs/concepts/workloads/pods/pod/) and +[ReplicaSets](/docs/concepts/workloads/controllers/replicaset/). + +You describe a _desired state_ in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments. + +**Note:** You should not manage ReplicaSets owned by a Deployment. All the use cases should be covered by manipulating the Deployment object. Consider opening an issue in the main Kubernetes repository if your use case is not covered below. +{: .note} + +{% endcapture %} + + +{% capture body %} + +## Use Case + +The following are typical use cases for Deployments: + +* [Create a Deployment to rollout a ReplicaSet](#creating-a-deployment). The ReplicaSet creates Pods in the background. Check the status of the rollout to see if it succeeds or not. +* [Declare the new state of the Pods](#updating-a-deployment) by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created and the Deployment manages moving the Pods from the old ReplicaSet to the new one at a controlled rate. Each new ReplicaSet updates the revision of the Deployment. +* [Rollback to an earlier Deployment revision](#rolling-back-a-deployment) if the current state of the Deployment is not stable. Each rollback updates the revision of the Deployment. +* [Scale up the Deployment to facilitate more load.](#scaling-a-deployment) +* [Pause the Deployment](#pausing-and-resuming-a-deployment) to apply multiple fixes to its PodTemplateSpec and then resume it to start a new rollout. +* [Use the status of the Deployment](#deployment-status) as an indicator that a rollout has stuck +* [Clean up older ReplicaSets](#clean-up-policy) that you don't need anymore + + +## Creating a Deployment + +Here is an example Deployment. It creates a ReplicaSet to bring up three nginx Pods. + +{% include code.html language="yaml" file="nginx-deployment.yaml" ghlink="/docs/concepts/workloads/controllers/nginx-deployment.yaml" %} + +Run the example by downloading the example file and then running this command: + +```shell +$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record +deployment "nginx-deployment" created +``` + +Setting the kubectl flag `--record` to `true` allows you to record current command in the annotations of +the resources being created or updated. It is useful for future introspection: for example, to see the +commands executed in each Deployment revision. + +Then running `get` immediately will give: + +```shell +$ kubectl get deployments +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 3 0 0 0 1s +``` + +This indicates that the Deployment's number of desired replicas is 3 (according to deployment's `.spec.replicas`), +the number of current replicas (`.status.replicas`) is 0, the number of up-to-date replicas (`.status.updatedReplicas`) +is 0, and the number of available replicas (`.status.availableReplicas`) is also 0. + +To see the Deployment rollout status, run: + +```shell +$ kubectl rollout status deployment/nginx-deployment +Waiting for rollout to finish: 2 out of 3 new replicas have been updated... +deployment "nginx-deployment" successfully rolled out +``` + +Running the `get` again a few seconds later should give: + +```shell +$ kubectl get deployments +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 3 3 3 3 18s +``` + +This indicates that the Deployment has created all three replicas, and all replicas are up-to-date (contains the +latest pod template) and available (pod status is ready for at least Deployment's `.spec.minReadySeconds`). Running +`kubectl get rs` and `kubectl get pods` will show the ReplicaSet (RS) and Pods created. + +```shell +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-deployment-2035384211 3 3 3 18s +``` + +You may notice that the name of the ReplicaSet is always `-`. + +```shell +$ kubectl get pods --show-labels +NAME READY STATUS RESTARTS AGE LABELS +nginx-deployment-2035384211-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 +nginx-deployment-2035384211-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 +nginx-deployment-2035384211-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=2035384211 +``` + +The created ReplicaSet ensures that there are three nginx Pods at all times. + +**Note:** You must specify an appropriate selector and pod template labels in a Deployment (in this case, +`app = nginx`). That is, don't overlap with other controllers (including other Deployments, ReplicaSets, +StatefulSets, etc.). Kubernetes doesn't stop you from overlapping, and if multiple +controllers have overlapping selectors, those controllers may fight with each other and won't behave +correctly. +{: .note} + +### Pod-template-hash label + +**Note:** Do not change this label. +{: .note} + +Note the pod-template-hash label in the example output in the pod labels above. This label is added by the +Deployment controller to every ReplicaSet that a Deployment creates or adopts. Its purpose is to make sure that child +ReplicaSets of a Deployment do not overlap. It is computed by hashing the PodTemplate of the ReplicaSet +and using the resulting hash as the label value that will be added in the ReplicaSet selector, pod template labels, +and in any existing Pods that the ReplicaSet may have. + +## Updating a Deployment + +**Note:** A Deployment's rollout is triggered if and only if the Deployment's pod template (that is, `.spec.template`) +is changed, for example if the labels or container images of the template are updated. Other updates, such as scaling the Deployment, do not trigger a rollout. +{: .note} + +Suppose that we now want to update the nginx Pods to use the `nginx:1.9.1` image +instead of the `nginx:1.7.9` image. + +```shell +$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 +deployment "nginx-deployment" image updated +``` + +Alternatively, we can `edit` the Deployment and change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`: + +```shell +$ kubectl edit deployment/nginx-deployment +deployment "nginx-deployment" edited +``` + +To see the rollout status, run: + +```shell +$ kubectl rollout status deployment/nginx-deployment +Waiting for rollout to finish: 2 out of 3 new replicas have been updated... +deployment "nginx-deployment" successfully rolled out +``` + +After the rollout succeeds, you may want to `get` the Deployment: + +```shell +$ kubectl get deployments +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 3 3 3 3 36s +``` + +The number of up-to-date replicas indicates that the Deployment has updated the replicas to the latest configuration. +The current replicas indicates the total replicas this Deployment manages, and the available replicas indicates the +number of current replicas that are available. + +We can run `kubectl get rs` to see that the Deployment updated the Pods by creating a new ReplicaSet and scaling it +up to 3 replicas, as well as scaling down the old ReplicaSet to 0 replicas. + +```shell +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 3 3 3 6s +nginx-deployment-2035384211 0 0 0 36s +``` + +Running `get pods` should now show only the new Pods: + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +nginx-deployment-1564180365-khku8 1/1 Running 0 14s +nginx-deployment-1564180365-nacti 1/1 Running 0 14s +nginx-deployment-1564180365-z9gth 1/1 Running 0 14s +``` + +Next time we want to update these Pods, we only need to update the Deployment's pod template again. + +Deployment can ensure that only a certain number of Pods may be down while they are being updated. By +default, it ensures that at least 1 less than the desired number of Pods are up (1 max unavailable). + +Deployment can also ensure that only a certain number of Pods may be created above the desired number of +Pods. By default, it ensures that at most 1 more than the desired number of Pods are up (1 max surge). + +In a future version of Kubernetes, the defaults will change from 1-1 to 25%-25%. + +For example, if you look at the above Deployment closely, you will see that it first created a new Pod, +then deleted some old Pods and created new ones. It does not kill old Pods until a sufficient number of +new Pods have come up, and does not create new Pods until a sufficient number of old Pods have been killed. +It makes sure that number of available Pods is at least 2 and the number of total Pods is at most 4. + +```shell +$ kubectl describe deployments +Name: nginx-deployment +Namespace: default +CreationTimestamp: Tue, 15 Mar 2016 12:01:06 -0700 +Labels: app=nginx +Selector: app=nginx +Replicas: 3 updated | 3 total | 3 available | 0 unavailable +StrategyType: RollingUpdate +MinReadySeconds: 0 +RollingUpdateStrategy: 1 max unavailable, 1 max surge +OldReplicaSets: +NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 36s 36s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 + 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 + 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 + 23s 23s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 + 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 + 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 +``` + +Here we see that when we first created the Deployment, it created a ReplicaSet (nginx-deployment-2035384211) +and scaled it up to 3 replicas directly. When we updated the Deployment, it created a new ReplicaSet +(nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old ReplicaSet to 2, so that at +least 2 Pods were available and at most 4 Pods were created at all times. It then continued scaling up and down +the new and the old ReplicaSet, with the same rolling update strategy. Finally, we'll have 3 available replicas +in the new ReplicaSet, and the old ReplicaSet is scaled down to 0. + +### Rollover (aka multiple updates in-flight) + +Each time a new deployment object is observed by the deployment controller, a ReplicaSet is created to bring up +the desired Pods if there is no existing ReplicaSet doing so. Existing ReplicaSet controlling Pods whose labels +match `.spec.selector` but whose template does not match `.spec.template` are scaled down. Eventually, the new +ReplicaSet will be scaled to `.spec.replicas` and all old ReplicaSets will be scaled to 0. + +If you update a Deployment while an existing rollout is in progress, the Deployment will create a new ReplicaSet +as per the update and start scaling that up, and will roll over the ReplicaSet that it was scaling up previously + -- it will add it to its list of old ReplicaSets and will start scaling it down. + +For example, suppose you create a Deployment to create 5 replicas of `nginx:1.7.9`, +but then updates the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3 +replicas of `nginx:1.7.9` had been created. In that case, Deployment will immediately start +killing the 3 `nginx:1.7.9` Pods that it had created, and will start creating +`nginx:1.9.1` Pods. It will not wait for 5 replicas of `nginx:1.7.9` to be created +before changing course. + +### Label selector updates + +It is generally discouraged to make label selector updates and it is suggested to plan your selectors up front. +In any case, if you need to perform a label selector update, exercise great caution and make sure you have grasped +all of the implications. + +* Selector additions require the pod template labels in the Deployment spec to be updated with the new label too, +otherwise a validation error is returned. This change is a non-overlapping one, meaning that the new selector does +not select ReplicaSets and Pods created with the old selector, resulting in orphaning all old ReplicaSets and +creating a new ReplicaSet. +* Selector updates -- that is, changing the existing value in a selector key -- result in the same behavior as additions. +* Selector removals -- that is, removing an existing key from the Deployment selector -- do not require any changes in the +pod template labels. No existing ReplicaSet is orphaned, and a new ReplicaSet is not created, but note that the +removed label still exists in any existing Pods and ReplicaSets. + +## Rolling Back a Deployment + +Sometimes you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping. +By default, all of the Deployment's rollout history is kept in the system so that you can rollback anytime you want +(you can change that by modifying revision history limit). + +**Note:** A Deployment's revision is created when a Deployment's rollout is triggered. This means that the +new revision is created if and only if the Deployment's pod template (`.spec.template`) is changed, +for example if you update the labels or container images of the template. Other updates, such as scaling the Deployment, +do not create a Deployment revision, so that we can facilitate simultaneous manual- or auto-scaling. +This means that when you roll back to an earlier revision, only the Deployment's pod template part is +rolled back. +{: .note} + +Suppose that we made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`: + +```shell +$ kubectl set image deployment/nginx-deployment nginx=nginx:1.91 +deployment "nginx-deployment" image updated +``` + +The rollout will be stuck. + +```shell +$ kubectl rollout status deployments nginx-deployment +Waiting for rollout to finish: 2 out of 3 new replicas have been updated... +``` + +Press Ctrl-C to stop the above rollout status watch. For more information on stuck rollouts, +[read more here](#deployment-status). + +You will also see that both the number of old replicas (nginx-deployment-1564180365 and +nginx-deployment-2035384211) and new replicas (nginx-deployment-3066724191) are 2. + +```shell +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-deployment-1564180365 2 2 0 25s +nginx-deployment-2035384211 0 0 0 36s +nginx-deployment-3066724191 2 2 2 6s +``` + +Looking at the Pods created, you will see that the 2 Pods created by new ReplicaSet are stuck in an image pull loop. + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +nginx-deployment-1564180365-70iae 1/1 Running 0 25s +nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s +nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s +nginx-deployment-3066724191-eocby 0/1 ImagePullBackOff 0 6s +``` + +**Note:** The Deployment controller will stop the bad rollout automatically, and will stop scaling up the new +ReplicaSet. This depends on the rollingUpdate parameters (`maxUnavailable` specifically) that you have specified. +Kubernetes by default sets the value to 1 and spec.replicas to 1 so if you haven't cared about setting those +parameters, your Deployment can have 100% unavailability by default! This will be fixed in Kubernetes in a future +version. +{: .note} + +```shell +$ kubectl describe deployment +Name: nginx-deployment +Namespace: default +CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 +Labels: app=nginx +Selector: app=nginx +Replicas: 2 updated | 3 total | 2 available | 2 unavailable +StrategyType: RollingUpdate +MinReadySeconds: 0 +RollingUpdateStrategy: 1 max unavailable, 1 max surge +OldReplicaSets: nginx-deployment-1564180365 (2/2 replicas created) +NewReplicaSet: nginx-deployment-3066724191 (2/2 replicas created) +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 + 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 + 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 + 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 + 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 + 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 + 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1 + 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2 + 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2 +``` + +To fix this, we need to rollback to a previous revision of Deployment that is stable. + +### Checking Rollout History of a Deployment + +First, check the revisions of this deployment: + +```shell +$ kubectl rollout history deployment/nginx-deployment +deployments "nginx-deployment" +REVISION CHANGE-CAUSE +1 kubectl create -f docs/user-guide/nginx-deployment.yaml --record +2 kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 +3 kubectl set image deployment/nginx-deployment nginx=nginx:1.91 +``` + +Because we recorded the command while creating this Deployment using `--record`, we can easily see +the changes we made in each revision. + +To further see the details of each revision, run: + +```shell +$ kubectl rollout history deployment/nginx-deployment --revision=2 +deployments "nginx-deployment" revision 2 + Labels: app=nginx + pod-template-hash=1159050644 + Annotations: kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 + Containers: + nginx: + Image: nginx:1.9.1 + Port: 80/TCP + QoS Tier: + cpu: BestEffort + memory: BestEffort + Environment Variables: + No volumes. +``` + +### Rolling Back to a Previous Revision + +Now we've decided to undo the current rollout and rollback to the previous revision: + +```shell +$ kubectl rollout undo deployment/nginx-deployment +deployment "nginx-deployment" rolled back +``` + +Alternatively, you can rollback to a specific revision by specify that in `--to-revision`: + +```shell +$ kubectl rollout undo deployment/nginx-deployment --to-revision=2 +deployment "nginx-deployment" rolled back +``` + +For more details about rollout related commands, read [`kubectl rollout`](/docs/user-guide/kubectl/{{page.version}}/#rollout). + +The Deployment is now rolled back to a previous stable revision. As you can see, a `DeploymentRollback` event +for rolling back to revision 2 is generated from Deployment controller. + +```shell +$ kubectl get deployment +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 3 3 3 3 30m + +$ kubectl describe deployment +Name: nginx-deployment +Namespace: default +CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 +Labels: app=nginx +Selector: app=nginx +Replicas: 3 updated | 3 total | 3 available | 0 unavailable +StrategyType: RollingUpdate +MinReadySeconds: 0 +RollingUpdateStrategy: 1 max unavailable, 1 max surge +OldReplicaSets: +NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) +Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 30m 30m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 2 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1 + 29m 29m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-1564180365 to 2 + 2m 2m 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-3066724191 to 0 + 2m 2m 1 {deployment-controller } Normal DeploymentRollback Rolled back deployment "nginx-deployment" to revision 2 + 29m 2m 2 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 +``` + +## Scaling a Deployment + +You can scale a Deployment by using the following command: + +```shell +$ kubectl scale deployment nginx-deployment --replicas=10 +deployment "nginx-deployment" scaled +``` + +Assuming [horizontal pod autoscaling](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) is enabled +in your cluster, you can setup an autoscaler for your Deployment and choose the minimum and maximum number of +Pods you want to run based on the CPU utilization of your existing Pods. + +```shell +$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80 +deployment "nginx-deployment" autoscaled +``` + +### Proportional scaling + +RollingUpdate Deployments support running multiple versions of an application at the same time. When you +or an autoscaler scales a RollingUpdate Deployment that is in the middle of a rollout (either in progress +or paused), then the Deployment controller will balance the additional replicas in the existing active +ReplicaSets (ReplicaSets with Pods) in order to mitigate risk. This is called *proportional scaling*. + +For example, you are running a Deployment with 10 replicas, [maxSurge](#max-surge)=3, and [maxUnavailable](#max-unavailable)=2. + +```shell +$ kubectl get deploy +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 10 10 10 10 50s +``` + +You update to a new image which happens to be unresolvable from inside the cluster. + +```shell +$ kubectl set image deploy/nginx-deployment nginx=nginx:sometag +deployment "nginx-deployment" image updated +``` + +The image update starts a new rollout with ReplicaSet nginx-deployment-1989198191, but it's blocked due to the +maxUnavailable requirement that we mentioned above. + +```shell +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-deployment-1989198191 5 5 0 9s +nginx-deployment-618515232 8 8 8 1m +``` + +Then a new scaling request for the Deployment comes along. The autoscaler increments the Deployment replicas +to 15. The Deployment controller needs to decide where to add these new 5 replicas. If we weren't using +proportional scaling, all 5 of them would be added in the new ReplicaSet. With proportional scaling, we +spread the additional replicas across all ReplicaSets. Bigger proportions go to the ReplicaSets with the +most replicas and lower proportions go to ReplicaSets with less replicas. Any leftovers are added to the +ReplicaSet with the most replicas. ReplicaSets with zero replicas are not scaled up. + +In our example above, 3 replicas will be added to the old ReplicaSet and 2 replicas will be added to the +new ReplicaSet. The rollout process should eventually move all replicas to the new ReplicaSet, assuming +the new replicas become healthy. + +```shell +$ kubectl get deploy +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx-deployment 15 18 7 8 7m +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-deployment-1989198191 7 7 0 7m +nginx-deployment-618515232 11 11 11 7m +``` + +## Pausing and Resuming a Deployment + +You can pause a Deployment before triggering one or more updates and then resume it. This will allow you to +apply multiple fixes in between pausing and resuming without triggering unnecessary rollouts. + +For example, with a Deployment that was just created: + +```shell +$ kubectl get deploy +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +nginx 3 3 3 3 1m +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-2142116321 3 3 3 1m +``` + +Pause by running the following command: + +```shell +$ kubectl rollout pause deployment/nginx-deployment +deployment "nginx-deployment" paused +``` + +Then update the image of the Deployment: + +```shell +$ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1 +deployment "nginx-deployment" image updated +``` + +Notice that no new rollout started: + +```shell +$ kubectl rollout history deploy/nginx-deployment +deployments "nginx" +REVISION CHANGE-CAUSE +1 + +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-2142116321 3 3 3 2m +``` + +You can make as many updates as you wish, for example, update the resources that will be used: + +```shell +$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi +deployment "nginx" resource requirements updated +``` + +The initial state of the Deployment prior to pausing it will continue its function, but new updates to +the Deployment will not have any effect as long as the Deployment is paused. + +Eventually, resume the Deployment and observe a new ReplicaSet coming up with all the new updates: + +```shell +$ kubectl rollout resume deploy/nginx-deployment +deployment "nginx" resumed +$ kubectl get rs -w +NAME DESIRED CURRENT READY AGE +nginx-2142116321 2 2 2 2m +nginx-3926361531 2 2 0 6s +nginx-3926361531 2 2 1 18s +nginx-2142116321 1 2 2 2m +nginx-2142116321 1 2 2 2m +nginx-3926361531 3 2 1 18s +nginx-3926361531 3 2 1 18s +nginx-2142116321 1 1 1 2m +nginx-3926361531 3 3 1 18s +nginx-3926361531 3 3 2 19s +nginx-2142116321 0 1 1 2m +nginx-2142116321 0 1 1 2m +nginx-2142116321 0 0 0 2m +nginx-3926361531 3 3 3 20s +^C +$ kubectl get rs +NAME DESIRED CURRENT READY AGE +nginx-2142116321 0 0 0 2m +nginx-3926361531 3 3 3 28s +``` + +**Note:** You cannot rollback a paused Deployment until you resume it. +{: .note} + +## Deployment status + +A Deployment enters various states during its lifecycle. It can be [progressing](#progressing-deployment) while +rolling out a new ReplicaSet, it can be [complete](#complete-deployment), or it can [fail to progress](#failed-deployment). + +### Progressing Deployment + +Kubernetes marks a Deployment as _progressing_ when one of the following tasks is performed: + +* The Deployment creates a new ReplicaSet. +* The Deployment is scaling up its newest ReplicaSet. +* The Deployment is scaling down its older ReplicaSet(s). +* New Pods become ready or available (ready for at least [MinReadySeconds](#min-ready-seconds)). + +You can monitor the progress for a Deployment by using `kubectl rollout status`. + +### Complete Deployment + +Kubernetes marks a Deployment as _complete_ when it has the following characteristics: + +* All of the replicas associated with the Deployment have been updated to the latest version you've specified, meaning any +updates you've requested have been completed. +* All of the replicas associated with the Deployment are available. +* No old replicas for the Deployment are running. + +You can check if a Deployment has completed by using `kubectl rollout status`. If the rollout completed +successfully, `kubectl rollout status` returns a zero exit code. + +```shell +$ kubectl rollout status deploy/nginx-deployment +Waiting for rollout to finish: 2 of 3 updated replicas are available... +deployment "nginx" successfully rolled out +$ echo $? +0 +``` + +### Failed Deployment + +Your Deployment may get stuck trying to deploy its newest ReplicaSet without ever completing. This can occur +due to some of the following factors: + +* Insufficient quota +* Readiness probe failures +* Image pull errors +* Insufficient permissions +* Limit ranges +* Application runtime misconfiguration + +One way you can detect this condition is to specify a deadline parameter in your Deployment spec: +([`spec.progressDeadlineSeconds`](#progress-deadline-seconds)). `spec.progressDeadlineSeconds` denotes the +number of seconds the Deployment controller waits before indicating (in the Deployment status) that the +Deployment progress has stalled. + +The following `kubectl` command sets the spec with `progressDeadlineSeconds` to make the controller report +lack of progress for a Deployment after 10 minutes: + +```shell +$ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}' +"nginx-deployment" patched +``` +Once the deadline has been exceeded, the Deployment controller adds a DeploymentCondition with the following +attributes to the Deployment's `status.conditions`: + +* Type=Progressing +* Status=False +* Reason=ProgressDeadlineExceeded + +See the [Kubernetes API conventions](https://git.k8s.io/community/contributors/devel/api-conventions.md#typical-status-properties) for more information on status conditions. + +**Note:** Kubernetes will take no action on a stalled Deployment other than to report a status condition with +`Reason=ProgressDeadlineExceeded`. Higher level orchestrators can take advantage of it and act accordingly, for +example, rollback the Deployment to its previous version. +{: .note} + +**Note:** If you pause a Deployment, Kubernetes does not check progress against your specified deadline. You can +safely pause a Deployment in the middle of a rollout and resume without triggering the condition for exceeding the +deadline. +{: .note} + +You may experience transient errors with your Deployments, either due to a low timeout that you have set or +due to any other kind of error that can be treated as transient. For example, let's suppose you have +insufficient quota. If you describe the Deployment you will notice the following section: + +```shell +$ kubectl describe deployment nginx-deployment +<...> +Conditions: + Type Status Reason + ---- ------ ------ + Available True MinimumReplicasAvailable + Progressing True ReplicaSetUpdated + ReplicaFailure True FailedCreate +<...> +``` + +If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployement status might look like this: + +``` +status: + availableReplicas: 2 + conditions: + - lastTransitionTime: 2016-10-04T12:25:39Z + lastUpdateTime: 2016-10-04T12:25:39Z + message: Replica set "nginx-deployment-4262182780" is progressing. + reason: ReplicaSetUpdated + status: "True" + type: Progressing + - lastTransitionTime: 2016-10-04T12:25:42Z + lastUpdateTime: 2016-10-04T12:25:42Z + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: "True" + type: Available + - lastTransitionTime: 2016-10-04T12:25:39Z + lastUpdateTime: 2016-10-04T12:25:39Z + message: 'Error creating: pods "nginx-deployment-4262182780-" is forbidden: exceeded quota: + object-counts, requested: pods=1, used: pods=3, limited: pods=2' + reason: FailedCreate + status: "True" + type: ReplicaFailure + observedGeneration: 3 + replicas: 2 + unavailableReplicas: 2 +``` + +Eventually, once the Deployment progress deadline is exceeded, Kubernetes updates the status and the +reason for the Progressing condition: + +``` +Conditions: + Type Status Reason + ---- ------ ------ + Available True MinimumReplicasAvailable + Progressing False ProgressDeadlineExceeded + ReplicaFailure True FailedCreate +``` + +You can address an issue of insufficient quota by scaling down your Deployment, by scaling down other +controllers you may be running, or by increasing quota in your namespace. If you satisfy the quota +conditions and the Deployment controller then completes the Deployment rollout, you'll see the +Deployment's status update with a successful condition (`Status=True` and `Reason=NewReplicaSetAvailable`). + +``` +Conditions: + Type Status Reason + ---- ------ ------ + Available True MinimumReplicasAvailable + Progressing True NewReplicaSetAvailable +``` + +`Type=Available` with `Status=True` means that your Deployment has minimum availability. Minimum availability is dictated +by the parameters specified in the deployment strategy. `Type=Progressing` with `Status=True` means that your Deployment +is either in the middle of a rollout and it is progressing or that it has successfully completed its progress and the minimum +required new replicas are available (see the Reason of the condition for the particulars - in our case +`Reason=NewReplicaSetAvailable` means that the Deployment is complete). + +You can check if a Deployment has failed to progress by using `kubectl rollout status`. `kubectl rollout status` +returns a non-zero exit code if the Deployment has exceeded the progression deadline. + +```shell +$ kubectl rollout status deploy/nginx-deployment +Waiting for rollout to finish: 2 out of 3 new replicas have been updated... +error: deployment "nginx" exceeded its progress deadline +$ echo $? +1 +``` + +### Operating on a failed deployment + +All actions that apply to a complete Deployment also apply to a failed Deployment. You can scale it up/down, roll back +to a previous revision, or even pause it if you need to apply multiple tweaks in the Deployment pod template. + +## Clean up Policy + +You can set `.spec.revisionHistoryLimit` field in a Deployment to specify how many old ReplicaSets for +this Deployment you want to retain. The rest will be garbage-collected in the background. By default, +all revision history will be kept. In a future version, it will default to switch to 2. + +**Note:** Explicitly setting this field to 0, will result in cleaning up all the history of your Deployment +thus that Deployment will not be able to roll back. +{: .note} + +## Use Cases + +### Canary Deployment + +If you want to roll out releases to a subset of users or servers using the Deployment, you +can create multiple Deployments, one for each release, following the canary pattern described in +[managing resources](/docs/concepts/cluster-administration/manage-deployment/#canary-deployments). + +## Writing a Deployment Spec + +As with all other Kubernetes configs, a Deployment needs `apiVersion`, `kind`, and `metadata` fields. +For general information about working with config files, see [deploying applications](/docs/tutorials/stateless-application/run-stateless-application-deployment/), +configuring containers, and [using kubectl to manage resources](/docs/tutorials/object-management-kubectl/object-management/) documents. + +A Deployment also needs a [`.spec` section](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status). + +### Pod Template + +The `.spec.template` is the only required field of the `.spec`. + +The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an +`apiVersion` or `kind`. + +In addition to required fields for a Pod, a pod template in a Deployment must specify appropriate +labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See [selector](#selector)). + +Only a [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/) equal to `Always` is +allowed, which is the default if not specified. + +### Replicas + +`.spec.replicas` is an optional field that specifies the number of desired Pods. It defaults to 1. + +### Selector + +`.spec.selector` is an optional field that specifies a [label selector](/docs/concepts/overview/working-with-objects/labels/) +for the Pods targeted by this deployment. + +If specified, `.spec.selector` must match `.spec.template.metadata.labels`, or it will be rejected by +the API. If `.spec.selector` is unspecified, `.spec.selector.matchLabels` defaults to +`.spec.template.metadata.labels`. + +A Deployment may terminate Pods whose labels match the selector if their template is different +from `.spec.template` or if the total number of such Pods exceeds `.spec.replicas`. It brings up new +Pods with `.spec.template` if the number of Pods is less than the desired number. + +**Note:** You should not create other pods whose labels match this selector, either directly, by creating +another Deployment, or by creating another controller such as a ReplicaSet or a ReplicationController. If you +do so, the first Deployment thinks that it created these other pods. Kubernetes does not stop you from doing this. +{: .note} + +If you have multiple controllers that have overlapping selectors, the controllers will fight with each +other and won't behave correctly. + +### Strategy + +`.spec.strategy` specifies the strategy used to replace old Pods by new ones. +`.spec.strategy.type` can be "Recreate" or "RollingUpdate". "RollingUpdate" is +the default value. + +#### Recreate Deployment + +All existing Pods are killed before new ones are created when `.spec.strategy.type==Recreate`. + +#### Rolling Update Deployment + +The Deployment updates Pods in a [rolling update](/docs/tasks/run-application/rolling-update-replication-controller/) +fashion when `.spec.strategy.type==RollingUpdate`. You can specify `maxUnavailable` and `maxSurge` to control +the rolling update process. + +##### Max Unavailable + +`.spec.strategy.rollingUpdate.maxUnavailable` is an optional field that specifies the maximum number +of Pods that can be unavailable during the update process. The value can be an absolute number (for example, 5) +or a percentage of desired Pods (for example, 10%). The absolute number is calculated from percentage by +rounding down. The value cannot be 0 if `.spec.strategy.rollingUpdate.maxSurge` is 0. The default value is 25%. + +For example, when this value is set to 30%, the old ReplicaSet can be scaled down to 70% of desired +Pods immediately when the rolling update starts. Once new Pods are ready, old ReplicaSet can be scaled +down further, followed by scaling up the new ReplicaSet, ensuring that the total number of Pods available +at all times during the update is at least 70% of the desired Pods. + +##### Max Surge + +`.spec.strategy.rollingUpdate.maxSurge` is an optional field that specifies the maximum number of Pods +that can be created over the desired number of Pods. The value can be an absolute number (for example, 5) or a +percentage of desired Pods (for example, 10%). The value cannot be 0 if `MaxUnavailable` is 0. The absolute number +is calculated from the percentage by rounding up. The default value is 25%. + +For example, when this value is set to 30%, the new ReplicaSet can be scaled up immediately when the +rolling update starts, such that the total number of old and new Pods does not exceed 130% of desired +Pods. Once old Pods have been killed, the new ReplicaSet can be scaled up further, ensuring that the +total number of Pods running at any time during the update is at most 130% of desired Pods. + +### Progress Deadline Seconds + +`.spec.progressDeadlineSeconds` is an optional field that specifies the number of seconds you want +to wait for your Deployment to progress before the system reports back that the Deployment has +[failed progressing](#failed-deployment) - surfaced as a condition with `Type=Progressing`, `Status=False`. +and `Reason=ProgressDeadlineExceeded` in the status of the resource. The deployment controller will keep +retrying the Deployment. In the future, once automatic rollback will be implemented, the deployment +controller will roll back a Deployment as soon as it observes such a condition. + +If specified, this field needs to be greater than `.spec.minReadySeconds`. + +### Min Ready Seconds + +`.spec.minReadySeconds` is an optional field that specifies the minimum number of seconds for which a newly +created Pod should be ready without any of its containers crashing, for it to be considered available. +This defaults to 0 (the Pod will be considered available as soon as it is ready). To learn more about when +a Pod is considered ready, see [Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + +### Rollback To + +`.spec.rollbackTo` is an optional field with the configuration the Deployment +should roll back to. Setting this field triggers a rollback, and this field will +be cleared by the server after a rollback is done. + +Because this field will be cleared by the server, it should not be used +declaratively. For example, you should not perform `kubectl apply` with a +manifest with `.spec.rollbackTo` field set. + +#### Revision + +`.spec.rollbackTo.revision` is an optional field specifying the revision to roll +back to. Setting to 0 means rolling back to the last revision in history; +otherwise, means rolling back to the specified revision. This defaults to 0 when +[`spec.rollbackTo`](#rollback-to) is set. + +### Revision History Limit + +A Deployment's revision history is stored in the replica sets it controls. + +`.spec.revisionHistoryLimit` is an optional field that specifies the number of old ReplicaSets to retain +to allow rollback. Its ideal value depends on the frequency and stability of new Deployments. All old +ReplicaSets will be kept by default, consuming resources in `etcd` and crowding the output of `kubectl get rs`, +if this field is not set. The configuration of each Deployment revision is stored in its ReplicaSets; +therefore, once an old ReplicaSet is deleted, you lose the ability to rollback to that revision of Deployment. + +More specifically, setting this field to zero means that all old ReplicaSets with 0 replica will be cleaned up. +In this case, a new Deployment rollout cannot be undone, since its revision history is cleaned up. + +### Paused + +`.spec.paused` is an optional boolean field for pausing and resuming a Deployment. The only difference between +a paused Deployment and one that is not paused, is that any changes into the PodTemplateSpec of the paused +Deployment will not trigger new rollouts as long as it is paused. A Deployment is not paused by default when +it is created. + +## Alternative to Deployments + +### kubectl rolling update + +[Kubectl rolling update](/docs/user-guide/kubectl/{{page.version}}/#rolling-update) updates Pods and ReplicationControllers +in a similar fashion. But Deployments are recommended, since they are declarative, server side, and have +additional features, such as rolling back to any previous revision even after the rolling update is done. + +{% endcapture %} + +{% include templates/concept.md %} diff --git a/cn/docs/concepts/workloads/controllers/frontend.yaml b/cn/docs/concepts/workloads/controllers/frontend.yaml new file mode 100644 index 0000000000..2a2b4d13b9 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/frontend.yaml @@ -0,0 +1,45 @@ +apiVersion: extensions/v1beta1 +kind: ReplicaSet +metadata: + name: frontend + # these labels can be applied automatically + # from the labels in the pod template if not set + # labels: + # app: guestbook + # tier: frontend +spec: + # this replicas value is default + # modify it according to your case + replicas: 3 + # selector can be applied automatically + # from the labels in the pod template if not set, + # but we are specifying the selector here to + # demonstrate its usage. + selector: + matchLabels: + tier: frontend + matchExpressions: + - {key: tier, operator: In, values: [frontend]} + template: + metadata: + labels: + app: guestbook + tier: frontend + spec: + containers: + - name: php-redis + image: gcr.io/google_samples/gb-frontend:v3 + resources: + requests: + cpu: 100m + memory: 100Mi + env: + - name: GET_HOSTS_FROM + value: dns + # If your cluster config does not include a dns service, then to + # instead access environment variables to find service host + # info, comment out the 'value: dns' line above, and uncomment the + # line below. + # value: env + ports: + - containerPort: 80 diff --git a/cn/docs/concepts/workloads/controllers/hpa-rs.yaml b/cn/docs/concepts/workloads/controllers/hpa-rs.yaml new file mode 100644 index 0000000000..a8388530dc --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/hpa-rs.yaml @@ -0,0 +1,11 @@ +apiVersion: autoscaling/v1 +kind: HorizontalPodAutoscaler +metadata: + name: frontend-scaler +spec: + scaleTargetRef: + kind: ReplicaSet + name: frontend + minReplicas: 3 + maxReplicas: 10 + targetCPUUtilizationPercentage: 50 diff --git a/cn/docs/concepts/workloads/controllers/job.yaml b/cn/docs/concepts/workloads/controllers/job.yaml new file mode 100644 index 0000000000..ece4512a8a --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/job.yaml @@ -0,0 +1,15 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: pi +spec: + template: + metadata: + name: pi + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + diff --git a/cn/docs/concepts/workloads/controllers/my-repset.yaml b/cn/docs/concepts/workloads/controllers/my-repset.yaml new file mode 100644 index 0000000000..54befd8f9d --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/my-repset.yaml @@ -0,0 +1,17 @@ +apiVersion: extensions/v1beta1 +kind: ReplicaSet +metadata: + name: my-repset +spec: + replicas: 3 + selector: + matchLabels: + pod-is-for: garbage-collection-example + template: + metadata: + labels: + pod-is-for: garbage-collection-example + spec: + containers: + - name: nginx + image: nginx diff --git a/cn/docs/concepts/workloads/controllers/nginx-deployment.yaml b/cn/docs/concepts/workloads/controllers/nginx-deployment.yaml new file mode 100644 index 0000000000..4ce71688f7 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/nginx-deployment.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/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 diff --git a/cn/docs/concepts/workloads/controllers/petset.yaml b/cn/docs/concepts/workloads/controllers/petset.yaml new file mode 100644 index 0000000000..5c29237c48 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/petset.yaml @@ -0,0 +1,51 @@ +# A headless service to create DNS records +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + # *.nginx.default.svc.cluster.local + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1alpha1 +kind: PetSet +metadata: + name: web +spec: + serviceName: "nginx" + replicas: 2 + template: + metadata: + labels: + app: nginx + annotations: + pod.alpha.kubernetes.io/initialized: "true" + spec: + terminationGracePeriodSeconds: 0 + containers: + - name: nginx + image: gcr.io/google_containers/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + volumeClaimTemplates: + - metadata: + name: www + annotations: + volume.alpha.kubernetes.io/storage-class: anything + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + diff --git a/cn/docs/concepts/workloads/controllers/replication.yaml b/cn/docs/concepts/workloads/controllers/replication.yaml new file mode 100644 index 0000000000..6eff0b9b57 --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/replication.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: nginx +spec: + replicas: 3 + selector: + app: nginx + template: + metadata: + name: nginx + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/cn/docs/concepts/workloads/controllers/statefulset.md b/cn/docs/concepts/workloads/controllers/statefulset.md new file mode 100644 index 0000000000..d52a8c1e1f --- /dev/null +++ b/cn/docs/concepts/workloads/controllers/statefulset.md @@ -0,0 +1,231 @@ +--- +approvers: +- enisoc +- erictune +- foxish +- janetkuo +- kow3ns +- smarterclayton +title: StatefulSets +--- + +{% capture overview %} +**StatefulSets are a beta feature in 1.7. This feature replaces the +PetSets feature from 1.4. Users of PetSets are referred to the 1.5 +[Upgrade Guide](/docs/tasks/manage-stateful-set/upgrade-pet-set-to-stateful-set/) +for further information on how to upgrade existing PetSets to StatefulSets.** + +{% include templates/glossary/snippet.md term="statefulset" length="long" %} +{% endcapture %} + +{% capture body %} + +## Using StatefulSets + +StatefulSets are valuable for applications that require one or more of the +following. + +* Stable, unique network identifiers. +* Stable, persistent storage. +* Ordered, graceful deployment and scaling. +* Ordered, graceful deletion and termination. +* Ordered, automated rolling updates. + +In the above, stable is synonymous with persistence across Pod (re)scheduling. +If an application doesn't require any stable identifiers or ordered deployment, +deletion, or scaling, you should deploy your application with a controller that +provides a set of stateless replicas. Controllers such as +[Deployment](/docs/concepts/workloads/controllers/deployment/) or +[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) may be better suited to your stateless needs. + +## Limitations + +* StatefulSet is a beta resource, not available in any Kubernetes release prior to 1.5. +* As with all alpha/beta resources, you can disable StatefulSet through the `--runtime-config` option passed to the apiserver. +* The storage for a given Pod must either be provisioned by a [PersistentVolume Provisioner](http://releases.k8s.io/{{page.githubbranch}}/examples/persistent-volume-provisioning/README.md) based on the requested `storage class`, or pre-provisioned by an admin. +* Deleting and/or scaling a StatefulSet down will *not* delete the volumes associated with the StatefulSet. This is done to ensure data safety, which is generally more valuable than an automatic purge of all related StatefulSet resources. +* StatefulSets currently require a [Headless Service](/docs/concepts/services-networking/service/#headless-services) to be responsible for the network identity of the Pods. You are responsible for creating this Service. + +## Components +The example below demonstrates the components of a StatefulSet. + +* A Headless Service, named nginx, is used to control the network domain. +* The StatefulSet, named web, has a Spec that indicates that 3 replicas of the nginx container will be launched in unique Pods. +* The volumeClaimTemplates will provide stable storage using [PersistentVolumes](/docs/concepts/storage/volumes/) provisioned by a + PersistentVolume Provisioner. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: web +spec: + serviceName: "nginx" + replicas: 3 + template: + metadata: + labels: + app: nginx + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: nginx + image: gcr.io/google_containers/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: my-storage-class + resources: + requests: + storage: 1Gi +``` + +## Pod Identity +StatefulSet Pods have a unique identity that is comprised of an ordinal, a +stable network identity, and stable storage. The identity sticks to the Pod, +regardless of which node it's (re)scheduled on. + +### Ordinal Index + +For a StatefulSet with N replicas, each Pod in the StatefulSet will be +assigned an integer ordinal, in the range [0,N), that is unique over the Set. + +### Stable Network ID + +Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet +and the ordinal of the Pod. The pattern for the constructed hostname +is `$(statefulset name)-$(ordinal)`. The example above will create three Pods +named `web-0,web-1,web-2`. +A StatefulSet can use a [Headless Service](/docs/concepts/services-networking/service/#headless-services) +to control the domain of its Pods. The domain managed by this Service takes the form: +`$(service name).$(namespace).svc.cluster.local`, where "cluster.local" +is the [cluster domain](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md). +As each Pod is created, it gets a matching DNS subdomain, taking the form: +`$(podname).$(governing service domain)`, where the governing service is defined +by the `serviceName` field on the StatefulSet. + +Here are some examples of choices for Cluster Domain, Service name, +StatefulSet name, and how that affects the DNS names for the StatefulSet's Pods. + +Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain | Pod DNS | Pod Hostname | +-------------- | ----------------- | ----------------- | -------------- | ------- | ------------ | + cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} | + cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} | + kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} | + +Note that Cluster Domain will be set to `cluster.local` unless +[otherwise configured](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md). + +### Stable Storage + +Kubernetes creates one [PersistentVolume](/docs/concepts/storage/volumes/) for each +VolumeClaimTemplate. In the nginx example above, each Pod will receive a single PersistentVolume +with a StorageClass of `my-storage-class` and 1 Gib of provisioned storage. If no StorageClass +is specified, then the default StorageClass will be used. When a Pod is (re)scheduled +onto a node, its `volumeMounts` mount the PersistentVolumes associated with its +PersistentVolume Claims. Note that, the PersistentVolumes associated with the +Pods' PersistentVolume Claims are not deleted when the Pods, or StatefulSet are deleted. +This must be done manually. + +## Deployment and Scaling Guarantees + +* For a StatefulSet with N replicas, when Pods are being deployed, they are created sequentially, in order from {0..N-1}. +* When Pods are being deleted, they are terminated in reverse order, from {N-1..0}. +* Before a scaling operation is applied to a Pod, all of its predecessors must be Running and Ready. +* Before a Pod is terminated, all of its successors must be completely shutdown. + +The StatefulSet should not specify a `pod.Spec.TerminationGracePeriodSeconds` of 0. This practice is unsafe and strongly discouraged. For further explanation, please refer to [force deleting StatefulSet Pods](/docs/tasks/run-application/force-delete-stateful-set-pod/). + +When the nginx example above is created, three Pods will be deployed in the order +web-0, web-1, web-2. web-1 will not be deployed before web-0 is +[Running and Ready](/docs/user-guide/pod-states), and web-2 will not be deployed until +web-1 is Running and Ready. If web-0 should fail, after web-1 is Running and Ready, but before +web-2 is launched, web-2 will not be launched until web-0 is successfully relaunched and +becomes Running and Ready. + +If a user were to scale the deployed example by patching the StatefulSet such that +`replicas=1`, web-2 would be terminated first. web-1 would not be terminated until web-2 +is fully shutdown and deleted. If web-0 were to fail after web-2 has been terminated and +is completely shutdown, but prior to web-1's termination, web-1 would not be terminated +until web-0 is Running and Ready. + +### Pod Management Policies +In Kubernetes 1.7 and later, StatefulSet allows you to relax its ordering guarantees while +preserving its uniqueness and identity guarantees via its `.spec.podManagementPolicy` field. + +#### OrderedReady Pod Management + +`OrderedReady` pod management is the default for StatefulSets. It implements the behavior +described [above](#deployment-and-scaling-guarantees). + +#### Parallel Pod Management + +`Parallel` pod management tells the StatefulSet controller to launch or +terminate all Pods in parallel, and to not wait for Pods to become Running +and Ready or completely terminated prior to launching or terminating another +Pod. + +## Update Strategies + +In Kubernetes 1.7 and later, StatefulSet's `.spec.updateStrategy` field allows you to configure +and disable automated rolling updates for containers, labels, resource request/limits, and +annotations for the Pods in a StatefulSet. + +### On Delete + +The `OnDelete` update strategy implements the legacy (1.6 and prior) behavior. It is the default +strategy when `spec.updateStrategy` is left unspecified. When a StatefulSet's +`.spec.updateStrategy.type` is set to `OnDelete`, the StatefulSet controller will not automatically +update the Pods in a StatefulSet. Users must manually delete Pods to cause the controller to +create new Pods that reflect modifications made to a StatefulSet's `.spec.template`. + +### Rolling Updates + +The `RollingUpdate` update strategy implements automated, rolling update for the Pods in a +StatefulSet. When a StatefulSet's `.spec.updateStrategy.type` is set to `RollingUpdate`, the +StatefulSet controller will delete and recreate each Pod in the StatefulSet. It will proceed +in the same order as Pod termination (from the largest ordinal to the smallest), updating +each Pod one at a time. It will wait until an updated Pod is Running and Ready prior to +updating its predecessor. + +#### Partitions + +The `RollingUpdate` update strategy can be partitioned, by specifying a +`.spec.updateStrategy.rollingUpdate.partition`. If a partition is specified, all Pods with an +ordinal that is greater than or equal to the partition will be updated when the StatefulSet's +`.spec.template` is updated. All Pods with an ordinal that is less than the partition will not +be updated, and, even if they are deleted, they will be recreated at the previous version. If a +StatefulSet's `.spec.updateStrategy.rollingUpdate.partition` is greater than its `.spec.replicas`, +updates to its `.spec.template` will not be propagated to its Pods. +In most cases you will not need to use a partition, but they are useful if you want to stage an +update, roll out a canary, or perform a phased roll out. + +{% endcapture %} +{% capture whatsnext %} + +* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set). + +{% endcapture %} +{% include templates/concept.md %} diff --git a/cn/docs/tasks/access-application-cluster/access-cluster.md b/cn/docs/tasks/access-application-cluster/access-cluster.md new file mode 100644 index 0000000000..a623ad36bf --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/access-cluster.md @@ -0,0 +1,318 @@ +--- +title: Accessing Clusters +--- + +* TOC +{:toc} + +## Accessing the cluster API + +### Accessing for the first time with kubectl + +When accessing the Kubernetes API for the first time, we suggest using the +Kubernetes CLI, `kubectl`. + +To access a cluster, you need to know the location of the cluster and have credentials +to access it. Typically, this is automatically set-up when you work through +a [Getting started guide](/docs/getting-started-guides/), +or someone else setup the cluster and provided you with credentials and a location. + +Check the location and credentials that kubectl knows about with this command: + +```shell +$ kubectl config view +``` + +Many of the [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) provide an introduction to using +kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index). + +### Directly accessing the REST API + +Kubectl handles locating and authenticating to the apiserver. +If you want to directly access the REST API with an http client like +curl or wget, or a browser, there are several ways to locate and authenticate: + + - Run kubectl in proxy mode. + - Recommended approach. + - Uses stored apiserver location. + - Verifies identity of apiserver using self-signed cert. No MITM possible. + - Authenticates to apiserver. + - In future, may do intelligent client-side load-balancing and failover. + - Provide the location and credentials directly to the http client. + - Alternate approach. + - Works with some types of client code that are confused by using a proxy. + - Need to import a root cert into your browser to protect against MITM. + +#### Using kubectl proxy + +The following command runs kubectl in a mode where it acts as a reverse proxy. It handles +locating the apiserver and authenticating. +Run it like this: + +```shell +$ kubectl proxy --port=8080 & +``` + +See [kubectl proxy](/docs/user-guide/kubectl/v1.6/#proxy) for more details. + +Then you can explore the API with curl, wget, or a browser, like so: + +```shell +$ curl http://localhost:8080/api/ +{ + "versions": [ + "v1" + ] +} +``` + +#### Without kubectl proxy (before v1.3.x) + +It is possible to avoid using kubectl proxy by passing an authentication token +directly to the apiserver, like this: + +```shell +$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ") +$ TOKEN=$(kubectl config view | grep token | cut -f 2 -d ":" | tr -d " ") +$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +{ + "versions": [ + "v1" + ] +} +``` + +#### Without kubectl proxy (post v1.3.x) + +In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl describe secret...` to get the token for the default service account, like this: + +``` shell +$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ") +$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t') +$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure +{ + "kind": "APIVersions", + "versions": [ + "v1" + ], + "serverAddressByClientCIDRs": [ + { + "clientCIDR": "0.0.0.0/0", + "serverAddress": "10.0.1.149:443" + } + ] +} +``` + +The above examples use the `--insecure` flag. This leaves it subject to MITM +attacks. When kubectl accesses the cluster it uses a stored root certificate +and client certificates to access the server. (These are installed in the +`~/.kube` directory). Since cluster certificates are typically self-signed, it +may take special configuration to get your http client to use root +certificate. + +On some clusters, the apiserver does not require authentication; it may serve +on localhost, or be protected by a firewall. There is not a standard +for this. [Configuring Access to the API](/docs/admin/accessing-the-api) +describes how a cluster admin can configure this. Such approaches may conflict +with future high-availability support. + +### Programmatic access to the API + +Kubernetes officially supports [Go](#go-client) and [Python](#python-client) +client libraries. + +#### Go client + +* To get the library, run the following command: `go get k8s.io/client-go//kubernetes`. See [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go) to see which versions are supported. +* Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct. + +The Go client can use the same [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/) +as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://git.k8s.io/client-go/examples/out-of-cluster-client-configuration/main.go). + +If the application is deployed as a Pod in the cluster, please refer to the [next section](#accessing-the-api-from-a-pod). + +#### Python client + +To use [Python client](https://github.com/kubernetes-incubator/client-python), run the following command: `pip install kubernetes`. See [Python Client Library page](https://github.com/kubernetes-incubator/client-python) for more installation options. + +The Python client can use the same [kubeconfig file](/docs/user-guide/kubeconfig-file) +as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes-incubator/client-python/tree/master/examples/example1.py). + +#### Other languages + +There are [client libraries](/docs/reference/client-libraries/) for accessing the API from other languages. +See documentation for other libraries for how they authenticate. + +### Accessing the API from a Pod + +When accessing the API from a pod, locating and authenticating +to the apiserver are somewhat different. + +The recommended way to locate the apiserver within the pod is with +the `kubernetes` DNS name, which resolves to a Service IP which in turn +will be routed to an apiserver. + +The recommended way to authenticate to the apiserver is with a +[service account](/docs/tasks/configure-pod-container/configure-service-account/) credential. By kube-system, a pod +is associated with a service account, and a credential (token) for that +service account is placed into the filesystem tree of each container in that pod, +at `/var/run/secrets/kubernetes.io/serviceaccount/token`. + +If available, a certificate bundle is placed into the filesystem tree of each +container at `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`, and should be +used to verify the serving certificate of the apiserver. + +Finally, the default namespace to be used for namespaced API operations is placed in a file +at `/var/run/secrets/kubernetes.io/serviceaccount/namespace` in each container. + +From within a pod the recommended ways to connect to API are: + + - run a kubectl proxy as one of the containers in the pod, or as a background + process within a container. This proxies the + Kubernetes API to the localhost interface of the pod, so that other processes + in any container of the pod can access it. See this [example of using kubectl proxy + in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/). + - use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions. + They handle locating and authenticating to the apiserver. [example](https://git.k8s.io/client-go/examples/in-cluster-client-configuration/main.go) + +In each case, the credentials of the pod are used to communicate securely with the apiserver. + + +## Accessing services running on the cluster + +The previous section was about connecting the Kubernetes API server. This section is about +connecting to other services running on Kubernetes cluster. In Kubernetes, the +[nodes](/docs/admin/node), [pods](/docs/user-guide/pods) and [services](/docs/user-guide/services) all have +their own IPs. In many cases, the node IPs, pod IPs, and some service IPs on a cluster will not be +routable, so they will not be reachable from a machine outside the cluster, +such as your desktop machine. + +### Ways to connect + +You have several options for connecting to nodes, pods and services from outside the cluster: + + - Access services through public IPs. + - Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside + the cluster. See the [services](/docs/user-guide/services) and + [kubectl expose](/docs/user-guide/kubectl/v1.6/#expose) documentation. + - Depending on your cluster environment, this may just expose the service to your corporate network, + or it may expose it to the internet. Think about whether the service being exposed is secure. + Does it do its own authentication? + - Place pods behind services. To access one specific pod from a set of replicas, such as for debugging, + place a unique label on the pod and create a new service which selects this label. + - In most cases, it should not be necessary for application developer to directly access + nodes via their nodeIPs. + - Access services, nodes, or pods using the Proxy Verb. + - Does apiserver authentication and authorization prior to accessing the remote service. + Use this if the services are not secure enough to expose to the internet, or to gain + access to ports on the node IP, or for debugging. + - Proxies may cause problems for some web applications. + - Only works for HTTP/HTTPS. + - Described [here](#manually-constructing-apiserver-proxy-urls). + - Access from a node or pod in the cluster. + - Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/v1.6/#exec). + Connect to other nodes, pods, and services from that shell. + - Some clusters may allow you to ssh to a node in the cluster. From there you may be able to + access cluster services. This is a non-standard method, and will work on some clusters but + not others. Browsers and other tools may or may not be installed. Cluster DNS may not work. + +### Discovering builtin services + +Typically, there are several services which are started on a cluster by kube-system. Get a list of these +with the `kubectl cluster-info` command: + +```shell +$ kubectl cluster-info + + Kubernetes master is running at https://104.197.5.247 + elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy + kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy + kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy + grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy + heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy +``` + +This shows the proxy-verb URL for accessing each service. +For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached +at `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` if suitable credentials are passed. Logging can also be reached through a kubectl proxy, for example at: +`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`. +(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.) + +#### Manually constructing apiserver proxy URLs + +As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL: +`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy` + +If you haven't specified a name for your port, you don't have to specify *port_name* in the URL. + +##### Examples + + * To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy` + * To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true` + +```json + { + "cluster_name" : "kubernetes_logging", + "status" : "yellow", + "timed_out" : false, + "number_of_nodes" : 1, + "number_of_data_nodes" : 1, + "active_primary_shards" : 5, + "active_shards" : 5, + "relocating_shards" : 0, + "initializing_shards" : 0, + "unassigned_shards" : 5 + } +``` + +#### Using web browsers to access services running on the cluster + +You may be able to put an apiserver proxy url into the address bar of a browser. However: + + - Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth, + but your cluster may not be configured to accept basic auth. + - Some web apps may not work, particularly those with client side javascript that construct urls in a + way that is unaware of the proxy path prefix. + +## Requesting redirects + +The redirect capabilities have been deprecated and removed. Please use a proxy (see below) instead. + +## So Many Proxies + +There are several different proxies you may encounter when using Kubernetes: + + 1. The [kubectl proxy](#directly-accessing-the-rest-api): + - runs on a user's desktop or in a pod + - proxies from a localhost address to the Kubernetes apiserver + - client to proxy uses HTTP + - proxy to apiserver uses HTTPS + - locates apiserver + - adds authentication headers + 1. The [apiserver proxy](#discovering-builtin-services): + - is a bastion built into the apiserver + - connects a user outside of the cluster to cluster IPs which otherwise might not be reachable + - runs in the apiserver processes + - client to proxy uses HTTPS (or http if apiserver so configured) + - proxy to target may use HTTP or HTTPS as chosen by proxy using available information + - can be used to reach a Node, Pod, or Service + - does load balancing when used to reach a Service + 1. The [kube proxy](/docs/user-guide/services/#ips-and-vips): + - runs on each node + - proxies UDP and TCP + - does not understand HTTP + - provides load balancing + - is just used to reach services + 1. A Proxy/Load-balancer in front of apiserver(s): + - existence and implementation varies from cluster to cluster (e.g. nginx) + - sits between all clients and one or more apiservers + - acts as load balancer if there are several apiservers. + 1. Cloud Load Balancers on external services: + - are provided by some cloud providers (e.g. AWS ELB, Google Cloud Load Balancer) + - are created automatically when the Kubernetes service has type `LoadBalancer` + - use UDP/TCP only + - implementation varies by cloud provider. + +Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin +will typically ensure that the latter types are setup correctly. diff --git a/cn/docs/tasks/access-application-cluster/frontend.yaml b/cn/docs/tasks/access-application-cluster/frontend.yaml new file mode 100644 index 0000000000..382c3786e5 --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/frontend.yaml @@ -0,0 +1,34 @@ +kind: Service +apiVersion: v1 +metadata: + name: frontend +spec: + selector: + app: hello + tier: frontend + ports: + - protocol: "TCP" + port: 80 + targetPort: 80 + type: LoadBalancer +--- +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: frontend +spec: + replicas: 1 + template: + metadata: + labels: + app: hello + tier: frontend + track: stable + spec: + containers: + - name: nginx + image: "gcr.io/google-samples/hello-frontend:1.0" + lifecycle: + preStop: + exec: + command: ["/usr/sbin/nginx","-s","quit"] diff --git a/cn/docs/tasks/access-application-cluster/hello-service.yaml b/cn/docs/tasks/access-application-cluster/hello-service.yaml new file mode 100644 index 0000000000..1e4c7a6c32 --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/hello-service.yaml @@ -0,0 +1,12 @@ +kind: Service +apiVersion: v1 +metadata: + name: hello +spec: + selector: + app: hello + tier: backend + ports: + - protocol: TCP + port: 80 + targetPort: http diff --git a/cn/docs/tasks/access-application-cluster/hello.yaml b/cn/docs/tasks/access-application-cluster/hello.yaml new file mode 100644 index 0000000000..61e4ea4a17 --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/hello.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: hello +spec: + replicas: 7 + template: + metadata: + labels: + app: hello + tier: backend + track: stable + spec: + containers: + - name: hello + image: "gcr.io/google-samples/hello-go-gke:1.0" + ports: + - name: http + containerPort: 80 diff --git a/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md b/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md new file mode 100644 index 0000000000..672495468a --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md @@ -0,0 +1,94 @@ +--- +title: Use Port Forwarding to Access Applications in a Cluster +--- + +{% capture overview %} + +This page shows how to use `kubectl port-forward` to connect to a Redis +server running in a Kubernetes cluster. This type of connection can be useful +for database debugging. + +{% endcapture %} + + +{% capture prerequisites %} + +* {% include task-tutorial-prereqs.md %} + +* Install [redis-cli](http://redis.io/topics/rediscli). + +{% endcapture %} + + +{% capture steps %} + +## Creating a pod to run a Redis server + +1. Create a pod: + + kubectl create -f https://k8s.io/docs/tasks/access-application-cluster/redis-master.yaml + + The output of a successful command verifies that the pod was created: + + pod "redis-master" created + +1. Check to see whether the pod is running and ready: + + kubectl get pods + + When the pod is ready, the output displays a STATUS of Running: + + NAME READY STATUS RESTARTS AGE + redis-master 2/2 Running 0 41s + +1. Verify that the Redis server is running in the pod and listening on port 6379: + + {% raw %} + kubectl get pods redis-master --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}' + {% endraw %} + + The output displays the port: + + 6379 + +## Forward a local port to a port on the pod + +1. Forward port 6379 on the local workstation to port 6379 of redis-master pod: + + kubectl port-forward redis-master 6379:6379 + + The output is similar to this: + + I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:6379 -> 6379 + I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:6379 -> 6379 + +1. Start the Redis command line interface: + + redis-cli + +1. At the Redis command line prompt, enter the `ping` command: + + 127.0.0.1:6379>ping + + A successful ping request returns PONG. + +{% endcapture %} + + +{% capture discussion %} + +## Discussion + +Connections made to local port 6379 are forwarded to port 6379 of the pod that +is running the Redis server. With this connection in place you can use your +local workstation to debug the database that is running in the pod. + +{% endcapture %} + + +{% capture whatsnext %} +Learn more about [kubectl port-forward](/docs/user-guide/kubectl/v1.6/#port-forward). +{% endcapture %} + + +{% include templates/task.md %} diff --git a/cn/docs/tasks/access-application-cluster/redis-master.yaml b/cn/docs/tasks/access-application-cluster/redis-master.yaml new file mode 100644 index 0000000000..57305a7a35 --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/redis-master.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + name: redis + redis-sentinel: "true" + role: master + name: redis-master +spec: + containers: + - name: master + image: gcr.io/google_containers/redis:v1 + env: + - name: MASTER + value: "true" + ports: + - containerPort: 6379 + resources: + limits: + cpu: "0.1" + volumeMounts: + - mountPath: /redis-master-data + name: data + - name: sentinel + image: kubernetes/redis:v1 + env: + - name: SENTINEL + value: "true" + ports: + - containerPort: 26379 + volumes: + - name: data + emptyDir: {} diff --git a/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md b/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md new file mode 100644 index 0000000000..ebbd195b5e --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/service-access-application-cluster.md @@ -0,0 +1,147 @@ +--- +title: Use a Service to Access an Application in a Cluster +--- + +{% capture overview %} + +This page shows how to create a Kubernetes Service object that external +clients can use to access an application running in a cluster. The Service +provides load balancing for an application that has two running instances. + +{% endcapture %} + + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture objectives %} + +* Run two instances of a Hello World application. +* Create a Service object that exposes a node port. +* Use the Service object to access the running application. + +{% endcapture %} + + +{% capture lessoncontent %} + +## Creating a service for an application running in two pods + +1. Run a Hello World application in your cluster: + + kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=gcr.io/google-samples/node-hello:1.0 --port=8080 + + The preceding command creates a + [Deployment](/docs/concepts/workloads/controllers/deployment/) + object and an associated + [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) + object. The ReplicaSet has two + [Pods](/docs/concepts/workloads/pods/pod/), + each of which runs the Hello World application. + +1. Display information about the Deployment: + + kubectl get deployments hello-world + kubectl describe deployments hello-world + +1. Display information about your ReplicaSet objects: + + kubectl get replicasets + kubectl describe replicasets + +1. Create a Service object that exposes the deployment: + + kubectl expose deployment hello-world --type=NodePort --name=example-service + +1. Display information about the Service: + + kubectl describe services example-service + + The output is similar to this: + + Name: example-service + Namespace: default + Labels: run=load-balancer-example + Selector: run=load-balancer-example + Type: NodePort + IP: 10.32.0.16 + Port: 8080/TCP + NodePort: 31496/TCP + Endpoints: 10.200.1.4:8080,10.200.2.5:8080 + Session Affinity: None + No events. + + Make a note of the NodePort value for the service. For example, + in the preceding output, the NodePort value is 31496. + +1. List the pods that are running the Hello World application: + + kubectl get pods --selector="run=load-balancer-example" --output=wide + + The output is similar to this: + + NAME READY STATUS ... IP NODE + hello-world-2895499144-bsbk5 1/1 Running ... 10.200.1.4 worker1 + hello-world-2895499144-m1pwt 1/1 Running ... 10.200.2.5 worker2 + +1. Get the public IP address of one of your nodes that is running + a Hello World pod. How you get this address depends on how you set + up your cluster. For example, if you are using Minikube, you can + see the node address by running `kubectl cluster-info`. If you are + using Google Compute Engine instances, you can use the + `gcloud compute instances list` command to see the public addresses of your + nodes. For more information about this command, see the [GCE documentation](https://cloud.google.com/sdk/gcloud/reference/compute/instances/list). + +1. On your chosen node, create a firewall rule that allows TCP traffic + on your node port. For example, if your Service has a NodePort value of + 31568, create a firewall rule that allows TCP traffic on port 31568. Different + cloud providers offer different ways of configuring firewall rules. See [the + GCE documentation on firewall rules](https://cloud.google.com/compute/docs/vpc/firewalls), + for example. + +1. Use the node address and node port to access the Hello World application: + + curl http://: + + where `` is the public IP address of your node, + and `` is the NodePort value for your service. + + The response to a successful request is a hello message: + + Hello Kubernetes! + +## Using a service configuration file + +As an alternative to using `kubectl expose`, you can use a +[service configuration file](/docs/user-guide/services/operations) +to create a Service. + +{% endcapture %} + + +{% capture cleanup %} + +To delete the Service, enter this command: + + kubectl delete services example-service + +To delete the Deployment, the ReplicaSet, and the Pods that are running +the Hello World application, enter this command: + + kubectl delete deployment hello-world + +{% endcapture %} + + +{% capture whatsnext %} + +Learn more about +[connecting applications with services](/docs/concepts/services-networking/connect-applications-service/). +{% endcapture %} + +{% include templates/tutorial.md %} + diff --git a/cn/docs/tasks/access-application-cluster/two-container-pod.yaml b/cn/docs/tasks/access-application-cluster/two-container-pod.yaml new file mode 100644 index 0000000000..031ada7112 --- /dev/null +++ b/cn/docs/tasks/access-application-cluster/two-container-pod.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Pod +metadata: + name: two-containers +spec: + + restartPolicy: Never + + volumes: + - name: shared-data + emptyDir: {} + + containers: + + - name: nginx-container + image: nginx + volumeMounts: + - name: shared-data + mountPath: /usr/share/nginx/html + + - name: debian-container + image: debian + volumeMounts: + - name: shared-data + mountPath: /pod-data + command: ["/bin/sh"] + args: ["-c", "echo Hello from the debian container > /pod-data/index.html"] diff --git a/cn/docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml new file mode 100644 index 0000000000..b5c7348f26 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-2.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-cpu-demo-2 +spec: + containers: + - name: constraints-cpu-demo-2-ctr + image: nginx + resources: + limits: + cpu: "1.5" + requests: + cpu: "500m" diff --git a/cn/docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml new file mode 100644 index 0000000000..896d98ec2f --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-3.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-cpu-demo-4 +spec: + containers: + - name: constraints-cpu-demo-4-ctr + image: nginx + resources: + limits: + cpu: "800m" + requests: + cpu: "100m" diff --git a/cn/docs/tasks/administer-cluster/cpu-constraints-pod-4.yaml b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-4.yaml new file mode 100644 index 0000000000..3c102158db --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-constraints-pod-4.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-cpu-demo-4 +spec: + containers: + - name: constraints-cpu-demo-4-ctr + image: vish/stress diff --git a/cn/docs/tasks/administer-cluster/cpu-constraints-pod.yaml b/cn/docs/tasks/administer-cluster/cpu-constraints-pod.yaml new file mode 100644 index 0000000000..7db23f26c8 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-constraints-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-cpu-demo +spec: + containers: + - name: constraints-cpu-demo-ctr + image: nginx + resources: + limits: + cpu: "800m" + requests: + cpu: "500m" diff --git a/cn/docs/tasks/administer-cluster/cpu-constraints.yaml b/cn/docs/tasks/administer-cluster/cpu-constraints.yaml new file mode 100644 index 0000000000..6fc4239027 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-constraints.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: cpu-min-max-demo-lr +spec: + limits: + - max: + cpu: "800m" + min: + cpu: "200m" + type: Container diff --git a/cn/docs/tasks/administer-cluster/cpu-defaults-pod-2.yaml b/cn/docs/tasks/administer-cluster/cpu-defaults-pod-2.yaml new file mode 100644 index 0000000000..9ca216dee1 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-defaults-pod-2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-cpu-demo-2 +spec: + containers: + - name: default-cpu-demo-2-ctr + image: nginx + resources: + limits: + cpu: "1" diff --git a/cn/docs/tasks/administer-cluster/cpu-defaults-pod-3.yaml b/cn/docs/tasks/administer-cluster/cpu-defaults-pod-3.yaml new file mode 100644 index 0000000000..214cdee34b --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-defaults-pod-3.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-cpu-demo-3 +spec: + containers: + - name: default-cpu-demo-3-ctr + image: nginx + resources: + requests: + cpu: "0.75" diff --git a/cn/docs/tasks/administer-cluster/cpu-defaults-pod.yaml b/cn/docs/tasks/administer-cluster/cpu-defaults-pod.yaml new file mode 100644 index 0000000000..56b06d9a69 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-defaults-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-cpu-demo +spec: + containers: + - name: default-cpu-demo-ctr + image: nginx diff --git a/cn/docs/tasks/administer-cluster/cpu-defaults.yaml b/cn/docs/tasks/administer-cluster/cpu-defaults.yaml new file mode 100644 index 0000000000..b53d297181 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/cpu-defaults.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: cpu-limit-range +spec: + limits: + - default: + cpu: 1 + defaultRequest: + cpu: 0.5 + type: Container diff --git a/cn/docs/tasks/administer-cluster/dns-horizontal-autoscaler.yaml b/cn/docs/tasks/administer-cluster/dns-horizontal-autoscaler.yaml new file mode 100644 index 0000000000..f29dd2e275 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/dns-horizontal-autoscaler.yaml @@ -0,0 +1,30 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: kube-dns-autoscaler + namespace: kube-system + labels: + k8s-app: kube-dns-autoscaler +spec: + template: + metadata: + labels: + k8s-app: kube-dns-autoscaler + spec: + containers: + - name: autoscaler + image: gcr.io/google_containers/cluster-proportional-autoscaler-amd64:1.0.0 + resources: + requests: + cpu: "20m" + memory: "10Mi" + command: + - /cluster-proportional-autoscaler + - --namespace=kube-system + - --configmap=kube-dns-autoscaler + - --target= + # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. + # If using small nodes, "nodesPerReplica" should dominate. + - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"min":1}} + - --logtostderr=true + - --v=2 diff --git a/cn/docs/tasks/administer-cluster/ip-masq-agent.md b/cn/docs/tasks/administer-cluster/ip-masq-agent.md new file mode 100644 index 0000000000..04625647c6 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/ip-masq-agent.md @@ -0,0 +1,112 @@ +--- +title: IP Masquerade Agent User Guide +--- + +{% capture overview %} +This page shows how to configure and enable the ip-masq-agent. +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture discussion %} +## IP Masquerade Agent User Guide + +The ip-masq-agent configures iptables rules to hide a pod's IP address behind the cluster node's IP address. This is typically done when sending traffic to destinations outside the cluster's pod [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) range. + +### **Key Terms** + +* **NAT (Network Address Translation)** + Is a method of remapping one IP address to another by modifying either the source and/or destination address information in the IP header. Typically performed by a device doing IP routing. +* **Masquerading** + A form of NAT that is typically used to perform a many to one address translation, where multiple source IP addresses are masked behind a single address, which is typically the device doing the IP routing. In Kubernetes this is the Node's IP address. +* **CIDR (Classless Inter-Domain Routing)** + Based on the variable-length subnet masking, allows specifying arbitrary-length prefixes. CIDR introduced a new method of representation for IP addresses, now commonly known as **CIDR notation**, in which an address or routing prefix is written with a suffix indicating the number of bits of the prefix, such as 192.168.2.0/24. +* **Link Local** + A link-local address is a network address that is valid only for communications within the network segment or the broadcast domain that the host is connected to. Link-local addresses for IPv4 are defined in the address block 169.254.0.0/16 in CIDR notation. + +The ip-masq-agent configures iptables rules to handle masquerading node/pod IP addresses when sending traffic to destinations outside the cluster node's IP and the Cluster IP range. This essentially hides pod IP addresses behind the cluster node's IP address. In some environments, traffic to "external" addresses must come from a known machine address. For example, in Google Cloud, any traffic to the internet must come from a VM's IP. When containers are used, as in GKE, the Pod IP will be rejected for egress. To avoid this, we must hide the Pod IP behind the VM's own IP address - generally known as "masquerade". By default, the agent is configured to treat the three private IP ranges specified by [RFC 1918](https://tools.ietf.org/html/rfc1918) as non-masquerade [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). These ranges are 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. The agent will also treat link-local (169.254.0.0/16) as a non-masquerade CIDR by default. The agent is configured to reload its configuration from the location */etc/config/ip-masq-agent* every 60 seconds, which is also configurable. + +![masq/non-masq example](/images/docs/ip-masq.png) + +The agent configuration file must be written in YAML or JSON syntax, and may contain three optional keys: + +* **nonMasqueradeCIDRs:** A list of strings in [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) notation that specify the non-masquerade ranges. +* **masqLinkLocal:** A Boolean (true / false) which indicates whether to masquerade traffic to the link local prefix 169.254.0.0/16. False by default. +* **resyncInterval:** An interval at which the agent attempts to reload config from disk. e.g. '30s' where 's' is seconds, 'ms' is milliseconds etc... + +Traffic to 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) ranges will NOT be masqueraded. Any other traffic (assumed to be internet) will be masqueraded. An example of a local destination from a pod could be its Node's IP address as well as another node's address or one of the IP addresses in Cluster's IP range. Any other traffic will be masqueraded by default. The below entries show the default set of rules that are applied by the ip-masq-agent: + +``` +iptables -t nat -L IP-MASQ-AGENT +RETURN all -- anywhere 169.254.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL +RETURN all -- anywhere 10.0.0.0/8 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL +RETURN all -- anywhere 172.16.0.0/12 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL +RETURN all -- anywhere 192.168.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL +MASQUERADE all -- anywhere anywhere /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL + +``` + +By default, in GCE/GKE starting with Kubernetes version 1.7.0, if network policy is enabled or you are using a cluster CIDR not in the 10.0.0.0/8 range, the ip-masq-agent will run in your cluster. If you are running in another environment, you can add the ip-masq-agent [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) to your cluster: + +{% endcapture %} + +{% capture steps %} + +## Create an ip-masq-agent +To create an ip-masq-agent, run the following kubectl command: + +` +kubectl create -f https://raw.githubusercontent.com/kubernetes-incubator/ip-masq-agent/master/ip-masq-agent.yaml +` + +You must also apply the appropriate node label to any nodes in your cluster that you want the agent to run on. + +` +kubectl label nodes my-node beta.kubernetes.io/masq-agent-ds-ready=true +` + +More information can be found in the ip-masq-agent documentation [here](https://github.com/kubernetes-incubator/ip-masq-agent) + +In most cases, the default set of rules should be sufficient; however, if this is not the case for your cluster, you can create and apply a [ConfigMap](/docs/tasks/configure-pod-container/configmap/) to customize the IP ranges that are affected. For example, to allow only 10.0.0.0/8 to be considered by the ip-masq-agent, you can create the following [ConfigMap](/docs/tasks/configure-pod-container/configmap/) in a file called "config". +**Note:** It is important that the file is called config since, by default, that will be used as the key for lookup by the ip-masq-agent: + +``` +nonMasqueradeCIDRs: + - 10.0.0.0/8 +resyncInterval: 60s + +``` + +Run the following command to add the config map to your cluster: + +``` +kubectl create configmap ip-masq-agent --from-file=config --namespace=kube-system +``` + +This will update a file located at */etc/config/ip-masq-agent* which is periodically checked every *resyscInterval* and applied to the cluster node. +After the resync interval has expired, you should see the iptables rules reflect your changes: + +``` +iptables -t nat -L IP-MASQ-AGENT +Chain IP-MASQ-AGENT (1 references) +target prot opt source destination +RETURN all -- anywhere 169.254.0.0/16 /* ip-masq-agent: cluster-local traffic should not be subject to MASQUERADE */ ADDRTYPE match dst-type !LOCAL +RETURN all -- anywhere 10.0.0.0/8 /* ip-masq-agent: cluster-local +MASQUERADE all -- anywhere anywhere /* ip-masq-agent: outbound traffic should be subject to MASQUERADE (this match must come after cluster-local CIDR matches) */ ADDRTYPE match dst-type !LOCAL +``` + +By default, the link local range (169.254.0.0/16) is also handled by the ip-masq agent, which sets up the appropriate iptables rules. To have the ip-masq-agent ignore link local, you can set *masqLinkLocal* to true in the config map. + +``` +nonMasqueradeCIDRs: + - 10.0.0.0/8 +resyncInterval: 60s +masqLinkLocal: true +``` +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/memory-constraints-pod-2.yaml b/cn/docs/tasks/administer-cluster/memory-constraints-pod-2.yaml new file mode 100644 index 0000000000..0b1ae569c4 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-constraints-pod-2.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-mem-demo-2 +spec: + containers: + - name: constraints-mem-demo-2-ctr + image: nginx + resources: + limits: + memory: "1.5Gi" + requests: + memory: "800Mi" diff --git a/cn/docs/tasks/administer-cluster/memory-constraints-pod-3.yaml b/cn/docs/tasks/administer-cluster/memory-constraints-pod-3.yaml new file mode 100644 index 0000000000..f97cd4a8ac --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-constraints-pod-3.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-mem-demo-3 +spec: + containers: + - name: constraints-mem-demo-3-ctr + image: nginx + resources: + limits: + memory: "800Mi" + requests: + memory: "100Mi" diff --git a/cn/docs/tasks/administer-cluster/memory-constraints-pod-4.yaml b/cn/docs/tasks/administer-cluster/memory-constraints-pod-4.yaml new file mode 100644 index 0000000000..657530c41e --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-constraints-pod-4.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-mem-demo-4 +spec: + containers: + - name: constraints-mem-demo-4-ctr + image: nginx + diff --git a/cn/docs/tasks/administer-cluster/memory-constraints-pod.yaml b/cn/docs/tasks/administer-cluster/memory-constraints-pod.yaml new file mode 100644 index 0000000000..06954d10d6 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-constraints-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: constraints-mem-demo +spec: + containers: + - name: constraints-mem-demo-ctr + image: nginx + resources: + limits: + memory: "800Mi" + requests: + memory: "600Mi" diff --git a/cn/docs/tasks/administer-cluster/memory-constraints.yaml b/cn/docs/tasks/administer-cluster/memory-constraints.yaml new file mode 100644 index 0000000000..3a2924c032 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-constraints.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: mem-min-max-demo-lr +spec: + limits: + - max: + memory: 1Gi + min: + memory: 500Mi + type: Container diff --git a/cn/docs/tasks/administer-cluster/memory-defaults-pod-2.yaml b/cn/docs/tasks/administer-cluster/memory-defaults-pod-2.yaml new file mode 100644 index 0000000000..1013293edd --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-defaults-pod-2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-mem-demo-2 +spec: + containers: + - name: defalt-mem-demo-2-ctr + image: nginx + resources: + limits: + memory: "1Gi" diff --git a/cn/docs/tasks/administer-cluster/memory-defaults-pod-3.yaml b/cn/docs/tasks/administer-cluster/memory-defaults-pod-3.yaml new file mode 100644 index 0000000000..09ee8b39a9 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-defaults-pod-3.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-mem-demo-3 +spec: + containers: + - name: default-mem-demo-3-ctr + image: nginx + resources: + requests: + memory: "128Mi" diff --git a/cn/docs/tasks/administer-cluster/memory-defaults-pod.yaml b/cn/docs/tasks/administer-cluster/memory-defaults-pod.yaml new file mode 100644 index 0000000000..ce7a50fb55 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-defaults-pod.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: default-mem-demo +spec: + containers: + - name: default-mem-demo-ctr + image: nginx diff --git a/cn/docs/tasks/administer-cluster/memory-defaults.yaml b/cn/docs/tasks/administer-cluster/memory-defaults.yaml new file mode 100644 index 0000000000..b98a5ae262 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/memory-defaults.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: mem-limit-range +spec: + limits: + - default: + memory: 512Mi + defaultRequest: + memory: 256Mi + type: Container diff --git a/cn/docs/tasks/administer-cluster/my-scheduler.yaml b/cn/docs/tasks/administer-cluster/my-scheduler.yaml new file mode 100644 index 0000000000..dde31f119a --- /dev/null +++ b/cn/docs/tasks/administer-cluster/my-scheduler.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + labels: + component: scheduler + tier: control-plane + name: my-scheduler + namespace: kube-system +spec: + replicas: 1 + template: + metadata: + labels: + component: scheduler + tier: control-plane + version: second + spec: + containers: + - command: + - /usr/local/bin/kube-scheduler + - --address=0.0.0.0 + - --leader-elect=false + - --scheduler-name=my-scheduler + image: gcr.io/my-gcp-project/my-kube-scheduler:1.0 + livenessProbe: + httpGet: + path: /healthz + port: 10251 + initialDelaySeconds: 15 + name: kube-second-scheduler + readinessProbe: + httpGet: + path: /healthz + port: 10251 + resources: + requests: + cpu: '0.1' + securityContext: + privileged: false + volumeMounts: [] + hostNetwork: false + hostPID: false + volumes: [] diff --git a/cn/docs/tasks/administer-cluster/pod1.yaml b/cn/docs/tasks/administer-cluster/pod1.yaml new file mode 100644 index 0000000000..733aa97d99 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/pod1.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: no-annotation + labels: + name: multischeduler-example +spec: + containers: + - name: pod-with-no-annotation-container + image: gcr.io/google_containers/pause:2.0 \ No newline at end of file diff --git a/cn/docs/tasks/administer-cluster/pod2.yaml b/cn/docs/tasks/administer-cluster/pod2.yaml new file mode 100644 index 0000000000..e1e280ff09 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/pod2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: annotation-default-scheduler + labels: + name: multischeduler-example +spec: + schedulerName: default-scheduler + containers: + - name: pod-with-default-annotation-container + image: gcr.io/google_containers/pause:2.0 diff --git a/cn/docs/tasks/administer-cluster/pod3.yaml b/cn/docs/tasks/administer-cluster/pod3.yaml new file mode 100644 index 0000000000..63be0e0aa3 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/pod3.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: annotation-second-scheduler + labels: + name: multischeduler-example +spec: + schedulerName: my-scheduler + containers: + - name: pod-with-second-annotation-container + image: gcr.io/google_containers/pause:2.0 diff --git a/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod-2.yaml b/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod-2.yaml new file mode 100644 index 0000000000..22726c600a --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod-2.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: quota-mem-cpu-demo-2 +spec: + containers: + - name: quota-mem-cpu-demo-2-ctr + image: redis + resources: + limits: + memory: "1Gi" + cpu: "800m" + requests: + memory: "700Mi" + cpu: "400m" + diff --git a/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod.yaml b/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod.yaml new file mode 100644 index 0000000000..ba27bf5ccf --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-mem-cpu-pod.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: quota-mem-cpu-demo +spec: + containers: + - name: quota-mem-cpu-demo-ctr + image: nginx + resources: + limits: + memory: "800Mi" + cpu: "800m" + requests: + memory: "600Mi" + cpu: "400m" + diff --git a/cn/docs/tasks/administer-cluster/quota-mem-cpu.yaml b/cn/docs/tasks/administer-cluster/quota-mem-cpu.yaml new file mode 100644 index 0000000000..5c4bcd81b8 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-mem-cpu.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: mem-cpu-demo +spec: + hard: + requests.cpu: "1" + requests.memory: 1Gi + limits.cpu: "2" + limits.memory: 2Gi diff --git a/cn/docs/tasks/administer-cluster/quota-objects-pvc-2.yaml b/cn/docs/tasks/administer-cluster/quota-objects-pvc-2.yaml new file mode 100644 index 0000000000..88c165d144 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-objects-pvc-2.yaml @@ -0,0 +1,11 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-quota-demo-2 +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 4Gi diff --git a/cn/docs/tasks/administer-cluster/quota-objects-pvc.yaml b/cn/docs/tasks/administer-cluster/quota-objects-pvc.yaml new file mode 100644 index 0000000000..b38256b897 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-objects-pvc.yaml @@ -0,0 +1,11 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-quota-demo +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/cn/docs/tasks/administer-cluster/quota-objects.yaml b/cn/docs/tasks/administer-cluster/quota-objects.yaml new file mode 100644 index 0000000000..e97748decd --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-objects.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: object-quota-demo +spec: + hard: + persistentvolumeclaims: "1" + services.loadbalancers: "2" + services.nodeports: "0" diff --git a/cn/docs/tasks/administer-cluster/quota-pod-deployment.yaml b/cn/docs/tasks/administer-cluster/quota-pod-deployment.yaml new file mode 100644 index 0000000000..6d6302a8f4 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-pod-deployment.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: pod-quota-demo +spec: + replicas: 3 + template: + metadata: + labels: + purpose: quota-demo + spec: + containers: + - name: pod-quota-demo + image: nginx diff --git a/cn/docs/tasks/administer-cluster/quota-pod.yaml b/cn/docs/tasks/administer-cluster/quota-pod.yaml new file mode 100644 index 0000000000..0a07f055ca --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-pod.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: pod-demo +spec: + hard: + pods: "2" diff --git a/cn/docs/tasks/administer-cluster/quota-pvc-2.yaml b/cn/docs/tasks/administer-cluster/quota-pvc-2.yaml new file mode 100644 index 0000000000..88c165d144 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/quota-pvc-2.yaml @@ -0,0 +1,11 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-quota-demo-2 +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 4Gi diff --git a/cn/docs/tasks/configure-pod-container/configmap.md b/cn/docs/tasks/configure-pod-container/configmap.md new file mode 100644 index 0000000000..352ea85c11 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/configmap.md @@ -0,0 +1,256 @@ +--- +approvers: +- eparis +- pmorie +title: Configure Containers Using a ConfigMap +--- + + +{% capture overview %} + +This page shows you how to configure an application using a ConfigMap. ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable. + +{% endcapture %} + +{% capture prerequisites %} + +* {% include task-tutorial-prereqs.md %} + +{% endcapture %} + + +{% capture steps %} + +## Use kubectl to create a ConfigMap + +Use the `kubectl create configmap` command to create configmaps from [directories](#creating-configmaps-from-directories), [files](#creating-configmaps-from-files), or [literal values](#creating-configmaps-from-literal-values): + +```shell +kubectl create configmap +``` + +where \ is the name you want to assign to the ConfigMap and \ is the directory, file, or literal value to draw the data from. + +The data source corresponds to a key-value pair in the ConfigMap, where + +* key = the file name or the key you provided on the command line, and +* value = the file contents or the literal value you provided on the command line. + +You can use [`kubectl describe`](/docs/user-guide/kubectl/v1.6/#describe) or [`kubectl get`](/docs/user-guide/kubectl/v1.6/#get) to retrieve information about a ConfigMap. The former shows a summary of the ConfigMap, while the latter returns the full contents of the ConfigMap. + +### Create ConfigMaps from directories + +You can use `kubectl create configmap` to create a ConfigMap from multiple files in the same directory. + +For example: + +```shell +kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl +``` + +combines the contents of the `docs/user-guide/configmap/kubectl/` directory + +```shell +ls docs/user-guide/configmap/kubectl/ +game.properties +ui.properties +``` + +into the following ConfigMap: + +```shell +kubectl describe configmaps game-config +Name: game-config +Namespace: default +Labels: +Annotations: + +Data +==== +game.properties: 158 bytes +ui.properties: 83 bytes +``` + +The `game.properties` and `ui.properties` files in the `docs/user-guide/configmap/kubectl/` directory are represented in the `data` section of the ConfigMap. + +```shell +kubectl get configmaps game-config -o yaml +``` + +```yaml +apiVersion: v1 +data: + game.properties: | + enemies=aliens + lives=3 + enemies.cheat=true + enemies.cheat.level=noGoodRotten + secret.code.passphrase=UUDDLRLRBABAS + secret.code.allowed=true + secret.code.lives=30 + ui.properties: | + color.good=purple + color.bad=yellow + allow.textmode=true + how.nice.to.look=fairlyNice +kind: ConfigMap +metadata: + creationTimestamp: 2016-02-18T18:52:05Z + name: game-config + namespace: default + resourceVersion: "516" + selfLink: /api/v1/namespaces/default/configmaps/game-config-2 + uid: b4952dc3-d670-11e5-8cd0-68f728db1985 +``` + +### Create ConfigMaps from files + +You can use `kubectl create configmap` to create a ConfigMap from an individual file, or from multiple files. + +For example, + +```shell +kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties +``` + +would produce the following ConfigMap: + +```shell +kubectl describe configmaps game-config-2 +Name: game-config-2 +Namespace: default +Labels: +Annotations: + +Data +==== +game.properties: 158 bytes +``` + +You can pass in the `--from-file` argument multiple times to create a ConfigMap from multiple data sources. + +```shell +kubectl create configmap game-config-2 --from-file=docs/user-guide/configmap/kubectl/game.properties --from-file=docs/user-guide/configmap/kubectl/ui.properties +``` + +```shell +kubectl describe configmaps game-config-2 +Name: game-config-2 +Namespace: default +Labels: +Annotations: + +Data +==== +game.properties: 158 bytes +ui.properties: 83 bytes +``` + +#### Define the key to use when creating a ConfigMap from a file + +You can define a key other than the file name to use in the `data` section of your ConfigMap when using the `--from-file` argument: + +```shell +kubectl create configmap game-config-3 --from-file== +``` + +where `` is the key you want to use in the ConfigMap and `` is the location of the data source file you want the key to represent. + +For example: + +```shell +kubectl create configmap game-config-3 --from-file=game-special-key=docs/user-guide/configmap/kubectl/game.properties + +kubectl get configmaps game-config-3 -o yaml +``` + +```yaml +apiVersion: v1 +data: + game-special-key: | + enemies=aliens + lives=3 + enemies.cheat=true + enemies.cheat.level=noGoodRotten + secret.code.passphrase=UUDDLRLRBABAS + secret.code.allowed=true + secret.code.lives=30 +kind: ConfigMap +metadata: + creationTimestamp: 2016-02-18T18:54:22Z + name: game-config-3 + namespace: default + resourceVersion: "530" + selfLink: /api/v1/namespaces/default/configmaps/game-config-3 + uid: 05f8da22-d671-11e5-8cd0-68f728db1985 +``` + +### Create ConfigMaps from literal values + +You can use `kubectl create configmap` with the `--from-literal` argument to define a literal value from the command line: + +```shell +kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm +``` + +You can pass in multiple key-value pairs. Each pair provided on the command line is represented as a separate entry in the `data` section of the ConfigMap. + +```shell +kubectl get configmaps special-config -o yaml +``` + +```yaml +apiVersion: v1 +data: + special.how: very + special.type: charm +kind: ConfigMap +metadata: + creationTimestamp: 2016-02-18T19:14:38Z + name: special-config + namespace: default + resourceVersion: "651" + selfLink: /api/v1/namespaces/default/configmaps/special-config + uid: dadce046-d673-11e5-8cd0-68f728db1985 +``` + +{% endcapture %} + +{% capture discussion %} + +## Understanding ConfigMaps + +ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable. +The ConfigMap API resource stores configuration data as key-value pairs. The data can be consumed in pods or provide the configurations for system components such as controllers. ConfigMap is similar to [Secrets](/docs/concepts/configuration/secret/), but provides a means of working with strings that don't contain sensitive information. Users and system components alike can store configuration data in ConfigMap. + +**Note:** ConfigMaps should reference properties files, not replace them. Think of the ConfigMap as representing something similar to the Linux `/etc` directory and its contents. For example, if you create a [Kubernetes Volume](/docs/concepts/storage/volumes/) from a ConfigMap, each data item in the ConfigMap is represented by an individual file in the volume. +{: .note} + +The ConfigMap's `data` field contains the configuration data. As shown in the example below, this can be simple -- like individual properties defined using `--from-literal` -- or complex -- like configuration files or JSON blobs defined using `--from-file`. + +```yaml +kind: ConfigMap +apiVersion: v1 +metadata: + creationTimestamp: 2016-02-18T19:14:38Z + name: example-config + namespace: default +data: + # example of a simple property defined using --from-literal + example.property.1: hello + example.property.2: world + # example of a complex property defined using --from-file + example.property.file: |- + property.1=value-1 + property.2=value-2 + property.3=value-3 +``` + +{% endcapture %} + +{% capture whatsnext %} +* See [Using ConfigMap Data in Pods](/docs/tasks/configure-pod-container/configure-pod-configmap). +* Follow a real world example of [Configuring Redis using a ConfigMap](/docs/tutorials/configuration/configure-redis-using-configmap/). +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md b/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md new file mode 100644 index 0000000000..a842c449cd --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md @@ -0,0 +1,301 @@ +--- +title: Configure Liveness and Readiness Probes +--- + +{% capture overview %} + +This page shows how to configure liveness and readiness probes for Containers. + +The [kubelet](/docs/admin/kubelet/) uses liveness probes to know when to +restart a Container. For example, liveness probes could catch a deadlock, +where an application is running, but unable to make progress. Restarting a +Container in such a state can help to make the application more available +despite bugs. + +The kubelet uses readiness probes to know when a Container is ready to start +accepting traffic. A Pod is considered ready when all of its Containers are ready. +One use of this signal is to control which Pods are used as backends for Services. +When a Pod is not ready, it is removed from Service load balancers. + +{% endcapture %} + +{% capture prerequisites %} + +{% include task-tutorial-prereqs.md %} + +{% endcapture %} + +{% capture steps %} + +## Define a liveness command + +Many applications running for long periods of time eventually transition to +broken states, and cannot recover except by being restarted. Kubernetes provides +liveness probes to detect and remedy such situations. + +In this exercise, you create a Pod that runs a Container based on the +`gcr.io/google_containers/busybox` image. Here is the configuration file for the Pod: + +{% include code.html language="yaml" file="exec-liveness.yaml" ghlink="/docs/tasks/configure-pod-container/exec-liveness.yaml" %} + +In the configuration file, you can see that the Pod has a single Container. +The `periodSeconds` field specifies that the kubelet should perform a liveness +probe every 5 seconds. The `initialDelaySeconds` field tells the kubelet that it +should wait 5 second before performing the first probe. To perform a probe, the +kubelet executes the command `cat /tmp/healthy` in the Container. If the +command succeeds, it returns 0, and the kubelet considers the Container to be alive and +healthy. If the command returns a non-zero value, the kubelet kills the Container +and restarts it. + +When the Container starts, it executes this command: + +```shell +/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600" +``` + +For the first 30 seconds of the Container's life, there is a `/tmp/healthy` file. +So during the first 30 seconds, the command `cat /tmp/healthy` returns a success +code. After 30 seconds, `cat /tmp/healthy` returns a failure code. + +Create the Pod: + +```shell +kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/exec-liveness.yaml +``` + +Within 30 seconds, view the Pod events: + +``` +kubectl describe pod liveness-exec +``` + +The output indicates that no liveness probes have failed yet: + +```shell +FirstSeen LastSeen Count From SubobjectPath Type Reason Message +--------- -------- ----- ---- ------------- -------- ------ ------- +24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "gcr.io/google_containers/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "gcr.io/google_containers/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e +``` + +After 35 seconds, view the Pod events again: + +```shell +kubectl describe pod liveness-exec +``` + +At the bottom of the output, there are messages indicating that the liveness +probes have failed, and the containers have been killed and recreated. + +```shell +FirstSeen LastSeen Count From SubobjectPath Type Reason Message +--------- -------- ----- ---- ------------- -------- ------ ------- +37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "gcr.io/google_containers/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "gcr.io/google_containers/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e +2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory +``` + +Wait another 30 seconds, and verify that the Container has been restarted: + +```shell +kubectl get pod liveness-exec +``` + +The output shows that `RESTARTS` has been incremented: + +```shell +NAME READY STATUS RESTARTS AGE +liveness-exec 1/1 Running 1 1m +``` + +## Define a liveness HTTP request + +Another kind of liveness probe uses an HTTP GET request. Here is the configuration +file for a Pod that runs a container based on the `gcr.io/google_containers/liveness` +image. + +{% include code.html language="yaml" file="http-liveness.yaml" ghlink="/docs/tasks/configure-pod-container/http-liveness.yaml" %} + +In the configuration file, you can see that the Pod has a single Container. +The `livenessProbe` field specifies that the kubelet should perform a liveness +probe every 3 seconds. The `initialDelaySeconds` field tells the kubelet that it +should wait 3 seconds before performing the first probe. To perform a probe, the +kubelet sends an HTTP GET request to the server that is running in the Container +and listening on port 8080. If the handler for the server's `/healthz` path +returns a success code, the kubelet considers the Container to be alive and +healthy. If the handler returns a failure code, the kubelet kills the Container +and restarts it. + +Any code greater than or equal to 200 and less than 400 indicates success. Any +other code indicates failure. + +You can see the source code for the server in +[server.go](https://github.com/kubernetes/kubernetes/blob/master/test/images/liveness/server.go). + +For the first 10 seconds that the Container is alive, the `/healthz` handler +returns a status of 200. After that, the handler returns a status of 500. + +```go +http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { + duration := time.Now().Sub(started) + if duration.Seconds() > 10 { + w.WriteHeader(500) + w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds()))) + } else { + w.WriteHeader(200) + w.Write([]byte("ok")) + } +}) +``` + +The kubelet starts performing health checks 3 seconds after the Container starts. +So the first couple of health checks will succeed. But after 10 seconds, the health +checks will fail, and the kubelet will kill and restart the Container. + +To try the HTTP liveness check, create a Pod: + +```shell +kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/http-liveness.yaml +``` + +After 10 seconds, view Pod events to verify that liveness probes have failed and +the Container has been restarted: + +```shell +kubectl describe pod liveness-http +``` + +## Define a TCP liveness probe + +A third type of liveness probe uses a TCP Socket. With this configuration, the +kubelet will attempt to open a socket to your container on the specified port. +If it can establish a connection, the container is considered healthy, if it +can’t it is considered a failure. + +{% include code.html language="yaml" file="tcp-liveness-readiness.yaml" ghlink="/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml" %} + +As you can see, configuration for a TCP check is quite similar to an HTTP check. +This example uses both readiness and liveness probes. The kubelet will send the +first readiness probe 5 seconds after the container starts. This will attempt to +connect to the `goproxy` container on port 8080. If the probe succeeds, the pod +will be marked as ready. The kubelet will continue to run this check every 10 +seconds. + +In addition to the readiness probe, this configuration includes a liveness probe. +The kubelet will run the first liveness probe 15 seconds after the container +starts. Just like the readiness probe, this will attempt to connect to the +`goproxy` container on port 8080. If the liveness probe fails, the container +will be restarted. + +## Use a named port + +You can use a named +[ContainerPort](/docs/api-reference/{{page.version}}/#containerport-v1-core) +for HTTP or TCP liveness checks: + +```yaml +ports: +- name: liveness-port + containerPort: 8080 + hostPort: 8080 + +livenessProbe: + httpGet: + path: /healthz + port: liveness-port +``` + +## Define readiness probes + +Sometimes, applications are temporarily unable to serve traffic. +For example, an application might need to load large data or configuration +files during startup. In such cases, you don't want to kill the application, +but you don’t want to send it requests either. Kubernetes provides +readiness probes to detect and mitigate these situations. A pod with containers +reporting that they are not ready does not receive traffic through Kubernetes +Services. + +Readiness probes are configured similarly to liveness probes. The only difference +is that you use the `readinessProbe` field instead of the `livenessProbe` field. + +```yaml +readinessProbe: + exec: + command: + - cat + - /tmp/healthy + initialDelaySeconds: 5 + periodSeconds: 5 +``` + +Configuration for HTTP and TCP readiness probes also remains identical to +liveness probes. + +Readiness and liveness probes can be used in parallel for the same container. +Using both can ensure that traffic does not reach a container that is not ready +for it, and that containers are restarted when they fail. + +## Configure Probes + +{% comment %} +Eventually, some of this section could be moved to a concept topic. +{% endcomment %} + +[Probes](/docs/api-reference/{{page.version}}/#probe-v1-core) have a number of fields that +you can use to more precisely control the behavior of liveness and readiness +checks: + +* `initialDelaySeconds`: Number of seconds after the container has started +before liveness probes are initiated. +* `periodSeconds`: How often (in seconds) to perform the probe. Default to 10 +seconds. Minimum value is 1. +* `timeoutSeconds`: Number of seconds after which the probe times out. Defaults +to 1 second. Minimum value is 1. +* `successThreshold`: Minimum consecutive successes for the probe to be +considered successful after having failed. Defaults to 1. Must be 1 for +liveness. Minimum value is 1. +* `failureThreshold`: Minimum consecutive failures for the probe to be +considered failed after having succeeded. Defaults to 3. Minimum value is 1. + +[HTTP probes](/docs/api-reference/{{page.version}}/#httpgetaction-v1-core) +have additional fields that can be set on `httpGet`: + +* `host`: Host name to connect to, defaults to the pod IP. You probably want to +set "Host" in httpHeaders instead. +* `scheme`: Scheme to use for connecting to the host. Defaults to HTTP. +* `path`: Path to access on the HTTP server. +* `httpHeaders`: Custom headers to set in the request. HTTP allows repeated headers. +* `port`: Name or number of the port to access on the container. Number must be +in the range 1 to 65535. + +For an HTTP probe, the kubelet sends an HTTP request to the specified path and +port to perform the check. The kubelet sends the probe to the container’s IP address, +unless the address is overridden by the optional `host` field in `httpGet`. +In most scenarios, you do not want to set the `host` field. Here's one scenario +where you would set it. Suppose the Container listens on 127.0.0.1 and the Pod's +`hostNetwork` field is true. Then `host`, under `httpGet`, should be set to 127.0.0.1. +If your pod relies on virtual hosts, which is probably the more common case, +you should not use `host`, but rather set the `Host` header in `httpHeaders`. + +{% endcapture %} + +{% capture whatsnext %} + +* Learn more about +[Container Probes](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes). + +### Reference + +* [Pod](/docs/api-reference/{{page.version}}/#pod-v1-core) +* [Container](/docs/api-reference/{{page.version}}/#container-v1-core) +* [Probe](/docs/api-reference/{{page.version}}/#probe-v1-core) + +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/configure-pod-container/configure-service-account.md b/cn/docs/tasks/configure-pod-container/configure-service-account.md new file mode 100644 index 0000000000..55e115bd10 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/configure-service-account.md @@ -0,0 +1,231 @@ +--- +approvers: +- bprashanth +- liggitt +- thockin +title: Configure Service Accounts for Pods +--- + +A service account provides an identity for processes that run in a Pod. + +*This is a user introduction to Service Accounts. See also the +[Cluster Admin Guide to Service Accounts](/docs/admin/service-accounts-admin).* + +**Note:** This document describes how service accounts behave in a cluster set up +as recommended by the Kubernetes project. Your cluster administrator may have +customized the behavior in your cluster, in which case this documentation may +not apply. +{: .note} + +When you (a human) access the cluster (e.g. using `kubectl`), you are +authenticated by the apiserver as a particular User Account (currently this is +usually `admin`, unless your cluster administrator has customized your +cluster). Processes in containers inside pods can also contact the apiserver. +When they do, they are authenticated as a particular Service Account (e.g. +`default`). + +## Use the Default Service Account to access the API server. + +When you create a pod, if you do not specify a service account, it is +automatically assigned the `default` service account in the same namespace. +If you get the raw json or yaml for a pod you have created (e.g. `kubectl get pods/podname -o yaml`), +you can see the `spec.serviceAccountName` field has been +[automatically set](/docs/user-guide/working-with-resources/#resources-are-automatically-modified). + +You can access the API from inside a pod using automatically mounted service account credentials, +as described in [Accessing the Cluster](/docs/user-guide/accessing-the-cluster/#accessing-the-api-from-a-pod). +The API permissions a service account has depend on the [authorization plugin and policy](/docs/admin/authorization/#a-quick-note-on-service-accounts) in use. + +In version 1.6+, you can opt out of automounting API credentials for a service account by setting +`automountServiceAccountToken: false` on the service account: + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: build-robot +automountServiceAccountToken: false +... +``` + +In version 1.6+, you can also opt out of automounting API credentials for a particular pod: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: my-pod +spec: + serviceAccountName: build-robot + automountServiceAccountToken: false + ... +``` + +The pod spec takes precedence over the service account if both specify a `automountServiceAccountToken` value. + +## Use Multiple Service Accounts. + +Every namespace has a default service account resource called `default`. +You can list this and any other serviceAccount resources in the namespace with this command: + +```shell +$ kubectl get serviceAccounts +NAME SECRETS AGE +default 1 1d +``` + +You can create additional ServiceAccount objects like this: + +```shell +$ cat > /tmp/serviceaccount.yaml < /tmp/build-robot-secret.yaml < +Annotations: kubernetes.io/service-account.name=build-robot,kubernetes.io/service-account.uid=870ef2a5-35cf-11e5-8d06-005056b45392 + +Type: kubernetes.io/service-account-token + +Data +==== +ca.crt: 1220 bytes +token: ... +namespace: 7 bytes +``` + +**Note:** The content of `token` is elided here. +{: .note} + +## Add ImagePullSecrets to a service account + +First, create an imagePullSecret, as described [here](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). +Next, verify it has been created. For example: + +```shell +$ kubectl get secrets myregistrykey +NAME TYPE DATA AGE +myregistrykey   kubernetes.io/.dockerconfigjson   1       1d +``` + +Next, modify the default service account for the namespace to use this secret as an imagePullSecret. + +```shell +kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}' +``` + +Interactive version requiring manual edit: + +```shell +$ kubectl get serviceaccounts default -o yaml > ./sa.yaml +$ cat sa.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: 2015-08-07T22:02:39Z + name: default + namespace: default + resourceVersion: "243024" + selfLink: /api/v1/namespaces/default/serviceaccounts/default + uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 +secrets: +- name: default-token-uudge +$ vi sa.yaml +[editor session not shown] +[delete line with key "resourceVersion"] +[add lines with "imagePullSecret:"] +$ cat sa.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + creationTimestamp: 2015-08-07T22:02:39Z + name: default + namespace: default + selfLink: /api/v1/namespaces/default/serviceaccounts/default + uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 +secrets: +- name: default-token-uudge +imagePullSecrets: +- name: myregistrykey +$ kubectl replace serviceaccount default -f ./sa.yaml +serviceaccounts/default +``` + +Now, any new pods created in the current namespace will have this added to their spec: + +```yaml +spec: + imagePullSecrets: + - name: myregistrykey +``` + + diff --git a/cn/docs/tasks/configure-pod-container/cpu-request-limit-2.yaml b/cn/docs/tasks/configure-pod-container/cpu-request-limit-2.yaml new file mode 100644 index 0000000000..afb5562d59 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/cpu-request-limit-2.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: cpu-demo-2 +spec: + containers: + - name: cpu-demo-ctr-2 + image: vish/stress + resources: + limits: + cpu: "100" + requests: + cpu: "100" + args: + - -cpus + - "2" diff --git a/cn/docs/tasks/configure-pod-container/cpu-request-limit.yaml b/cn/docs/tasks/configure-pod-container/cpu-request-limit.yaml new file mode 100644 index 0000000000..a85dde6181 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/cpu-request-limit.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: cpu-demo +spec: + containers: + - name: cpu-demo-ctr + image: vish/stress + resources: + limits: + cpu: "1" + requests: + cpu: "0.5" + args: + - -cpus + - "2" diff --git a/cn/docs/tasks/configure-pod-container/exec-liveness.yaml b/cn/docs/tasks/configure-pod-container/exec-liveness.yaml new file mode 100644 index 0000000000..7b04a5eb8d --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/exec-liveness.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod + +metadata: + labels: + test: liveness + name: liveness-exec +spec: + containers: + + - name: liveness + + args: + - /bin/sh + - -c + - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 + + image: gcr.io/google_containers/busybox + + livenessProbe: + exec: + command: + - cat + - /tmp/healthy + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/cn/docs/tasks/configure-pod-container/http-liveness.yaml b/cn/docs/tasks/configure-pod-container/http-liveness.yaml new file mode 100644 index 0000000000..8485e3444e --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/http-liveness.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + test: liveness + name: liveness-http +spec: + containers: + + - name: liveness + + args: + - /server + + image: gcr.io/google_containers/liveness + + livenessProbe: + httpGet: + path: /healthz + port: 8080 + httpHeaders: + - name: X-Custom-Header + value: Awesome + initialDelaySeconds: 3 + periodSeconds: 3 diff --git a/cn/docs/tasks/configure-pod-container/init-containers.yaml b/cn/docs/tasks/configure-pod-container/init-containers.yaml new file mode 100644 index 0000000000..35c393d7c7 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/init-containers.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Pod +metadata: + name: init-demo +spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 + volumeMounts: + - name: workdir + mountPath: /usr/share/nginx/html + # These containers are run during pod initialization + initContainers: + - name: install + image: busybox + command: + - wget + - "-O" + - "/work-dir/index.html" + - http://kubernetes.io + volumeMounts: + - name: workdir + mountPath: "/work-dir" + dnsPolicy: Default + volumes: + - name: workdir + emptyDir: {} + diff --git a/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml b/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml new file mode 100644 index 0000000000..c62028d7ef --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/lifecycle-events.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: Pod +metadata: + name: lifecycle-demo +spec: + containers: + - name: lifecycle-demo-container + image: nginx + + lifecycle: + postStart: + exec: + command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] + preStop: + exec: + command: ["/usr/sbin/nginx","-s","quit"] + + + + + + + + + + + + + + + + + diff --git a/cn/docs/tasks/configure-pod-container/mem-limit-range.yaml b/cn/docs/tasks/configure-pod-container/mem-limit-range.yaml new file mode 100644 index 0000000000..b98a5ae262 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/mem-limit-range.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: mem-limit-range +spec: + limits: + - default: + memory: 512Mi + defaultRequest: + memory: 256Mi + type: Container diff --git a/cn/docs/tasks/configure-pod-container/memory-request-limit-2.yaml b/cn/docs/tasks/configure-pod-container/memory-request-limit-2.yaml new file mode 100644 index 0000000000..ca16c1de4a --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/memory-request-limit-2.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: memory-demo-2 +spec: + containers: + - name: memory-demo-2-ctr + image: vish/stress + resources: + requests: + memory: 50Mi + limits: + memory: "100Mi" + args: + - -mem-total + - 250Mi + - -mem-alloc-size + - 10Mi + - -mem-alloc-sleep + - 1s diff --git a/cn/docs/tasks/configure-pod-container/memory-request-limit-3.yaml b/cn/docs/tasks/configure-pod-container/memory-request-limit-3.yaml new file mode 100644 index 0000000000..394ec9c2d4 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/memory-request-limit-3.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: memory-demo-3 +spec: + containers: + - name: memory-demo-3-ctr + image: vish/stress + resources: + limits: + memory: "1000Gi" + requests: + memory: "1000Gi" + args: + - -mem-total + - 150Mi + - -mem-alloc-size + - 10Mi + - -mem-alloc-sleep + - 1s diff --git a/cn/docs/tasks/configure-pod-container/memory-request-limit.yaml b/cn/docs/tasks/configure-pod-container/memory-request-limit.yaml new file mode 100644 index 0000000000..22f0d9e0c7 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/memory-request-limit.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: memory-demo +spec: + containers: + - name: memory-demo-ctr + image: vish/stress + resources: + limits: + memory: "200Mi" + requests: + memory: "100Mi" + args: + - -mem-total + - 150Mi + - -mem-alloc-size + - 10Mi + - -mem-alloc-sleep + - 1s diff --git a/cn/docs/tasks/configure-pod-container/oir-pod-2.yaml b/cn/docs/tasks/configure-pod-container/oir-pod-2.yaml new file mode 100644 index 0000000000..cfe4b96076 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/oir-pod-2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: oir-demo-2 +spec: + containers: + - name: oir-demo-2-ctr + image: nginx + resources: + requests: + pod.alpha.kubernetes.io/opaque-int-resource-dongle: 2 diff --git a/cn/docs/tasks/configure-pod-container/oir-pod.yaml b/cn/docs/tasks/configure-pod-container/oir-pod.yaml new file mode 100644 index 0000000000..bd85a5d4f6 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/oir-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: oir-demo +spec: + containers: + - name: oir-demo-ctr + image: nginx + resources: + requests: + pod.alpha.kubernetes.io/opaque-int-resource-dongle: 3 diff --git a/cn/docs/tasks/configure-pod-container/pod-redis.yaml b/cn/docs/tasks/configure-pod-container/pod-redis.yaml new file mode 100644 index 0000000000..cb06456d4b --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/pod-redis.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: redis +spec: + containers: + - name: redis + image: redis + volumeMounts: + - name: redis-storage + mountPath: /data/redis + volumes: + - name: redis-storage + emptyDir: {} diff --git a/cn/docs/tasks/configure-pod-container/pod.yaml b/cn/docs/tasks/configure-pod-container/pod.yaml new file mode 100644 index 0000000000..134ddae2aa --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + nodeSelector: + disktype: ssd diff --git a/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml b/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml new file mode 100644 index 0000000000..9928b6d608 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/private-reg-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: private-reg +spec: + containers: + - name: private-reg-container + image: + imagePullSecrets: + - name: regsecret + diff --git a/cn/docs/tasks/configure-pod-container/projected-volume.yaml b/cn/docs/tasks/configure-pod-container/projected-volume.yaml new file mode 100644 index 0000000000..172ca0dee5 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/projected-volume.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-projected-volume +spec: + containers: + - name: test-projected-volume + image: busybox + args: + - sleep + - "86400" + volumeMounts: + - name: all-in-one + mountPath: "/projected-volume" + readOnly: true + volumes: + - name: all-in-one + projected: + sources: + - secret: + name: user + - secret: + name: pass diff --git a/cn/docs/tasks/configure-pod-container/qos-pod-2.yaml b/cn/docs/tasks/configure-pod-container/qos-pod-2.yaml new file mode 100644 index 0000000000..8e26f6bb37 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/qos-pod-2.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: qos-demo-2 +spec: + containers: + - name: qos-demo-2-ctr + image: nginx + resources: + limits: + memory: "200Mi" + requests: + memory: "100Mi" diff --git a/cn/docs/tasks/configure-pod-container/qos-pod-3.yaml b/cn/docs/tasks/configure-pod-container/qos-pod-3.yaml new file mode 100644 index 0000000000..c31ea25257 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/qos-pod-3.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Pod +metadata: + name: qos-demo-3 +spec: + containers: + - name: qos-demo-3-ctr + image: nginx diff --git a/cn/docs/tasks/configure-pod-container/qos-pod-4.yaml b/cn/docs/tasks/configure-pod-container/qos-pod-4.yaml new file mode 100644 index 0000000000..eebb1739d2 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/qos-pod-4.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: qos-demo-4 +spec: + containers: + + - name: qos-demo-4-ctr-1 + image: nginx + resources: + requests: + memory: "200Mi" + + - name: qos-demo-4-ctr-2 + image: redis diff --git a/cn/docs/tasks/configure-pod-container/qos-pod.yaml b/cn/docs/tasks/configure-pod-container/qos-pod.yaml new file mode 100644 index 0000000000..a54d2b961f --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/qos-pod.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: qos-demo +spec: + containers: + - name: qos-demo-ctr + image: nginx + resources: + limits: + memory: "200Mi" + cpu: "700m" + requests: + memory: "200Mi" + cpu: "700m" diff --git a/cn/docs/tasks/configure-pod-container/rq-compute-resources.yaml b/cn/docs/tasks/configure-pod-container/rq-compute-resources.yaml new file mode 100644 index 0000000000..9757018f19 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/rq-compute-resources.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: compute-resources +spec: + hard: + pods: "4" + requests.cpu: "1" + requests.memory: 1Gi + limits.cpu: "2" + limits.memory: 2Gi diff --git a/cn/docs/tasks/configure-pod-container/security-context-2.yaml b/cn/docs/tasks/configure-pod-container/security-context-2.yaml new file mode 100644 index 0000000000..5a515c99e4 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/security-context-2.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo-2 +spec: + securityContext: + runAsUser: 1000 + containers: + - name: sec-ctx-demo-2 + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + runAsUser: 2000 diff --git a/cn/docs/tasks/configure-pod-container/security-context-3.yaml b/cn/docs/tasks/configure-pod-container/security-context-3.yaml new file mode 100644 index 0000000000..05295e1a03 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/security-context-3.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo-3 +spec: + containers: + - name: sec-ctx-3 + image: gcr.io/google-samples/node-hello:1.0 + + + diff --git a/cn/docs/tasks/configure-pod-container/security-context-4.yaml b/cn/docs/tasks/configure-pod-container/security-context-4.yaml new file mode 100644 index 0000000000..d725308fec --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/security-context-4.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo-4 +spec: + containers: + - name: sec-ctx-4 + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + add: ["NET_ADMIN", "SYS_TIME"] diff --git a/cn/docs/tasks/configure-pod-container/security-context.yaml b/cn/docs/tasks/configure-pod-container/security-context.yaml new file mode 100644 index 0000000000..0795dbfe06 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/security-context.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo +spec: + securityContext: + runAsUser: 1000 + fsGroup: 2000 + volumes: + - name: sec-ctx-vol + emptyDir: {} + containers: + - name: sec-ctx-demo + image: gcr.io/google-samples/node-hello:1.0 + volumeMounts: + - name: sec-ctx-vol + mountPath: /data/demo diff --git a/cn/docs/tasks/configure-pod-container/task-pv-claim.yaml b/cn/docs/tasks/configure-pod-container/task-pv-claim.yaml new file mode 100644 index 0000000000..197db917c8 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/task-pv-claim.yaml @@ -0,0 +1,11 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: task-pv-claim +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/cn/docs/tasks/configure-pod-container/task-pv-pod.yaml b/cn/docs/tasks/configure-pod-container/task-pv-pod.yaml new file mode 100644 index 0000000000..79d97c2f77 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/task-pv-pod.yaml @@ -0,0 +1,22 @@ +kind: Pod +apiVersion: v1 +metadata: + name: task-pv-pod +spec: + + volumes: + - name: task-pv-storage + persistentVolumeClaim: + claimName: task-pv-claim + + containers: + - name: task-pv-container + image: nginx + ports: + - containerPort: 80 + name: "http-server" + volumeMounts: + - mountPath: "/usr/share/nginx/html" + name: task-pv-storage + + diff --git a/cn/docs/tasks/configure-pod-container/task-pv-volume.yaml b/cn/docs/tasks/configure-pod-container/task-pv-volume.yaml new file mode 100644 index 0000000000..5fa1edb55f --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/task-pv-volume.yaml @@ -0,0 +1,14 @@ +kind: PersistentVolume +apiVersion: v1 +metadata: + name: task-pv-volume + labels: + type: local +spec: + storageClassName: manual + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/tmp/data" diff --git a/cn/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml b/cn/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml new file mode 100644 index 0000000000..08065019c5 --- /dev/null +++ b/cn/docs/tasks/configure-pod-container/tcp-liveness-readiness.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Pod +metadata: + name: goproxy + labels: + app: goproxy +spec: + containers: + - name: goproxy + image: gcr.io/google_containers/goproxy:0.1 + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 diff --git a/cn/docs/tasks/run-application/deployment-patch-demo.yaml b/cn/docs/tasks/run-application/deployment-patch-demo.yaml new file mode 100644 index 0000000000..3c45b6c8a9 --- /dev/null +++ b/cn/docs/tasks/run-application/deployment-patch-demo.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: patch-demo +spec: + replicas: 2 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: patch-demo-ctr + image: nginx diff --git a/cn/docs/tasks/run-application/deployment-scale.yaml b/cn/docs/tasks/run-application/deployment-scale.yaml new file mode 100644 index 0000000000..01351c3b5a --- /dev/null +++ b/cn/docs/tasks/run-application/deployment-scale.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + replicas: 4 # Update the replicas from 2 to 4 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.8 + ports: + - containerPort: 80 diff --git a/cn/docs/tasks/run-application/deployment-update.yaml b/cn/docs/tasks/run-application/deployment-update.yaml new file mode 100644 index 0000000000..8f0ac0b48c --- /dev/null +++ b/cn/docs/tasks/run-application/deployment-update.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + replicas: 2 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.8 # Update the version of nginx from 1.7.9 to 1.8 + ports: + - containerPort: 80 diff --git a/cn/docs/tasks/run-application/deployment.yaml b/cn/docs/tasks/run-application/deployment.yaml new file mode 100644 index 0000000000..8d14e2ef08 --- /dev/null +++ b/cn/docs/tasks/run-application/deployment.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + replicas: 2 # tells deployment to run 2 pods matching the template + template: # create pods using pod definition in this template + metadata: + # unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is + # generated from the deployment name + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.7.9 + ports: + - containerPort: 80 diff --git a/cn/docs/tasks/run-application/gce-volume.yaml b/cn/docs/tasks/run-application/gce-volume.yaml new file mode 100644 index 0000000000..ddb9ecc3ce --- /dev/null +++ b/cn/docs/tasks/run-application/gce-volume.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: mysql-pv +spec: + capacity: + storage: 20Gi + accessModes: + - ReadWriteOnce + gcePersistentDisk: + pdName: mysql-disk + fsType: ext4 diff --git a/cn/docs/tasks/run-application/horizontal-pod-autoscale.md b/cn/docs/tasks/run-application/horizontal-pod-autoscale.md new file mode 100644 index 0000000000..d292232fa9 --- /dev/null +++ b/cn/docs/tasks/run-application/horizontal-pod-autoscale.md @@ -0,0 +1,153 @@ +--- +approvers: +- fgrzadkowski +- jszczepkowski +- directxman12 +title: Horizontal Pod Autoscaling +--- + +This document describes the current state of Horizontal Pod Autoscaling in Kubernetes. + +## What is Horizontal Pod Autoscaling? + +With Horizontal Pod Autoscaling, Kubernetes automatically scales the number of pods +in a replication controller, deployment or replica set based on observed CPU utilization +(or, with alpha support, on some other, application-provided metrics). + +The Horizontal Pod Autoscaler is implemented as a Kubernetes API resource and a controller. +The resource determines the behavior of the controller. +The controller periodically adjusts the number of replicas in a replication controller or deployment +to match the observed average CPU utilization to the target specified by user. + +## How does the Horizontal Pod Autoscaler work? + +![Horizontal Pod Autoscaler diagram](/images/docs/horizontal-pod-autoscaler.svg) + +The Horizontal Pod Autoscaler is implemented as a control loop, with a period controlled +by the controller manager's `--horizontal-pod-autoscaler-sync-period` flag (with a default +value of 30 seconds). + +During each period, the controller manager queries the resource utilization against the +metrics specified in each HorizontalPodAutoscaler definition. The controller manager +obtains the metrics from either the resource metrics API (for per-pod resource metrics), +or the custom metrics API (for all other metrics). + +* For per-pod resource metrics (like CPU), the controller fetches the metrics + from the resource metrics API for each pod targeted by the HorizontalPodAutoscaler. + Then, if a target utilization value is set, the controller calculates the utilization + value as a percentage of the equivalent resource request on the containers in + each pod. If a target raw value is set, the raw metric values are used directly. + The controller then takes the mean of the utilization or the raw value (depending on the type + of target specified) across all targeted pods, and produces a ratio used to scale + the number of desired replicas. + + Please note that if some of the pod's containers do not have the relevant resource request set, + CPU utilization for the pod will not be defined and the autoscaler will not take any action + for that metric. See the [autoscaling algorithm design document](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#autoscaling-algorithm) for further + details about how the autoscaling algorithm works. + +* For per-pod custom metrics, the controller functions similarly to per-pod resource metrics, + except that it works with raw values, not utilization values. + +* For object metrics, a single metric is fetched (which describes the object + in question), and compared to the target value, to produce a ratio as above. + +The HorizontalPodAutoscaler controller can fetch metrics in two different ways: direct Heapster +access, and REST client access. + +When using direct Heapster access, the HorizontalPodAutoscaler queries Heapster directly +through the API server's service proxy subresource. Heapster needs to be deployed on the +cluster and running in the kube-system namespace. + +See [Support for custom metrics](#support-for-custom-metrics) for more details on REST client access. + +The autoscaler accesses corresponding replication controller, deployment or replica set by scale sub-resource. +Scale is an interface that allows you to dynamically set the number of replicas and examine each of their current states. +More details on scale sub-resource can be found [here](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#scale-subresource). + + +## API Object + +The Horizontal Pod Autoscaler is an API resource in the Kubernetes `autoscaling` API group. +The current stable version, which only includes support for CPU autoscaling, +can be found in the `autoscaling/v1` API version. + +The alpha version, which includes support for scaling on memory and custom metrics, +can be found in `autoscaling/v2alpha1`. The new fields introduced in `autoscaling/v2alpha1` +are preserved as annotations when working with `autoscaling/v1`. + +More details about the API object can be found at +[HorizontalPodAutoscaler Object](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md#horizontalpodautoscaler-object). + +## Support for Horizontal Pod Autoscaler in kubectl + +Horizontal Pod Autoscaler, like every API resource, is supported in a standard way by `kubectl`. +We can create a new autoscaler using `kubectl create` command. +We can list autoscalers by `kubectl get hpa` and get detailed description by `kubectl describe hpa`. +Finally, we can delete an autoscaler using `kubectl delete hpa`. + +In addition, there is a special `kubectl autoscale` command for easy creation of a Horizontal Pod Autoscaler. +For instance, executing `kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80` +will create an autoscaler for replication controller *foo*, with target CPU utilization set to `80%` +and the number of replicas between 2 and 5. +The detailed documentation of `kubectl autoscale` can be found [here](/docs/user-guide/kubectl/v1.6/#autoscale). + + +## Autoscaling during rolling update + +Currently in Kubernetes, it is possible to perform a [rolling update](/docs/tasks/run-application/rolling-update-replication-controller/) by managing replication controllers directly, +or by using the deployment object, which manages the underlying replication controllers for you. +Horizontal Pod Autoscaler only supports the latter approach: the Horizontal Pod Autoscaler is bound to the deployment object, +it sets the size for the deployment object, and the deployment is responsible for setting sizes of underlying replication controllers. + +Horizontal Pod Autoscaler does not work with rolling update using direct manipulation of replication controllers, +i.e. you cannot bind a Horizontal Pod Autoscaler to a replication controller and do rolling update (e.g. using `kubectl rolling-update`). +The reason this doesn't work is that when rolling update creates a new replication controller, +the Horizontal Pod Autoscaler will not be bound to the new replication controller. + +## Support for multiple metrics + +Kubernetes 1.6 adds support for scaling based on multiple metrics. You can use the `autoscaling/v2alpha1` API +version to specify multiple metrics for the Horizontal Pod Autoscaler to scale on. Then, the Horizontal Pod +Autoscaler controller will evaluate each metric, and propose a new scale based on that metric. The largest of the +proposed scales will be used as the new scale. + +## Support for custom metrics + +**Note**: Kubernetes 1.2 added alpha support for scaling based on application-specific metrics using special annotations. +Support for these annotations was removed in Kubernetes 1.6 in favor of the `autoscaling/v2alpha1` API. While the old method for collecting +custom metrics is still available, these metrics will not be available for use by the Horizontal Pod Autoscaler, and the former +annotations for specifying which custom metrics to scale on are no longer honored by the Horizontal Pod Autoscaler controller. + +Kubernetes 1.6 adds support for making use of custom metrics in the Horizontal Pod Autoscaler. +You can add custom metrics for the Horizontal Pod Autoscaler to use in the `autoscaling/v2alpha1` API. +Kubernetes then queries the new custom metrics API to fetch the values of the appropriate custom metrics. + +### Requirements + +To use custom metrics with your Horizontal Pod Autoscaler, you must set the necessary configurations when deploying your cluster: + +* [Enable the API aggregation layer](/docs/tasks/access-kubernetes-api/configure-aggregation-layer/) if you have not already done so. + +* Register your resource metrics API and your +custom metrics API with the API aggregation layer. Both of these API servers must be running *on* your cluster. + + * *Resource Metrics API*: You can use Heapster's implementation of the resource metrics API, by running Heapster with its `--api-server` flag set to true. + + * *Custom Metrics API*: This must be provided by a separate component. To get started with boilerplate code, see the [kubernetes-incubator/custom-metrics-apiserver](https://github.com/kubernetes-incubator/custom-metrics-apiserver) and the [k8s.io/metrics](https://github.com/kubernetes/metrics) repositories. + +* Set the appropriate flags for kube-controller-manager: + + * `--horizontal-pod-autoscaler-use-rest-clients` should be true. + + * `--kubeconfig ` OR `--master ` + + Note that either the `--master` or `--kubeconfig` flag can be used; `--master` will override `--kubeconfig` if both are specified. These flags specify the location of the API aggregation layer, allowing the controller manager to communicate to the API server. + + In Kubernetes 1.7, the standard aggregation layer that Kubernetes provides runs in-process with the kube-apiserver, so the target IP address can be found with `kubectl get pods --selector k8s-app=kube-apiserver --namespace kube-system -o jsonpath='{.items[0].status.podIP}'`. + +## Further reading + +* Design documentation: [Horizontal Pod Autoscaling](https://git.k8s.io/community/contributors/design-proposals/horizontal-pod-autoscaler.md). +* kubectl autoscale command: [kubectl autoscale](/docs/user-guide/kubectl/v1.6/#autoscale). +* Usage example of [Horizontal Pod Autoscaler](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/). diff --git a/cn/docs/tasks/run-application/mysql-configmap.yaml b/cn/docs/tasks/run-application/mysql-configmap.yaml new file mode 100644 index 0000000000..46d34e422c --- /dev/null +++ b/cn/docs/tasks/run-application/mysql-configmap.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: mysql + labels: + app: mysql +data: + master.cnf: | + # Apply this config only on the master. + [mysqld] + log-bin + slave.cnf: | + # Apply this config only on slaves. + [mysqld] + super-read-only + diff --git a/cn/docs/tasks/run-application/mysql-deployment.yaml b/cn/docs/tasks/run-application/mysql-deployment.yaml new file mode 100644 index 0000000000..1bf9671ef1 --- /dev/null +++ b/cn/docs/tasks/run-application/mysql-deployment.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Service +metadata: + name: mysql +spec: + ports: + - port: 3306 + selector: + app: mysql + clusterIP: None +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql-pv-claim +spec: + accessModes: + - ReadWriteOnce + storageClassName: "" + resources: + requests: + storage: 20Gi +--- +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: mysql +spec: + strategy: + type: Recreate + template: + metadata: + labels: + app: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + # Use secret in real usage + - name: MYSQL_ROOT_PASSWORD + value: password + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim diff --git a/cn/docs/tasks/run-application/mysql-services.yaml b/cn/docs/tasks/run-application/mysql-services.yaml new file mode 100644 index 0000000000..f538992566 --- /dev/null +++ b/cn/docs/tasks/run-application/mysql-services.yaml @@ -0,0 +1,30 @@ +# Headless service for stable DNS entries of StatefulSet members. +apiVersion: v1 +kind: Service +metadata: + name: mysql + labels: + app: mysql +spec: + ports: + - name: mysql + port: 3306 + clusterIP: None + selector: + app: mysql +--- +# Client service for connecting to any MySQL instance for reads. +# For writes, you must instead connect to the master: mysql-0.mysql. +apiVersion: v1 +kind: Service +metadata: + name: mysql-read + labels: + app: mysql +spec: + ports: + - name: mysql + port: 3306 + selector: + app: mysql + diff --git a/cn/docs/tasks/run-application/mysql-statefulset.yaml b/cn/docs/tasks/run-application/mysql-statefulset.yaml new file mode 100644 index 0000000000..d8ee2d9ac9 --- /dev/null +++ b/cn/docs/tasks/run-application/mysql-statefulset.yaml @@ -0,0 +1,164 @@ +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: mysql +spec: + serviceName: mysql + replicas: 3 + template: + metadata: + labels: + app: mysql + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init-mysql", + "image": "mysql:5.7", + "command": ["bash", "-c", " + set -ex\n + # Generate mysql server-id from pod ordinal index.\n + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1\n + ordinal=${BASH_REMATCH[1]}\n + echo [mysqld] > /mnt/conf.d/server-id.cnf\n + # Add an offset to avoid reserved server-id=0 value.\n + echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf\n + # Copy appropriate conf.d files from config-map to emptyDir.\n + if [[ $ordinal -eq 0 ]]; then\n + cp /mnt/config-map/master.cnf /mnt/conf.d/\n + else\n + cp /mnt/config-map/slave.cnf /mnt/conf.d/\n + fi\n + "], + "volumeMounts": [ + {"name": "conf", "mountPath": "/mnt/conf.d"}, + {"name": "config-map", "mountPath": "/mnt/config-map"} + ] + }, + { + "name": "clone-mysql", + "image": "gcr.io/google-samples/xtrabackup:1.0", + "command": ["bash", "-c", " + set -ex\n + # Skip the clone if data already exists.\n + [[ -d /var/lib/mysql/mysql ]] && exit 0\n + # Skip the clone on master (ordinal index 0).\n + [[ `hostname` =~ -([0-9]+)$ ]] || exit 1\n + ordinal=${BASH_REMATCH[1]}\n + [[ $ordinal -eq 0 ]] && exit 0\n + # Clone data from previous peer.\n + ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql\n + # Prepare the backup.\n + xtrabackup --prepare --target-dir=/var/lib/mysql\n + "], + "volumeMounts": [ + {"name": "data", "mountPath": "/var/lib/mysql", "subPath": "mysql"}, + {"name": "conf", "mountPath": "/etc/mysql/conf.d"} + ] + } + ]' + spec: + containers: + - name: mysql + image: mysql:5.7 + env: + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "1" + ports: + - name: mysql + containerPort: 3306 + volumeMounts: + - name: data + mountPath: /var/lib/mysql + subPath: mysql + - name: conf + mountPath: /etc/mysql/conf.d + resources: + requests: + cpu: 1 + memory: 1Gi + livenessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: 30 + timeoutSeconds: 5 + readinessProbe: + exec: + # Check we can execute queries over TCP (skip-networking is off). + command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"] + initialDelaySeconds: 5 + timeoutSeconds: 1 + - name: xtrabackup + image: gcr.io/google-samples/xtrabackup:1.0 + ports: + - name: xtrabackup + containerPort: 3307 + command: + - bash + - "-c" + - | + set -ex + cd /var/lib/mysql + + # Determine binlog position of cloned data, if any. + if [[ -f xtrabackup_slave_info ]]; then + # XtraBackup already generated a partial "CHANGE MASTER TO" query + # because we're cloning from an existing slave. + mv xtrabackup_slave_info change_master_to.sql.in + # Ignore xtrabackup_binlog_info in this case (it's useless). + rm -f xtrabackup_binlog_info + elif [[ -f xtrabackup_binlog_info ]]; then + # We're cloning directly from master. Parse binlog position. + [[ `cat xtrabackup_binlog_info` =~ ^(.*?)[[:space:]]+(.*?)$ ]] || exit 1 + rm xtrabackup_binlog_info + echo "CHANGE MASTER TO MASTER_LOG_FILE='${BASH_REMATCH[1]}',\ + MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in + fi + + # Check if we need to complete a clone by starting replication. + if [[ -f change_master_to.sql.in ]]; then + echo "Waiting for mysqld to be ready (accepting connections)" + until mysql -h 127.0.0.1 -e "SELECT 1"; do sleep 1; done + + echo "Initializing replication from clone position" + # In case of container restart, attempt this at-most-once. + mv change_master_to.sql.in change_master_to.sql.orig + mysql -h 127.0.0.1 < +Annotations: +CreationTimestamp: Tue, 21 Mar 2017 07:03:51 -0700 +Requesting User: yourname@example.com +Status: Pending +Subject: + Common Name: my-svc.my-namespace.svc.cluster.local + Serial Number: +Subject Alternative Names: + DNS Names: my-svc.my-namespace.svc.cluster.local + IP Addresses: 172.168.0.24 + 10.0.34.2 +Events: +``` + +### Step 3. Get the Certificate Signing Request Approved + +Approving the certificate signing request is either done by an automated +approval process or on a one off basis by a cluster administrator. More +information on what this involves is covered below. + +### Step 4. Download the Certificate and Use It + +Once the CSR is signed and approved you should see the following: + +```console +$ kubectl get csr +NAME AGE REQUESTOR CONDITION +my-svc.my-namespace 10m yourname@example.com Approved,Issued +``` + +You can download the issued certificate and save it to a `server.crt` file +by running the following: + +```console +$ kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \ + | base64 -d > server.crt +``` + +Now you can use `server.crt` and `server-key.pem` as the keypair to start +your HTTPS server. + +## Approving Certificate Signing Requests + +A Kubernetes administrator (with appropriate permissions) can manually approve +(or deny) Certificate Signing Requests by using the `kubectl certificate +approve` and `kubectl certificate deny` commands. However if you intend +to make heavy usage of this API, you might consider writing an automated +certificates controller. + +Whether a machine or a human using kubectl as above, the role of the approver is +to verify that the CSR satisfies two requirements: + +1. The subject of the CSR controls the private key used to sign the CSR. This + addresses the threat of a third party masquerading as an authorized subject. + In the above example, this step would be to verify that the pod controls the + private key used to generate the CSR. +2. The subject of the CSR is authorized to act in the requested context. This + addresses the threat of an undesired subject joining the cluster. In the + above example, this step would be to verify that the pod is allowed to + participate in the requested service. + +If and only if these two requirements are met, the approver should approve +the CSR and otherwise should deny the CSR. + +## A Word of **Warning** on the Approval Permission + +The ability to approve CSRs decides who trusts who within the cluster. This +includes who the Kubernetes API trusts. The ability to approve CSRs should +not be granted broadly or lightly. The requirements of the challenge +noted in the previous section and the repercussions of issuing a specific +certificate should be fully understood before granting this permission. See +[here](/docs/admin/authentication#x509-client-certs) for information on how +certificates interact with authentication. + +## A Note to Cluster Administrators + +This tutorial assumes that a signer is setup to serve the certificates API. The +Kubernetes controller manager provides a default implementation of a signer. To +enable it, pass the `--cluster-signing-cert-file` and +`--cluster-signing-key-file` parameters to the controller manager with paths to +your Certificate Authority's keypair. From 4d6e4604ddab86567bc888a14b11ad0daf241ea9 Mon Sep 17 00:00:00 2001 From: chentao1596 Date: Wed, 30 Aug 2017 11:18:05 +0800 Subject: [PATCH 28/32] Translate into chinese about NetworkPolicy --- .../calico-network-policy.md | 74 +++++++++ .../declare-network-policy.md | 147 ++++++++++++++++++ .../romana-network-policy.md | 50 ++++++ .../weave-network-policy.md | 118 ++++++++++++++ 4 files changed, 389 insertions(+) create mode 100644 cn/docs/tasks/administer-cluster/calico-network-policy.md create mode 100644 cn/docs/tasks/administer-cluster/declare-network-policy.md create mode 100644 cn/docs/tasks/administer-cluster/romana-network-policy.md create mode 100644 cn/docs/tasks/administer-cluster/weave-network-policy.md diff --git a/cn/docs/tasks/administer-cluster/calico-network-policy.md b/cn/docs/tasks/administer-cluster/calico-network-policy.md new file mode 100644 index 0000000000..0ec16607e9 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/calico-network-policy.md @@ -0,0 +1,74 @@ +--- +approvers: +- caseydavenport +title: 使用 Calico 来提供 NetworkPolicy +--- + + +{% capture overview %} +本页展示怎么样使用 Calico 来提供 NetworkPolicy +{% endcapture %} + + +{% capture prerequisites %} +* 为 Kubernetes 安装 Calico +{% endcapture %} + +{% capture steps %} + +## 使用 Calico 部署一个集群 + + +使用如下命令,您可以在默认的 [GCE 部署环境中](/docs/getting-started-guides/gce) 部署一个使用 Calico 来提供网络策略的集群: + +```shell +export NETWORK_POLICY_PROVIDER=calico +export KUBE_NODE_OS_DISTRIBUTION=debian +curl -sS https://get.k8s.io | bash +``` + + +如果希望了解其它的部署选项,请您参考 [Calico 项目文档](http://docs.projectcalico.org/) +{% endcapture %} + +{% capture discussion %} + +## 理解 Calico 组件 + + +部署使用 Calico 的集群其实是增加了支持 Kubernetes NetworkPolicy 的 Pods, 这些 Pods 运行在 `kube-system` 命名空间下。 + + +使用如下方式去查看这些运行的 Pods: + +```shell +kubectl get pods --namespace=kube-system +``` + + +您可以看到类似下面这样的一个 Pods 列表: + +```console +NAME READY STATUS RESTARTS AGE +calico-node-kubernetes-minion-group-jck6 1/1 Running 0 46m +calico-node-kubernetes-minion-group-k9jy 1/1 Running 0 46m +calico-node-kubernetes-minion-group-szgr 1/1 Running 0 46m +calico-policy-controller-65rw1 1/1 Running 0 46m +... +``` + + +主要有两种组件 + + +- 在集群的每个节点上都会运行一个以 `calico-node` 开头命名的 Pod,用于配置 iptables 去实现那些机器上 Pods 的出/入网络策略 + +- 整个集群环境只有一个以 `calico-policy-controller` 开头命名的 Pod,用于从 Kubernetes API 中读取策略和标签信息,适当的对 Calico 进行配置 +{% endcapture %} + + +{% capture whatsnext %} +集群部署完成之后,您可以通过 [NetworkPolicy 入门指南](/docs/getting-started-guides/network-policy/walkthrough)去尝试使用 Kubernetes NetworkPolicy +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/declare-network-policy.md b/cn/docs/tasks/administer-cluster/declare-network-policy.md new file mode 100644 index 0000000000..d43ca3770f --- /dev/null +++ b/cn/docs/tasks/administer-cluster/declare-network-policy.md @@ -0,0 +1,147 @@ +--- +approvers: +- caseydavenport +- danwinship +title: 声明网络策略 +--- + +{% capture overview %} + + +本文可以帮助您开始使用 Kubernetes 的 [NetworkPolicy API](/docs/concepts/services-networking/network-policies/) 声明网络策略去管理 Pod 之间的通信 + +{% endcapture %} + +{% capture prerequisites %} + + +您首先需要有一个支持网络策略的 Kubernetes 集群。已经有许多支持 NetworkPolicy 的网络提供商,包括: + +* [Calico](/docs/tasks/configure-pod-container/calico-network-policy/) +* [Romana](/docs/tasks/configure-pod-container/romana-network-policy/) +* [Weave 网络](/docs/tasks/configure-pod-container/weave-network-policy/) + + +**注意**:以上列表是根据产品名称按字母顺序排序,而不是按推荐或偏好排序。下面示例对于使用了上面任何提供商的 Kubernetes 集群都是有效的 + +{% endcapture %} + +{% capture steps %} + + +## 创建一个`nginx` deployment 并且通过服务将其暴露 + + +为了查看 Kubernetes 网络策略是怎样工作的,可以从创建一个`nginx` deployment 并且通过服务将其暴露开始 + +```console +$ kubectl run nginx --image=nginx --replicas=2 +deployment "nginx" created +$ kubectl expose deployment nginx --port=80 +service "nginx" exposed +``` + + +在 default 命名空间下运行了两个 `nginx` pod,而且通过一个名字为 `nginx` 的服务进行了暴露 + +```console +$ kubectl get svc,pod +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +svc/kubernetes 10.100.0.1 443/TCP 46m +svc/nginx 10.100.0.16 80/TCP 33s + +NAME READY STATUS RESTARTS AGE +po/nginx-701339712-e0qfq 1/1 Running 0 35s +po/nginx-701339712-o00ef 1/1 Running 0 35s +``` + + +## 测试服务能够被其它的 pod 访问 + + +您应该可以从其它的 pod 访问这个新的 `nginx` 服务。为了验证它,从 default 命名空间下的其它 pod 来访问该服务。请您确保在该命名空间下没有执行孤立动作。 + + +启动一个 busybox 容器,然后在容器中使用 `wget` 命令去访问 `nginx` 服务: + +```console +$ kubectl run busybox --rm -ti --image=busybox /bin/sh +Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false + +Hit enter for command prompt + +/ # wget --spider --timeout=1 nginx +Connecting to nginx (10.100.0.16:80) +/ # +``` + + +## 限制访问 `nginx` 服务 + + +如果说您想限制 `nginx` 服务,只让那些拥有标签 `access: true` 的 pod 访问它,那么您可以创建一个只允许从那些 pod 连接的 `NetworkPolicy`: + +```yaml +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: access-nginx +spec: + podSelector: + matchLabels: + run: nginx + ingress: + - from: + - podSelector: + matchLabels: + access: "true" +``` + + +## 为服务指定策略 + + +使用 kubectl 工具根据上面的 nginx-policy.yaml 文件创建一个 NetworkPolicy: + +```console +$ kubectl create -f nginx-policy.yaml +networkpolicy "access-nginx" created +``` + + +## 当访问标签没有定义时测试访问服务 + + +如果您尝试从没有设定正确标签的 pod 中去访问 `nginx` 服务,请求将会超时: + +```console +$ kubectl run busybox --rm -ti --image=busybox /bin/sh +Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false + +Hit enter for command prompt + +/ # wget --spider --timeout=1 nginx +Connecting to nginx (10.100.0.16:80) +wget: download timed out +/ # +``` + + +## 定义访问标签后再次测试 + + +创建一个拥有正确标签的 pod,您将看到请求是被允许的: + +```console +$ kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh +Waiting for pod default/busybox-472357175-y0m47 to be running, status is Pending, pod ready: false + +Hit enter for command prompt + +/ # wget --spider --timeout=1 nginx +Connecting to nginx (10.100.0.16:80) +/ # +``` +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/romana-network-policy.md b/cn/docs/tasks/administer-cluster/romana-network-policy.md new file mode 100644 index 0000000000..ec542ceac2 --- /dev/null +++ b/cn/docs/tasks/administer-cluster/romana-network-policy.md @@ -0,0 +1,50 @@ +--- +approvers: +- chrismarino +title: 使用 Romana 来提供 NetworkPolicy +--- + +{% capture overview %} + + +本页展示怎么样使用 Romana 来提供 NetworkPolicy + +{% endcapture %} + +{% capture prerequisites %} + + +完成 [kubeadm 入门指南](/docs/getting-started-guides/kubeadm/)中的步骤1、2和3 + +{% endcapture %} + +{% capture steps %} + + +## 使用 kubeadm 安装 Romana + + +按照[容器化安装指南](https://github.com/romana/romana/tree/master/containerize)中使用 kubeadm 的方式安装 + + +## 应用网络策略 + + +要应用网络策略,请使用以下方式之一: + + +* [Romana 网络策略](https://github.com/romana/romana/wiki/Romana-policies) + * [Romana 网络策略示例](https://github.com/romana/core/tree/master/policy) + +* NetworkPolicy API + +{% endcapture %} + +{% capture whatsnext %} + + +Romana 安装完成之后,您可以通过 [NetworkPolicy 入门指南](/docs/getting-started-guides/network-policy/walkthrough)去尝试使用 Kubernetes NetworkPolicy + +{% endcapture %} + +{% include templates/task.md %} diff --git a/cn/docs/tasks/administer-cluster/weave-network-policy.md b/cn/docs/tasks/administer-cluster/weave-network-policy.md new file mode 100644 index 0000000000..6d744bef8e --- /dev/null +++ b/cn/docs/tasks/administer-cluster/weave-network-policy.md @@ -0,0 +1,118 @@ +--- +approvers: +- bboreham +title: 使用 Weave 网络来提供 NetworkPolicy +--- + +{% capture overview %} + + +本页展示怎么样使用 Weave 网络来提供 NetworkPolicy + +{% endcapture %} + +{% capture prerequisites %} + + +完成 [kubeadm 入门指南](/docs/getting-started-guides/kubeadm/)中的步骤1、2和3 + +{% endcapture %} + +{% capture steps %} + + +## 安装 Weave 网络插件 + + +按照[通过插件方式集成到 Kubernetes ](https://www.weave.works/docs/net/latest/kube-addon/)指南完成安装 + + +Kubernetes 的 Weave 网络插件配有一个[网络策略控制器](https://www.weave.works/docs/net/latest/kube-addon/#npc),它监控所有命名空间下 NetworkPolicy 相关的注解,然后配置 iptables 规则生成允许或者阻断通信的策略 + +{% endcapture %} + +{% capture example %} + + +## 命名空间隔离示例 + + +1. 创建携带 `DefaultDeny` 标识的命名空间 + +```yaml +kind: Namespace +apiVersion: v1 +metadata: + name: myns + annotations: + net.beta.kubernetes.io/network-policy: | + { + "ingress": { + "isolation": "DefaultDeny" + } + } +``` + + +2. 在命名空间下创建2个 pod + +```yaml +kind: Pod +apiVersion: v1 +metadata: + name: pod1 + namespace: myns + labels: + inns: "yes" +spec: + containers: + - name: pod1 + image: nginx +--- +kind: Pod +apiVersion: v1 +metadata: + name: pod2 + namespace: myns + labels: + inns: "yes" +spec: + containers: + - name: pod2 + image: nginx +``` + + +3. 获取 pod 的 IP 地址 + +```shell +kubectl get po -n myns -o wide +``` + +**注意:** 如果您对 pod 的 cURL 请求是被禁止的,请尝试在 pod 中访问其它的 pod + + +4. 创建一个允许 pod 访问命名空间内其它 pod 的 Kubernetes NetworkPolicy + +```yaml +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: aaa + namespace: myns +spec: + podSelector: + matchExpressions: + - {key: inns, operator: In, values: ["yes"]} + ingress: + - from: + - podSelector: + matchExpressions: + - {key: inns, operator: In, values: ["yes"]} +``` + +Weave 网络插件安装完成之后,您可以通过 [NetworkPolicy 入门指南](/docs/getting-started-guides/network-policy/walkthrough)去尝试使用 Kubernetes NetworkPolicy + +{% endcapture %} + +{% include templates/task.md %} From 6ce4d572f4a450786363f5c46916e43df2a0f26c Mon Sep 17 00:00:00 2001 From: chenhuan12 Date: Fri, 1 Sep 2017 16:16:55 +0800 Subject: [PATCH 29/32] fix the command output fix the command output --- docs/tutorials/clusters/apparmor.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/clusters/apparmor.md b/docs/tutorials/clusters/apparmor.md index 4e1cec4a1f..b1c60fc596 100644 --- a/docs/tutorials/clusters/apparmor.md +++ b/docs/tutorials/clusters/apparmor.md @@ -259,6 +259,7 @@ Namespace: default Node: gke-test-default-pool-239f5d02-x1kf/ Start Time: Tue, 30 Aug 2016 17:58:56 -0700 Labels: +Annotations: container.apparmor.security.beta.kubernetes.io/hello=localhost/k8s-apparmor-example-allow-write Status: Failed Reason: AppArmor Message: Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded @@ -266,20 +267,34 @@ IP: Controllers: Containers: hello: + Container ID: Image: busybox + Image ID: Port: Command: sh -c echo 'Hello AppArmor!' && sleep 1h - Requests: - cpu: 100m - Environment Variables: + State: Waiting + Reason: Blocked + Ready: False + Restart Count: 0 + Environment: + Mounts: + /var/run/secrets/kubernetes.io/serviceaccount from default-token-dnz7v (ro) +Conditions: + Type Status + Initialized True + Ready False + PodScheduled True Volumes: default-token-dnz7v: Type: Secret (a volume populated by a Secret) SecretName: default-token-dnz7v -QoS Tier: Burstable + Optional: false +QoS Class: BestEffort +Node-Selectors: +Tolerations: Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- From b99a6e9743a4ab189bf8706c7cd9bf29fe39e1df Mon Sep 17 00:00:00 2001 From: Jose Olcese Date: Fri, 1 Sep 2017 14:30:02 -0700 Subject: [PATCH 30/32] Update deployment.md deployment name is nginx-deployment and not nginx --- docs/concepts/workloads/controllers/deployment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/workloads/controllers/deployment.md b/docs/concepts/workloads/controllers/deployment.md index c0c9587624..16532ca288 100644 --- a/docs/concepts/workloads/controllers/deployment.md +++ b/docs/concepts/workloads/controllers/deployment.md @@ -574,8 +574,8 @@ nginx-2142116321 3 3 3 2m You can make as many updates as you wish, for example, update the resources that will be used: ```shell -$ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi -deployment "nginx" resource requirements updated +$ kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi +deployment "nginx-deployment" resource requirements updated ``` The initial state of the Deployment prior to pausing it will continue its function, but new updates to From 34c58235fdf36901c119493635a9196e104854c1 Mon Sep 17 00:00:00 2001 From: Weibin Lin Date: Sat, 2 Sep 2017 05:54:40 +0800 Subject: [PATCH 31/32] Update some docs in /cn/docs (#4842) * Add docs in Chinese Add configure-redis-using-configmap.md in Chinese * Modify docs in Chinese Modify imperative-object-management-command.md in Chinese --- .../configure-redis-using-configmap.md | 128 ++++++++++++++++++ .../imperative-object-management-command.md | 34 ++--- 2 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 cn/docs/tutorials/configuration/configure-redis-using-configmap.md diff --git a/cn/docs/tutorials/configuration/configure-redis-using-configmap.md b/cn/docs/tutorials/configuration/configure-redis-using-configmap.md new file mode 100644 index 0000000000..1c4b339df8 --- /dev/null +++ b/cn/docs/tutorials/configuration/configure-redis-using-configmap.md @@ -0,0 +1,128 @@ +--- +approvers: +- eparis +- pmorie +title: 使用ConfigMap来配置Redis +--- + +{% capture overview %} + +这篇文档基于[在Pods中使用ConfigMap数据](/docs/tasks/configure-pod-container/configure-pod-configmap/) 和 [使用ConfigMap来配置Containers](/docs/tasks/configure-pod-container/configmap/) 两个任务,提供了一个使用ConfigMap来配置Redis的真实案例。 + +{% endcapture %} + +{% capture objectives %} + +* 创建一个ConfigMap。 +* 使用ConfigMap来配置pod参数。 +* 创建pod。 +* 验证是否配置成功。 + +{% endcapture %} + +{% capture prerequisites %} + +* {% include task-tutorial-prereqs.md %} +* 理解[在Pods中使用ConfigMap数据](/docs/tasks/configure-pod-container/configure-pod-configmap/)。 +* 理解[使用ConfigMap来配置Containers](/docs/tasks/configure-pod-container/configmap/)。 + +{% endcapture %} + +{% capture lessoncontent %} + + +## 真实世界的案例:使用ConfigMap来配置Redis + +按照下面的步骤,您可以使用ConfigMap中的数据来配置Redis缓存。 + +1. 根据`docs/user-guide/configmap/redis/redis-config`来创建一个ConfigMap: + + ```shell + kubectl create configmap example-redis-config --from-file=docs/user-guide/configmap/redis/redis-config + + kubectl get configmap example-redis-config -o yaml + ``` + + ```yaml + apiVersion: v1 + data: + redis-config: | + maxmemory 2mb + maxmemory-policy allkeys-lru + kind: ConfigMap + metadata: + creationTimestamp: 2016-03-30T18:14:41Z + name: example-redis-config + namespace: default + resourceVersion: "24686" + selfLink: /api/v1/namespaces/default/configmaps/example-redis-config + uid: 460a2b6e-f6a3-11e5-8ae5-42010af00002 + ``` + +1. 使用ConfigMap来配置pod参数: + + ```yaml + apiVersion: v1 + kind: Pod + metadata: + name: redis + spec: + containers: + - name: redis + image: kubernetes/redis:v1 + env: + - name: MASTER + value: "true" + ports: + - containerPort: 6379 + resources: + limits: + cpu: "0.1" + volumeMounts: + - mountPath: /redis-master-data + name: data + - mountPath: /redis-master + name: config + volumes: + - name: data + emptyDir: {} + - name: config + configMap: + name: example-redis-config + items: + - key: redis-config + path: redis.conf + ``` +1. 创建pod: + + ```shell + kubectl create -f docs/user-guide/configmap/redis/redis-pod.yaml + ``` + + In the example, the config volume is mounted at `/redis-master`. + It uses `path` to add the `redis-config` key to a file named `redis.conf`. + The file path for the redis config, therefore, is `/redis-master/redis.conf`. + This is where the image will look for the config file for the redis master. + +1. 使用`kubectl exec`命令进入pod后运行 `redis-cli` 工具来验证配置是否成功: + + ```shell + kubectl exec -it redis redis-cli + 127.0.0.1:6379> CONFIG GET maxmemory + 1) "maxmemory" + 2) "2097152" + 127.0.0.1:6379> CONFIG GET maxmemory-policy + 1) "maxmemory-policy" + 2) "allkeys-lru" + ``` + +{% endcapture %} + +{% capture whatsnext %} + +* 了解关于[ConfigMaps](/docs/tasks/configure-pod-container/configmap/)的更多知识。 +* 参见[在Pods中使用ConfigMap数据](/docs/tasks/configure-pod-container/configure-pod-configmap/)。 + +{% endcapture %} + +{% include templates/tutorial.md %} diff --git a/cn/docs/tutorials/object-management-kubectl/imperative-object-management-command.md b/cn/docs/tutorials/object-management-kubectl/imperative-object-management-command.md index d1a1fde2b6..2a29daf40d 100644 --- a/cn/docs/tutorials/object-management-kubectl/imperative-object-management-command.md +++ b/cn/docs/tutorials/object-management-kubectl/imperative-object-management-command.md @@ -10,40 +10,34 @@ title: 使用命令式的方式管理 Kubernetes 对象 ## 权衡 -`kubectl` 工具支持三种对象的管理: +`kubectl` 工具支持三种方式进行对象的管理: * 命令式的方式 * 命令式的对象配置 * 声明式的对象配置 参见[Kubernetes对象管理](/docs/concepts/tools/kubectl/object-management-overview/) -讨论各种对象管理的优缺点. +讨论各种对象管理方式的优缺点. ## 如何创建对象 -`kubectl` 工具支持用于创建一些最常用的对象类型的动词驱动命令,这些命令被命名为对于不熟悉的用户也是一目了然。 +`kubectl` 工具支持用于创建一些最常用的对象类型的动词驱动命令,这些命令的命名让不熟悉Kubernetes 对象的用户也可以见名知义。 - `run`: 创建一个新的 Deployment 对象以在一个或多个 Pod 中运行 Containers。 - `expose`: 创建一个新的 Service 对象用于负载均衡 Pods 上的的网络流量。 -- `autoscale`: 创建一个新的 Autoscaler 对象,即自动水平扩展控制器,提供 Deployment 自动水平伸缩支持。 +- `autoscale`: 创建一个新的 Autoscaler 对象,来实现 Deployment 等控制器的自动水平拓展。 `kubectl` 工具也支持由对象类型驱动的创建命令。 这些命令支持更多的对象类型,并且对其意图更为明确,但要求用户知道他们打算创建的对象的类型。 - `create [] ` -某些对象类型具有您可以在“create"命令中指定的子类型. -例如,Service对象有几种子类型,包括ClusterIP, -LoadBalancer和NodePort. 以下是创建一个服务的示例 -子类型NodePort: - -一些对象类型允许你在 `create` 命令中指定子命令。例如,Service 对象拥有几个子命令,包括 ClusterIP、LoadBalancer 和 NodePort。以下是使用子命令 NodePort 创建服务的示例: - +某些对象类型具有您可以在“create"命令中指定的子类型。例如,Service对象有ClusterIP,LoadBalancer和NodePort等几种子类型。以下是使用子类型NodePort创建一个服务的示例: ```shell kubectl create service nodeport ``` -在前面的例子中,调用 `create service nodeport`命令是 `create service`命令的子命令. +在前面的例子中, `create service nodeport`命令叫做 `create service`命令的子命令. 您可以使用 `-h` 标志来查找子命令支持的参数和标志: @@ -53,7 +47,7 @@ kubectl create service nodeport -h ## 如何更新对象 -`kubectl` 命令支持一些常见更新操作的动词驱动命令。这样命名可以让不熟悉 Kubernetes 对象的用户,在不知道必须设置的特定字段的情况下也可以执行更新操作: +`kubectl` 命令支持一些常见更新操作的动词驱动命令。这些命令的命名方式可以让不熟悉 Kubernetes 对象的用户,在不知道必须设置的特定字段的情况下也可以执行更新操作: - `scale`: 通过更新控制器的副本数量,水平扩展控制器以添加或删除 Pod。 - `annotate`: 从对象添加或删除注释。 @@ -61,9 +55,9 @@ kubectl create service nodeport -h `kubectl`命令还支持由对象的一个​​切面驱动的更新命令.设置此切面可能会为不同的对象类型设置不同的字段: - - `set` : 设置对象的一个​​切面. + - `set` : 设置对象的一个​​切面。 -**注**: 在 Kubernetes 版本 1.5 中,并不是每个动词驱动的命令都有一个相关的切面驱动的命令. +**注**: 在 Kubernetes 版本 1.5 中,并不是每个动词驱动的命令都有一个相关的切面驱动的命令。 `kubectl` 工具支持直接更新活动对象的其他方法,然而,它们需要更好的了解 Kubernetes 对象模式。 @@ -71,7 +65,7 @@ kubectl create service nodeport -h - `patch`: 通过使用补丁字符串直接修改活动对象的特定字段。 有关补丁字符串的更多详细信息,请参阅补丁部分 -[API 公约](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#patch-operations). +[API 公约](https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#patch-operations)。 ## 如何删除对象 @@ -80,7 +74,7 @@ kubectl create service nodeport -h - `delete /` **注意**: 您可以对命令式命令和命令式对象配置都使用 `kubectl delete` 方法。两者的差异在于传递的命令参数不同。要将 - `kubectl delete` 作为命令式命令使用,将要删除的对象作为参数传递。以下是传递名为 nginx 的 Deployment 对象的示例: + `kubectl delete` 作为命令式命令使用,需将要删除的对象作为参数传递。以下是传递名为 nginx 的 Deployment 对象的示例: ```shell kubectl delete deployment/nginx @@ -89,9 +83,9 @@ kubectl delete deployment/nginx ## 如何查看对象 {% comment %} -TODO(pwittrock): 实现时取消注释. +TODO(pwittrock): 实现时取消注释。 -您可以使用 `kubectl view` 打印指定对象的字段。 +您可以使用 `kubectl view` 打印对象的指定字段。 - `view`: 打印对象的特定字段的值。 @@ -107,7 +101,7 @@ TODO(pwittrock): 实现时取消注释. ## 使用 `set` 命令在创建之前修改对象 -有一些对象字段没有可以使用的标志,在 `create` 命令中。在某些情况下,您可以使用组合 `set` 和 `create` 为对象之前的字段指定一个值创建。这是通过将 `create` 命令的输出管道连接到 `set` 命令,然后回到 `create` 命令。以下是一个例子: +有一些对象字段没有可以在 `create` 命令中使用的标志。在某些情况下,您可以组合使用 `set` 和 `create` 在对象创建之前指定字段的值。这是通过将 `create` 命令的输出管道连接到 `set` 命令,然后回到 `create` 命令。以下是一个例子: ```sh kubectl create service clusterip -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f - From 8c1d5fe1c8cbb6dcd6c6f6c282b6b93d8f9db752 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Fri, 1 Sep 2017 19:57:29 -0400 Subject: [PATCH 32/32] Fixed broken link to Pods concept documentation (#5223) * Fixed broken link to Pods concept documentation * Fixed link to statefulset too --- docs/concepts/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/index.md b/docs/concepts/index.md index 5fce2c4e4f..6ce8c3a9b9 100644 --- a/docs/concepts/index.md +++ b/docs/concepts/index.md @@ -30,7 +30,7 @@ In addition, Kubernetes contains a number of higher-level abstractions called Co * [ReplicaSet](/docs/concepts/workloads/controllers/replicaset/) * [Deployment](/docs/concepts/workloads/controllers/deployment/) -* [StatefulSet](/docs/concepts/workloads/controllers/statefulsets/) +* [StatefulSet](/docs/concepts/workloads/controllers/statefulset/) * [DaemonSet](/docs/concepts/workloads/controllers/daemonset/) * [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/)